ページ 11

カメラから机に置かれた紙の座標取得プログラムなんですが・・

Posted: 2016年1月16日(土) 16:43
by ビギナー
はじめましての方ははじめまして・・よろしくお願いします。

私はタイトルのように紙の座標 主に紙の四隅の座標を出したいと思っています

そのため下記のような輪郭を取り、座標を取るプログラムを実行しました

#include <C:\OpenCV2.4.9\sources\include\opencv\cv.h>
#include <C:\OpenCV2.4.9\sources\include\opencv\highgui.h>
int
main (int argc, char *argv[])
{
int i;
IplImage *src_img = 0, **dst_img;
IplImage *src_img_gray = 0;
IplImage *tmp_img;
CvMemStorage *storage = cvCreateMemStorage (0);
CvSeq *contours = 0;
CvPoint *point, *tmp;
CvSeq *contour;
CvTreeNodeIterator it;
CvFileStorage *fs;

if (argc <= 2)
src_img = cvLoadImage ("../test.png", CV_LOAD_IMAGE_COLOR);
if (src_img == 0)
return -1;

src_img_gray = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1);
cvCvtColor (src_img, src_img_gray, CV_BGR2GRAY);
tmp_img = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1);
dst_img = (IplImage **) cvAlloc (sizeof (IplImage *) * 3);
for (i = 0; i < 3; i++) {
dst_img = cvCloneImage (src_img);
}

// 画像の二値化と輪郭の検出
cvThreshold (src_img_gray, tmp_img, 100, 255, CV_THRESH_BINARY);
cvFindContours (tmp_img, storage, &contours, sizeof (CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);


/* 輪郭シーケンスから座標を取得 */
fs = cvOpenFileStorage ("contours.txt", 0, CV_STORAGE_WRITE);
// ツリーノードイテレータの初期化
cvInitTreeNodeIterator (&it, contours, 1);
// )各ノード(輪郭)を走査
while ((contour = (CvSeq *) cvNextTreeNode (&it)) != NULL) {
cvStartWriteStruct (fs, "contour", CV_NODE_SEQ);
// 輪郭を構成する頂点座標を取得
tmp = CV_GET_SEQ_ELEM (CvPoint, contour, -1);
for (i = 0; i < contour->total; i++) {
point = CV_GET_SEQ_ELEM (CvPoint, contour, i);
cvLine (src_img, *tmp, *point, CV_RGB (0, 0, 255), 2);
cvStartWriteStruct (fs, NULL, CV_NODE_MAP | CV_NODE_FLOW);
cvWriteInt (fs, "x", point->x);
cvWriteInt (fs, "y", point->y);
cvEndWriteStruct (fs);
tmp = point;
}
cvEndWriteStruct (fs);
}
cvReleaseFileStorage (&fs);


cvNamedWindow ("Contours", CV_WINDOW_AUTOSIZE);
cvShowImage ("Contours", src_img);
cvWaitKey (0);

cvDestroyWindow ("Contours");
cvReleaseImage (&src_img);
cvReleaseImage (&src_img_gray);
cvReleaseImage (&tmp_img);
cvReleaseMemStorage (&storage);

return 0;
}

しかし輪郭の複数の点がテキストファイルに保存されてしまいます.....

%YAML:1.0
contour:
- { x:158, y:39 }
- { x:156, y:41 }
- { x:156, y:43 }
- { x:154, y:45 }
- { x:154, y:46 }
- { x:153, y:47 }
- { x:153, y:48 }
- { x:151, y:50 }
- { x:151, y:52 }
- { x:149, y:54 }
- { x:149, y:55 }
- { x:148, y:56 }
- { x:148, y:57 }
- { x:147, y:58 }
- { x:147, y:59 }
- { x:145, y:61 }
- { x:145, y:62 }
- { x:144, y:63 }
- { x:144, y:64 }
- { x:143, y:65 }
- { x:143, y:66 }
- { x:141, y:68 }






そこで私なりに考え、テキストファイルからX Yの最大値と最小値の組合わせを取れば、四隅の座標を取得できるのではないかと思っています。

しかしそのプログラムが上手くいかず....
少しだけでもアドバイスいただけませんか?
C++の詳しい方 ご教授ください。



また違うやり方の方が簡単や、お勧めなどあればそれでもかまいません。
よろしくお願いします。

Re: カメラから机に置かれた紙の座標取得プログラムなんですが・・

Posted: 2016年1月20日(水) 19:10
by asd
ビギナー さんが書きました: そこで私なりに考え、テキストファイルからX Yの最大値と最小値の組合わせを取れば、四隅の座標を取得できるのではないかと思っています。

しかしそのプログラムが上手くいかず....
少しだけでもアドバイスいただけませんか?
C++の詳しい方 ご教授ください。
C++はそこまで詳しくないですがC#でOpenCVを使ったことはありますので可能な範囲で回答します。
取得された輪郭が対象となる紙の輪郭のみ(机の模様やノイズなどの余計な輪郭は無い前提)であれば、
それらを構成する座標から最大値と最小値の組み合わせで四隅の座標は取得できそうですが、

1.具体的にどのように四隅の座標を取得されたのでしょうか?
2.1の方法で取得できた座標と自分が思い描いていた座標とで何が違っていたでしょうか?
ビギナー さんが書きました: また違うやり方の方が簡単や、お勧めなどあればそれでもかまいません。
よろしくお願いします。
取得された輪郭から角検出を行うと四隅座標の絞り込みができるのではないでしょうか。
その際、検出範囲を上部と下部などに絞り込むと、より四隅の角が検出しやすくなるのではないでしょうか。

Re: カメラから机に置かれた紙の座標取得プログラムなんですが・・

Posted: 2016年1月20日(水) 19:53
by usao
このトピックは立て直されていて,こちら

http://dixq.net/forum/viewtopic.php?f=3&t=17610

の方が新しいものになっています.

Re: カメラから机に置かれた紙の座標取得プログラムなんですが・・

Posted: 2016年1月21日(木) 08:47
by asd
usao さんが書きました:このトピックは立て直されていて,こちら

http://dixq.net/forum/viewtopic.php?f=3&t=17610

の方が新しいものになっています.
新しいトピックを見落としていました。
ご指摘ありがとうございました。