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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

Q&A

解決済

1回答

2602閲覧

OpenCVによる輪郭処理について。

hide300

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

0グッド

0クリップ

投稿2016/08/09 13:52

編集2016/08/12 09:23

opencvを利用し、麻雀牌の認識プログラムを作ろうと思っています。その途中で疑問があるのでご教授お願いします。

画像を取り込み、輪郭を検出したのですがその輪郭1つ1つを切り取る方法はありますでしょうか。

調べたところ輪郭処理(cvFindContours)を使ったラベリング処理によるとh_nextというものを使えば良いようなのですが具体的な関数、コードの描き方がわかりません。

よろしくお願いします。

言語はCを使用しています。
・OS、コンパイラの情報
windows 7
visual studio express 2013 for windows desktop
・opecvのビルド方法
nugetよりopencv 2.4.10を入れました。

*8/12追記
issei.さんのご指導通り輪郭の情報を含んでいるものがポインタでくっついているものということは理解しました。
多くの輪郭が含まれているうち1つだけを抜き出す方法はどうすればよいのでしょうか?
たとえば1つだけ描こうとして

c

1cvDrawContours(result, find_contour->h_next, CV_RGB(255, 0, 0), CV_RGB(255, 0, 0), 1, 2, 8, cvPoint(0, 0));

としても1つ目の輪郭を除いたほかの輪郭すべてが描かれてしまいます。

↓赤い部分だけ抜き出したい
結果

C

1#include <opencv2/opencv.hpp> 2using namespace cv; 3 4int main(int argc, char *argv[]) 5{ 6 IplImage *im = cvLoadImage("pic.png"); //画像のよみこみ 7 IplImage *gray; //グレー化画像 8 IplImage *second; //2値化画像 9 IplImage *edge; //エッジ化画像 10 IplImage *contourim; //輪郭画像 11 IplImage *result; 12 //IplImage *result2; 13 14 gray = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 15 second = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 16 edge = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 17 contourim = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 18 result = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 19 //result2 = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); 20 21 cvCvtColor(im, gray, CV_BGR2GRAY); //グレー化処理 22 cvThreshold(gray, second, 200, 250, CV_THRESH_BINARY); //2値化処理 23 cvLaplace(second, edge, 3); //エッジ化処理 24 25 //輪郭検出 26 CvMemStorage *storage = cvCreateMemStorage(0); 27 CvSeq *find_contour = NULL; 28 cvFindContours(second, storage, &find_contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

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

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

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

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

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

issei.

2016/08/10 02:07

おそらく、挙げていただいているサイトだとC++というよりはCの書き方になると思います(使おうとされているライブラリが恐らくCなので)。Cの書き方が知りたいということで認識あっていますか?あるいはC++で良いのであれば、こちらが参考になりそうです。https://tech-sketch.jp/2012/11/labeling.html
hide300

2016/08/10 05:18

ご指摘の通りC言語による書き方です。ご指摘ありがとうございました
issei.

2016/08/10 05:38

ありがとうございます。でしたら、h_nextは単に線形リストにおいて次の要素を指すのに使っているだけですので、一旦、線形リストについて把握されることをオススメします。http://www.cc.kyoto-su.ac.jp/~yamada/ap/list.html (Cですとリスト構造からは逃げられないと思うので。。。)
guest

回答1

0

自己解決

cvStartFindContours,cvFindNextContourという関数があったのですね。勉強不足でした。

投稿2016/08/16 16:12

hide300

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問