9

現在、私は画像処理プロジェクトを開発しており、javacv を使用して画像処理コンポーネントを開発しています。画像の興味深い部分を抽出できたので、これらのオブジェクトの x 座標と y 座標を読み取る必要があります。これは私が抽出した画像です

ここに画像の説明を入力

そして、それらのオブジェクトを特定し、それらのオブジェクトの周りに正方形を描く必要があります. いくつかのチュートリアルを実行し、次のコードを使用してオブジェクトを識別しようとしました。

    IplImage img="sourceimage";
    CvSize sz = cvSize(img.width(), img.height());
    IplImage gry=cvCreateImage(sz, img.depth(), 1);
    cvCvtColor(img, gry, CV_BGR2GRAY);
    cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY);


    CvMemStorage mem = CvMemStorage.create();
    CvSeq contours = new CvSeq();
    CvSeq ptr = new CvSeq();
    cvFindContours(gry, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    CvRect boundbox;

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
        boundbox = cvBoundingRect(ptr, 0);
        if(boundbox.height()>10||boundbox.height()>10){
            cvRectangle( gry, cvPoint( boundbox.x(), boundbox.y() ), cvPoint( boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0 );
            System.out.println(boundbox.x()+", "+boundbox.y());
        }
    }
    cvShowImage("contures", gry);
    cvWaitKey(0);

ただし、オブジェクトの周りに長方形として描画されません。これらのオブジェクトを識別するために cvFindContours メソッドを使用できるかどうか知りたいですか? javacv/opencv を使用して目的をアーカイブする方法を説明してください。

4

5 に答える 5

11

次のコードを試してみると、質問に対する答えが得られます。

    IplImage img=cvLoadImage("pathtosourceimage");
    CvSize cvSize = cvSize(img.width(), img.height());
    IplImage gry=cvCreateImage(cvSize, img.depth(), 1);
    cvCvtColor(img, gry, CV_BGR2GRAY);
    cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY);
    cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5);

    CvMemStorage storage = CvMemStorage.create();
    CvSeq contours = new CvContour(null);

    int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0));

    CvSeq ptr = new CvSeq();

    int count =1;
    CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0);

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) {

        CvScalar color = CvScalar.BLUE;
        CvRect sq = cvBoundingRect(ptr, 0);

            System.out.println("Contour No ="+count);
            System.out.println("X ="+ sq.x()+" Y="+ sq.y());
            System.out.println("Height ="+sq.height()+" Width ="+sq.width());
            System.out.println("");

            p1.x(sq.x());
            p2.x(sq.x()+sq.width());
            p1.y(sq.y());
            p2.y(sq.y()+sq.height());
            cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0);
            cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
            count++;

    }

    cvShowImage("contures",img);
    cvWaitKey(0);

これは、指定された画像に対して取得した出力です。

ここに画像の説明を入力

于 2012-09-01T09:49:15.597 に答える
4

サードパーティのライブラリは必要ありません! 探しているものは、バウンディング ボックスと呼ばれる手法を使用して OpenCV で実現できます。

ここに画像の説明を入力

トリックは、 を使用cvFindContours()して輪郭を取得しcvApproxPoly()、結果を改善することです。白い輪郭を検索するcvNot()ため、入力画像の色を反転する必要があることに注意してください。cvFindContours()

  • この投稿には、輪郭の優れた紹介があります。
  • 車のナンバー プレートを検出するバウンディング ボックスのバージョンを実装するJava デモがあります。

ちなみに、cvMinEnclosingCircle()円の中心は として返されCvPoint2D32fます。

于 2012-08-27T23:55:39.870 に答える
4

関数が黒い背景に白い輪郭をfindContours見つけることをご存知ですか?

bitwise_notあなたのイメージに(またはJavaCVの類似物を)実行するだけで、この後に適用されますfindContours。これは実際にあなたの問題を解決します。

于 2012-08-27T05:57:25.117 に答える
4

cvFindContours は、あなたの問題に対する正しい解決策です。
そして、それがあなたの画像で機能することを確認しました。
これが私の実験です

内部に System.out.println がありますが、出力は何ですか?

cvFindContours は使いにくいので、より一般的な C++ 関数にラップしました。また、vBlob というクラスを使用して、 cvFindContours が検出するオブジェクトを記述します。あなたの Java コードから見ると、Java バージョンの API は C/C++ バージョンと非常によく似ています。したがって、書き直すことは難しくありません。

ps。アスターは正しい答えを出しました。

于 2012-08-26T09:58:26.343 に答える
2

私はc++apiを使用していますが、findContoursの出力を使用するdrawContoursまたはcvDrawContoursという名前の関数もjavacvにあるはずです。

于 2012-08-29T11:25:07.697 に答える