17

主なアイデアは、ユーザーが特定の壁ベースのユーザー選択に合わせて色を変更できるようにすることです。現在、私はこの機能をcvFloodFill(マスク画像の準備に役立ちます)を使用して実装しました。これHSVは、壁の相対値を変更してエッジを保持できるようにするのに役立ちます。ただし、このソリューションの問題は、色で機能し、ユーザーが選択した単一の壁ではなく、すべての壁が再塗装されることです。

私もキャニーエッジ検出を試みましたが、エッジを検出することはできますが、それを面積に変換することはできません。

私が現在再描画機能に使用している以下のコードを見つけてください

  1. マスクを準備する

    cvFloodFill(mask, new CvPoint(295, 75), new CvScalar(255, 255, 255,0), cvScalarAll(1), cvScalarAll(1), null, 4, null);

  2. 分割チャンネル

    cvSplit(hsvImage, hChannel, sChannel, vChannel, null);

  3. 色を変える

    cvAddS(vChannel, new CvScalar(255*(0.76-0.40),0,0,0), vChannel, mask);

画像からエッジと対応する領域をどのように検出できますか。

私はそれ以外の解決策を探していますがopencv、iPhoneとAndroidで可能でなければなりません

サンプル画像

編集

以下の手順を使用して、以下の画像のようにいくらかの結果を得ることができます

cvCvtColor(image, gray, CV_BGR2GRAY);   
cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0);
cvCanny(smooth, canny, 10, 250, 5);

この出力には 2 つの問題があります。解決方法がわからない 1. エッジの近くを閉じる 2. 小さなエッジを削除する

ここに画像の説明を入力

4

5 に答える 5

10

次のようなものを試すことができます:

 Mat imageOut = Mat::zeros(imageIn.rows, imageIn.cols, CV_8UC3);

 vector<vector<Point> > contours;
 vector<Vec4i> hierarchy;    

 findContours( imageIn, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
 for( int idx = 0; idx >= 0; idx = hierarchy[idx][0] )
 {
     Scalar color( rand()&255, rand()&255, rand()&255 );
     drawContours( imageOut, contours, idx, color, CV_FILLED, 8, hierarchy );
 }

壁をさまざまな色で描画する必要があります。それが機能する場合、それは「階層」で各壁が輪郭として識別されることを意味し、ユーザーがタッチスクリーンで選択したものを見つけて、色調整処理を行う必要があります。

「findContours」リンクのさまざまなパラメーターを変更する必要がある場合があります。また、輪郭検出の前に入力画像を滑らかにして、細部やテクスチャに煩わされないようにする必要があります。

お役に立てば幸いです、トーマス

于 2013-04-24T14:03:05.083 に答える
3

Canny Edge Detectionアルゴリズムを使用してエッジの違いを見つけることができると思います。いくつかのリンク

  1. スタックオーバーフロー
  2. スタックオーバーフロー
  3. OpenCV QA
  4. OpenCV
  5. ネイティブ チュートリアル

これがあなたを助けることができることを願っています。ありがとう。

于 2013-04-24T04:40:55.537 に答える
2

Mat呼び出された で最大の輪郭を見つけるための OpenCV4Android コードを次に示しますimage。これは RGBA 色空間にあると仮定します。輪郭を見つけるには、まず画像をしきい値処理または 2 値化 (白黒に変換) する必要があります。しきい値処理の前に画像にガウスぼかしを使用すると、生成される小さな輪郭の数が減ります。ぼかしとしきい値のサイズ パラメータは奇数でなければなりません。試してみて、どの値が最良の結果をもたらすかを見つけることができます (ここでは、両方に 7 を使用しました)。

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat BW = new Mat();
Mat hierarchy = new Mat();
MatOfPoint largestContour;

Imgproc.cvtColor(image, image, Imgproc.COLOR_RGBA2GRAY); // convert to grayscale

Imgproc.GaussianBlur(image, BW, new Size(7,7), 0); 

Imgproc.adaptiveThreshold(BW, BW, 255, 
    Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 7, 2.0);

Imgproc.findContours(BW, contours, hierarchy, Imgproc.RETR_EXTERNAL,
        Imgproc.CHAIN_APPROX_SIMPLE);

double maxArea = 0;
for (MatOfPoint contour : contours) {
    double area = Imgproc.contourArea(contour);
    if (area > maxArea) {
        maxArea = area;
        largestContour = contour;
    }
}
于 2013-04-25T03:46:14.370 に答える
0

この出力には 2 つの問題があります。解決方法がわからない 1. エッジの近くを閉じる 2. 小さなエッジを削除する

  1. モルフォロジー演算を使用してエッジを閉じることができます。拡張演算子と閉鎖演算子を探します。

  2. ラベリングを行うことで、小さなエッジを削除できます。各領域のピクセル数 (接続された白いピクセル) をカウントします。ピクセル数がしきい値よりも少ない領域を削除します。私は opencv を使用しませんが、ほとんどのライブラリにはラベル付け機能があり、単一色の接触ピクセルの各セットに出力画像で一意の色が割り当てられる画像を作成します。

于 2013-04-27T04:04:27.007 に答える