0

を使おうとすると、XCodeの何が問題になっているのかを理解するために何時間も努力してきましたfindContours。基本的にこれは私のコードです:

#include <opencv2/opencv.hpp>
int main()
{
    Mat img = imread(helper::getImageSequence(3, image_value_temp));
    Mat img_gray = Mat(Size(img.cols, img.rows), CV_8UC1);
    Mat img_canny;

    cvtColor(img, img_gray, CV_BGR2GRAY);    

    Canny(img_gray, img_canny, someLow, someHigh);

    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(img_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
}

等高線を印刷すると7905747460161236409になるので、ヒープがオーバーフローしているのではないかと思います。

  • XCodeバージョン:4.5.2
  • コンパイラ:Apple LLVM 4.1

つまり、基本的にクラッシュはさかのぼり、findContoursXCodeが私に与えるのはこれだけです。

ここに画像の説明を入力してください

4

2 に答える 2

3

このエラーを生成する完全なソースコードと画像を提供すると、エラーを再現しやすくなります。私があなたのコードを完成させたら、私はそれを使うことができます:

#include <opencv2/opencv.hpp>
int main()
{
    using namespace cv;
    Mat img = imread("test.png");
    Mat img_gray = Mat(Size(img.cols, img.rows), CV_8UC1);
    Mat img_canny;

    cvtColor(img, img_gray, CV_BGR2GRAY);    

    Canny(img_gray, img_canny, 80, 120);

    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(img_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
}

私のシステムでは正常に動作します。すべきでない理由はわかりません。スクリーンショットに投稿したエラーは、コンパイラのクラッシュではありません。デバッガーは、実行中にプログラムがクラッシュしたことを示しています。cv :: pointsのベクトルを破棄しているときにエラーを生成する、明らかに自分で作成した関数circle_fitting_callbackがあります。あなたの問題はあなたが投稿したコードではなく、あなたが私たちに見せていない何かにあります。最良のことは、デバッガーの使い方を学ぶことです。私はあなたのIDEを知りませんが、コールスタック(あなたが私たちに見せたもの)の適切な行をクリックすると、クラッシュを引き起こしている関数の部分に直接あなたを推測します。これで行き詰まった場合は、エラーを再現するための完全なコードを投稿してください。

于 2012-12-09T08:24:12.830 に答える
1

findContours(...)まず、 Cannyエッジ検出器の出力を直接実行することは想定されていないと思います。その理由は、一部の画像、および一部の値のエッジ検出器への入力パラメーター(この場合は「someLow」および「someHigh」)では、出力画像に小さな断片化されたエッジが多数含まれるためです。したがって、findContours(...)CV_RETR_TREEオプション(ネストされた輪郭の完全な階層を返す)を使用して呼び出すと、多くの輪郭に加えて、階層を構築するための余分なオーバーヘッドが検出されます。

これをテストするには、背景が無地の円のような単純なテスト画像でコードを実行してみてください。キャニーエッジ検出器は、単一の「エッジ」、つまり円を与える必要があります。次に、findContour(...)を呼び出すと、この円が表示されます。

別のテストは、CV_RETR_LISTが階層を構築せずに輪郭のみを返すため、CV_RETR_TREEの代わりにCV_RETR_LISTを使用することです。

さらに別のテストは、ごく少数のエッジを返すように設定されたキャニーエッジ検出器への入力を使用してコードを実行することです。

これらのケースでプログラムがクラッシュしない場合は、ほぼ正しい方向に進んでいます。

最後に、画像処理/コンピュータービジョンの作業を行った私の経験から、エッジマップでfindContours(...)を呼び出すことはほとんどありません。断片化されたエッジの周りに輪郭が必要な場合はどうすればよいですか?私の推測が正しければ、画像内のオブジェクトの周りの輪郭を見つけようとしています。その場合は、grabCutfloodfill(流域、平均シフトセグメンテーション)などのセグメンテーション方法を使用して、画像内のオブジェクトのバイナリマスクを取得し、いくつかの基本的な画像形態演算子を実行してマスクをクリーンアップする必要があります。次に、このマスクでfindContours(...)を実行します。

お役に立てれば。

于 2012-12-10T06:27:10.427 に答える