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

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

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

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Xcode 7

Xcode 7は、ソフトウェア開発のためのアップルの統合開発環境であるXcodeのバージョン。UIを作成するために用いるグラフィカルツールです。iOS9/OS X El Capitan/watchOS2に対応。Swift 2コンパイラーが搭載されています。

OpenCV

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Q&A

1回答

3468閲覧

OpenCVでの矩形検出

sakittyo

総合スコア16

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Xcode 7

Xcode 7は、ソフトウェア開発のためのアップルの統合開発環境であるXcodeのバージョン。UIを作成するために用いるグラフィカルツールです。iOS9/OS X El Capitan/watchOS2に対応。Swift 2コンパイラーが搭載されています。

OpenCV

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

0グッド

0クリップ

投稿2017/01/11 01:37

###前提・実現したいこと
opencvを使用し矩形検出のプログラムを書いています。
エラーが直せず相談させてもらいます。

###発生している問題・エラーメッセージ
cvFindContoursでcontoursの中に座標などのデータを入れてるはずなのですが中身が入ってないようです。
for (int i = 0; i+1 <= contours->total; i++) {でブレイクポイントになってしまい、試しにdouble Area = fabs(cvContourArea(contours, CV_WHOLE_SEQ));を前に入れてみたところcontours内がNULLだと表示が出ました。

###該当のソースコード

#import "MonochromeFilter.h" #import "OpenCVUtil.h" #import <AudioToolbox/AudioServices.h> @implementation MonochromeFilter + (UIImage *)doFilter:(UIImage *)image { // CGImageからIplImageを作成 IplImage *srcImage = [OpenCVUtil IplImageFromUIImage:image]; IplImage *grayScaleImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1); IplImage *dstImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3); IplImage *bin_image = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1); //cv::Mat aaa; CvSeq *contours; std::vector< cv::Point > approx; CvMemStorage *storage = cvCreateMemStorage (0); // グレースケール画像に変換 cvCvtColor(srcImage, grayScaleImage, CV_BGR2GRAY); //2値化 //cvThreshold(grayScaleImage,bin_image,160,255,CV_THRESH_BINARY); //std::vector< std::vector< cv::Point > > contours; // cv::Mat(aaa) = bin_image; cvCanny(grayScaleImage,bin_image, 50.0, 200.0, 3); //輪郭検出 cvFindContours (bin_image, storage, &contours, sizeof (CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); double Area = fabs(cvContourArea(contours, CV_WHOLE_SEQ));//NULLが出る場所 std::vector<cv::Point> points; for (int i = 0; i+1 <= contours->total; i++) {//ブレイク箇所 CvPoint *point = CV_GET_SEQ_ELEM(CvPoint, contours, i); i++; points.push_back(cv::Point(*point)); cv::approxPolyDP(points, approx, 50.0, true); double area = cv::contourArea(approx); if (approx.size() == 4 ){//&& 300.00> area > 1000.0){ AudioServicesPlaySystemSound(1000); } } // CGImage用にBGRに変換 cvCvtColor(bin_image, dstImage, CV_GRAY2BGR); // IplImageからCGImageを作成 UIImage *effectedImage = [OpenCVUtil UIImageFromIplImage:dstImage]; cvReleaseImage(&srcImage); cvReleaseImage(&grayScaleImage); cvReleaseImage(&dstImage); return effectedImage; } @end

###試したこと
多分なんですがcontoursをポインタで宣言している関係だと思うんですが原因がわかりません。
###補足情報(言語/FW/ツール等のバージョンなど)
Xcode7.3
opencv2.4.9

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

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

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

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

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

sakittyo

2017/01/11 01:47

そちらは試させていただきましたCvSeq contours;で宣言するとcvFindContoursで型が違うと言われてしまいました。
fuzzball

2017/01/11 01:59

cvFindContours()のmethodをCV_CHAIN_APPROX_NONEにしても変わらないでしょうか?
sakittyo

2017/01/11 02:55

一度だけ動いたのですがそのあと同じ現象で止まってしまいました
fuzzball

2017/01/11 02:56 編集

同じ現象というのは、contoursがNULLってことですか?
sakittyo

2017/01/11 03:01

すいません今見たとことdouble Area = fabs(cvContourArea(contours, CV_WHOLE_SEQ));のNULLは出てませんでした。for (int i = 0; i+1 <= contours->total; i++) {でブレイクしています。
sakittyo

2017/01/11 03:27

エラーになる前にfor文が30万ほど回ってるみたいなのでcontoursは中身が入ってるようです。ブレイクになってしまう理由は他にありそうです
guest

回答1

0

こんにちは。

cvFindContours()が輪郭検出に失敗しているのだと思います。
cvCanny()はエッジ抽出です。エッジを見つけたピクセルのみ非0になります。
確認したわけではないですが、1ピクセル幅の「線」は輪郭抽出対象から外れるのではないかと思います。
結果、検出できる「輪郭」が存在しないのだと思います。

cvFindContours()の一般的な前処理はcvThreshold()等で2値化画像を作ります。
cvThreshold()ではうまく矩形を切りだけなかった場合は、低周波成分の振幅が大きいということでしょうから、対策は結構難易度が高いと思います。
なんらかの手段で低周波成分を取り除いてからthresholdで2値化する、ハフ変換等を用いて矩形を構成する直線の候補を抽出し、その中からなんらかの手段で正しい線分を決定する等、様々なアプローチが考えられると思います。
かなり高度な話になるので、可能であれば画像処理の専門家の方に相談された方が良いかも知れません。

投稿2017/01/11 03:14

Chironian

総合スコア23272

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問