0

私はこの画像から始めました:

ここに画像の説明を入力

次に、Canny Edge Detector を次のように適用しました。

Mat originalMatGreyScale = new Mat();
Imgproc.cvtColor(originalPhotoMat, originalMatGreyScale, Imgproc.COLOR_BGR2GRAY);
Mat edgesMat = new Mat();
Imgproc.Canny(originalMatGreyScale, edgesMat , 50, 70);

私が得た:

ここに画像の説明を入力

次に、 によって等高線のリスト ( ) を見つけました。次にcontoursImgproc.findContours()(1) 最大の等高線 ( ) の領域を見つけるためのコーディングを行いました(2)未満の面積を持つ等高線maximumContourAreaから削除します。質問の下部にあるコード。contoursmaximumContourArea

元の画像に緑色の(残りの)輪郭Imgproc.drawContours()を描画するために呼び出した

for (int contourIndex = 0; contourIndex < contours.size(); contourIndex++) {
    Imgproc.drawContours(originalPhotoMat, contours, contourIndex, new Scalar(0, 255, 0));
}

私が期待していたのは、それらすべての小さな汚れとノイズの輪郭を輪郭リストから削除する必要があるということでしcontoursたが、代わりにこのマットを取得しました(これらの小さな汚れの周りにも緑色の輪郭が描かれています):

ここに画像の説明を入力

さらに、Log.i()次のコードのメッセージはこれを出力します。

最初の輪郭の数: 27

処理後の輪郭の数: 27

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(edgesMap, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);


Log.i(TAG, "Number of contours initially: " + contours.size());//check

double maximumContourArea = 0;

Iterator<MatOfPoint> contoursIterator = contours.iterator();

while(contoursIterator.hasNext()) {
    MatOfPoint nextContour = contoursIterator.next();
    double nextContourArea = Imgproc.contourArea(nextContour);

    if (nextContourArea > maximumContourArea) {
        maximumContourArea = nextContourArea;
    }
}

while(contoursIterator.hasNext()) {
    MatOfPoint nextContour = contoursIterator.next();
    if (Imgproc.contourArea(nextContour) < maximumContourArea*(10 / 100)) {
        contours.remove(contours.indexOf(nextContour));
    }
}

Log.i(TAG, "Number of contours after processing: " + contours.size());//check



編集:

  1. に置き換えまし(10/100)0.1が、実際にはわかりやすくする0.5ために、この例ではむしろ を使用することにしました。このようにして、最大の等高線の面積の半分よりも小さいすべての等高線を削除する必要があります。

  2. そのため、あちこちでいくつかのLog.iステートメントを実行した後、2 番目の while ループが実行されていないことに気付きました。いくつかいじってIteratorからforeachループに降りた後、私は取得ConcurrentModificationExceptionしていたので、次のように解決策がループであることが最終的にわかりましたfor

問題: (a) それでも同じMats が得られますが、次のコード スニペットと、このページの下部にある logcat 出力からmaximumContourAreaの s の値とs の値を見るとcurrentContourArea、面積のある 1 つの等高線しかないことに気付くでしょう。の1719.0残り、その他はすべて削除する必要があります。(b) 次のコードの後の Logcat 出力を参照してください。

コードが変更されました:

Log.i(TAG, "PNM Number of contours initially: " + contours.size());//check

double maximumContourArea = 0;

for (int currentContour=0; currentContour<contours.size(); currentContour++) {
    double currentContourArea = Imgproc.contourArea(contours.get(currentContour));
    if (maximumContourArea < currentContourArea) {
        maximumContourArea = currentContourArea;
    }
}

Log.i(TAG, "PNM maximumContourArea: " + maximumContourArea);//check
Log.i(TAG, "PNM maximumContourArea*.5: " + maximumContourArea*0.5);//check

for (int currentContour=0; currentContour<contours.size(); currentContour++) {
    double currentContourArea = Imgproc.contourArea(contours.get(currentContour));
    Log.i(TAG, "PNM currentContourArea: " + currentContourArea);//check
    if (currentContourArea < maximumContourArea*0.5) {
        contours.remove(currentContour);
    }
}
Log.i(TAG, "PNM Number of contours after processing: " + contours.size());//check

ログキャット出力:

04-21 12:09:59.955: I/MainActivity(9983): PNM Number of contours initially: 27
04-21 12:09:59.957: I/MainActivity(9983): PNM maximumContourArea: 1992.0
04-21 12:09:59.957: I/MainActivity(9983): PNM maximumContourArea*.5: 996.0
04-21 12:09:59.958: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.958: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 34.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 40.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 2.5
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.959: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.960: I/MainActivity(9983): PNM currentContourArea: 0.0
04-21 12:09:59.961: I/MainActivity(9983): PNM currentContourArea: 0.5
04-21 12:09:59.961: I/MainActivity(9983): PNM currentContourArea: 1719.0
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 35.5
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 105.0
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 29.5
04-21 12:09:59.962: I/MainActivity(9983): PNM currentContourArea: 47.0
04-21 12:09:59.962: I/MainActivity(9983): PNM Number of contours after processing: 14

OKのメソッドは削除されたもの (輪郭) を返すため、に置き換えcontours.remove(currentContour);ました。(ソースLog.i(TAG, "PNM A contour with an area of " + Imgproc.contourArea(contours.remove(currentContour)) + " is being removed.");ArrayListremove()

currentContour--;私もこの声明の後に付け加えました。

Logcat メッセージは次のとおりです。

04-21 14:15:19.824: I/MainActivity(11125): PNM Number of contours: 27
04-21 14:15:19.824: I/MainActivity(11125): PNM maximumContourArea: 1992.0
04-21 14:15:19.824: I/MainActivity(11125): PNM maximumContourArea*.5: 996.0
04-21 14:15:19.824: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.824: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 18.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 18.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 34.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 34.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 40.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 40.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.825: I/MainActivity(11125): PNM currentContourArea: 2.5
04-21 14:15:19.825: I/MainActivity(11125): PNM A contour with an area of 2.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 4.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 4.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 32.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 32.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.0
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.0 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 0.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 0.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 11.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 11.5 is being removed.
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 1719.0
04-21 14:15:19.826: I/MainActivity(11125): PNM currentContourArea: 35.5
04-21 14:15:19.826: I/MainActivity(11125): PNM A contour with an area of 35.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 59.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 59.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 105.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 105.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 1992.0
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 29.5
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 29.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 259.5
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 259.5 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 47.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 47.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM currentContourArea: 38.0
04-21 14:15:19.827: I/MainActivity(11125): PNM A contour with an area of 38.0 is being removed.
04-21 14:15:19.827: I/MainActivity(11125): PNM Number of contours after processing: 2

^ 動作しているようです。現在残っている唯一の問題は、元の画像に緑色の輪郭を描画するために最後に実行されたときに、すべての輪郭が描画されるのはなぜですか (それらの小さな汚れを巻き付けたものでも) 。drawContours()

4

1 に答える 1

2

ループ内のロジックに欠陥があります...

10 個の要素の配列があり、2 番目の要素が削除されることがわかった場合、この時点でcurrentContour変数は 1 であり、この要素を削除するとします。次に、9 つの要素があり、反復が終了し、currentContour変数が 2 になります。これまでの問題は何ですか。インデックス 1 の要素を削除すると、インデックス 2 の要素のインデックスが 1 に変更されました。したがって、currentContour変数はすでに 2にあるため、この要素はチェックされません。

これを修正する1つの方法は、新しい配列を作成して必要な輪郭を追加することです...または要素を削除した後、インデックスを前の番号に変更しますcurrentContour--;

于 2016-04-21T07:33:08.993 に答える