質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

0回答

3463閲覧

9×9の格子状の網目の作成

hoitya

総合スコア14

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/11/27 09:37

今、画像にある2点を頂点とした3×3の格子状の網目をつけ、そこに自分が決めた座標を新しく定義して、
網目内にある認識した図形の座標を表示するアプリを作っています。(説明下手ですいません)
開発環境はwindows10,visual studio,OpenCV-3.2.0で言語はC++を使っています。
順序としては自分のイメージでは
1:網目をつける場所をOpenCVで画像のある2点A(x1,y1),B(x2,y2)として認識する

2:Aをy軸方向,Bをx軸方向に伸ばした交点C(x1,y2)とし、線分AC(x2-x1),CB(y2-y1)の長さをそれぞれ3等分するような3×3の格子状の網目を作る

3:チェスや将棋のように格子状の網目に9つの座標(a1,a2,a3,b1,b2.b3,c1,c2,c3のような)を定義する

4:最後にAやBとは別に存在する図形(例えば星などのような)が自身が定義した9つの座標のどの場所にあるかをテキストに表す

流れとしては以上になります。
最終的に4番の行為が行われていればいいので、網目を表示したり交点Cをいちいち求めることは特に必要ないです。

現状では1番まで出来ています。

#include<opencv\opencv.hpp> #include <iostream> int main(int argc, char *argv[]) { //CvCapture *capture = cvCreateCameraCapture(0); // テンプレート画像 cv::Mat tmp_imgs[3]; tmp_imgs[0] = cv::imread("C:\opencv\sources\tenA.jpg", 1); tmp_imgs[1] = cv::imread("C:\opencv\sources\tenB.jpg", 1); tmp_imgs[2] = cv::imread("C:\opencv\sources\zukei_hosi.jpg", 1); //C:\opencv\sources\samples\data\koma4\ // 枠線の色 cv::Scalar cols[3]; cols[0] = cv::Scalar(255, 255, 255); cols[1] = cv::Scalar(0, 0, 0); cols[2] = cv::Scalar(0, 255, 0); std::ofstream writing_file; writing_file.open("test.txt", std::ios::out); cv::namedWindow("search image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); // while (1) { // 探索画像 cv::Mat search_img0 = cv::imread("C:\opencv\sources\sousaku.jpg", 1); cv::Mat search_img; search_img0.copyTo(search_img); for (int j = 0; j<3; j++) { cv::Mat &tmp_img = tmp_imgs[j]; cv::Mat result_img; // 50 個検出する for (int i = 0; i<50; i++) { // テンプレートマッチング // cv::matchTemplate(search_img, tmp_img, result_img, CV_TM_SQDIFF_NORMED); cv::matchTemplate(search_img, tmp_img, result_img, CV_TM_CCOEFF_NORMED); // 最大のスコアの場所を探す cv::Rect roi_rect(0, 0, tmp_img.cols, tmp_img.rows); cv::Point max_pt; double maxVal; cv::minMaxLoc(result_img, NULL, &maxVal, NULL, &max_pt); // 一定スコア以下の場合は処理終了 if (maxVal < 0.58) break; roi_rect.x = max_pt.x; roi_rect.y = max_pt.y; if (j == 0) { std::cout << "A" << std::endl; writing_file << "A " << "(" << max_pt.x << ", " << max_pt.y << ")\n"; } else if (j == 1) { std::cout << "B" << std::endl; writing_file << "B " << "(" << max_pt.x << ", " << max_pt.y << ")\n"; } else if (j == 2) { std::cout << "☆" << std::endl; writing_file << "☆ " << "(" << max_pt.x << ", " << max_pt.y << ")\n"; } std::cout << "(" << max_pt.x << ", " << max_pt.y << "), score=" << maxVal << std::endl; // 探索結果の場所に矩形を描画 cv::rectangle(search_img0, roi_rect, cols[j], 3); cv::rectangle(search_img, roi_rect, cv::Scalar(0, 0, 255), CV_FILLED); } printf("%d\n", j); } cv::imshow("search image", search_img0); char ch = cv::waitKey(0); //if (ch == 27) break; //cvReleaseCapture(&capture); }

コードでは点A,Bと図形☆の座標データをテキスト化するところまでできました。
ちなみにコードについては「Moonmile Solutions Blog」http://www.moonmile.net/blog/archives/2468というブログの複数の検出をしているほうのコードを参考にさせていただいております。
2番からのコードの書き方がうまくできないのでよろしければご教授いただきたいです。
上にも書きましたが、4番の最終的に図形☆が自身が定義した座標のどこにあるかをテキスト化できればいいので(イメージでは ☆(b2) のようなものがテキストファイルに書かれる)、もっと効率のいい方法があるのであれば1から3の手順は無視したり変更しても構いません。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2017/11/29 10:07 編集

9個ある網目(マス)のそれぞれで、マスの四隅座標(x,y)は計算できているのでしょうか?まずはご自身で処理ステップを(日本語や数式で)書き下してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問