3

OpenCVとC++を使用して画像内の円を検出したい。公式ドキュメントを参照し、OpenCVチームによって作成されたコードのパラメーターを調整することでそれを行うことができます。

したがって、私が使用しているコードは次のとおりです:(パラメーターはすでに調整されています)

    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>

    using namespace cv;

    int main(int, char** argv)
    {
       Mat src, src_gray;

       /// Read the image
       src = imread( argv[1], 1 );

       if( !src.data )
         { return -1; }

       /// Convert it to gray
        cvtColor( src, src_gray, CV_BGR2GRAY );

       /// Reduce the noise so we avoid false circle detection
        GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );

        vector<Vec3f> circles;

       /// Apply the Hough Transform to find the circles
        HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 6.0, 5, 110, 70, 3, 20 );

       /// Draw the circles detected
        for( size_t i = 0; i < circles.size(); i++ )
        {
             Point center(cvRound(circles[i][0]), cvRound(circles[i][2]));
             int radius = cvRound(circles[i][3]);
             // circle center
             circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
             // circle outline
             circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
        }

       /// Show your results
        namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
        imshow( "Hough Circle Transform Demo", src );

        waitKey(0);

        src.release();
        src_gray.release();

        return 0;
    }

そして、私が検出したい円の画像は次のとおりです。テスト画像

これらは実際には、cvBlobsLibを使用して取得し、新しい画像として再描画した2つのブロブの輪郭です。

そのアルゴリズムは各円の中心を識別することができますが、プログラムを閉じるために任意のキーを押すと、クラッシュします...:(そして私はそれを強制的に閉じる必要があります。

そのアルゴリズムをカメラで実行するように調整する必要があるため、そのようにクラッシュしている間は実装を続行できません。

それで、誰かがこの問題を引き起こしている可能性があるものを知っていますか?VisualStudio2012とOpenCVバージョン2.4.2で開発を行っています。

誰かが私にそれが何であるかについての提案をしてくれるか、あるいはアルゴリズムを実行してみることができれば、私は非常に感謝しています!

4

4 に答える 4

1

私はあなたに4つのアドバイスがあります。

最初: aMatが空かどうかを確認するには、次を使用します

if( src.empty() ) // instead of !src.data.

src.dataが空のランダムな(古い)値を持っている可能性がありますMat

2番目:次のようにインデックスを修正します。

Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);

(実際にはcvRoundは必要ありませんが、何でもかまいません)。

3番目:imreadチャンネル数をチェックして、カラーモードで画像をロードすることが理解されているかどうかをチェックする価値があります。

src.channels()==3
//or
src.type()==CV_8UC3; // that is what you are counting for, really.

そうしないと、グレー画像のCV_BGR2GRAYのような行が、奇妙な動作を引き起こす可能性があります。

4番目:マットを解放する必要はありません。それが彼らが最初にMatクラスを作成した理由であり、それにより彼らは自動的にリリースを処理します。

于 2012-12-06T09:19:28.187 に答える
0

あなたがVec3f限界を超えていることを除いて、私は明白なことは何も見ていません:

         Point center(cvRound(circles[i][0]), cvRound(circles[i][2]));
         int radius = cvRound(circles[i][3]);

インデックス2と3の代わりに、1と2を意味していると思います。

それは必ずしもクラッシュを引き起こしているわけではありませんが(スタックまたはヒープを破壊することによって)、それでも未定義の動作です...

私が提案するもう1つのことは、waitKey呼び出しに続く2行を削除することです。

    src.release();
    src_gray.release();

これらはオブジェクトのデストラクタによって自動的に処理されるため、手動で行う必要がある理由がわかりません。もちろん、それは物事を変えないかもしれません。

それでもクラッシュが発生する場合は、クラッシュするセクションを特定できるようになるまで、コードのセクションを省略し始める必要があります。

于 2012-12-06T03:15:28.177 に答える
0

環境に不安を感じ始めたので、OpenCVをセットアップしてくれた友達にコードを試してもらい、問題なく実行できました...

そこで、すべてを再インストールしましたが、今回はMicrosoft Visual Studio 2010SP1とOpenCV2.4.3を選択し、正しく機能しました。

同じ問題が発生している場合は、VS2010にダウングレードすることをお勧めします。また、このビデオインスタレーションガイドは、私が環境を設定しているときに本当に役に立ちました!

ありがとうございました :)

于 2012-12-08T04:48:04.960 に答える
0

私も同じ問題を抱えていました。アプリケーションをリリースモードで実行しているときに、opencvリリースdllを使用していることを確認してください。これを行うことで私の問題は解決しました。

参照: https ://code.ros.org/trac/opencv/ticket/953

于 2014-04-21T09:39:22.350 に答える