2

参照:スパイラルのターンを検出してカウントする方法

ピクセルベースの計算でもカウントを取得できません。

画像を添付した場合、ターンのカウントから始める方法。

FindContours(); を試しました。しかし、それができないターンを完全に分離することはできません。また、matchshape() には類似度がありますが、コイル全体が対象です。

そこで、ターン数について次のように試しました。

 public static int GetSpringTurnCount()
        {
            if (null == m_imageROIed)
                return -1;
            int imageWidth = m_imageROIed.Width;
            int imageHeight = m_imageROIed.Height;

            if ((imageWidth <= 0) || (imageHeight <= 0))
                return 0;

            int turnCount = 0;

            Image<Gray, float> imgGrayF = new Image<Gray, float>(imageWidth, imageHeight);

            CvInvoke.cvConvert(m_imageROIed, imgGrayF);

            imgGrayF = imgGrayF.Laplace(1); // For saving integer overflow.

            Image<Gray, byte> imgGray = new Image<Gray, byte>(imageWidth, imageHeight);
            Image<Gray, byte> cannyEdges = new Image<Gray, byte>(imageWidth, imageHeight);

            CvInvoke.cvConvert(imgGrayF, imgGray);

            cannyEdges = imgGray.Copy();

            //cannyEdges = cannyEdges.ThresholdBinary(new Gray(1), new Gray(255));// = cannyEdges > 0 ? 1 : 0;
            cannyEdges = cannyEdges.Max(0);

            cannyEdges /= 255;

            Double[] sumRow = new Double[cannyEdges.Cols];
            //int sumRowIndex = 0;
            int Rows = cannyEdges.Rows;
            int Cols = cannyEdges.Cols;
            for (int X = 0; X < cannyEdges.Cols; X++)
            {
                Double sumB = 0;

                for (int Y = 0; Y < cannyEdges.Rows; Y ++)
                {
                    //LineSegment2D lines1 = new LineSegment2D(new System.Drawing.Point(X, 0), new System.Drawing.Point(X, Y));

                    Double pixels = cannyEdges[Y, X].Intensity;

                    sumB += pixels;


                }
                sumRow[X] = sumB;
            }

            Double avg = sumRow.Average();

List<int> turnCountList = new List<int>();

            int cnt = 0;
            foreach(int i in sumRow)
            {
                sumRow[cnt] /=  avg;
                if(sumRow[cnt]>3.0)
                turnCountList.Add((int)sumRow[cnt]);
                    cnt++;
            }
            turnCount = turnCountList.Count();

 cntSmooth = cntSmooth * 0.9f + (turnCount) * 0.1f;
            return (int)cntSmooth;
    }

ここに画像の説明を入力

次はサーフィンに挑戦します。

==================================================

編集:サンプルを追加します。あなたがそれを好きなら、それをしてください。 ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

==================================================

編集:別のアルゴリズムを試しました:

  1. ROI の次に回転 (最大の薄い水色の長方形)
  2. GetMoments() は、モーメントを使用して ROI の高さと位置.Y を縮小します。
  3. 縮小した ROI を設定し、空白の画像で ._And() を実行します。( 緑色の四角形の灰色の領域 )
  4. 画像を半分にカットします。
  5. 輪郭を描き、楕円に合わせます。
  6. 適合楕円の最大数を取得します。

後で、より良いアルゴリズムと結果に取り組みます。

ここに画像の説明を入力

4

1 に答える 1

0

白い色のより大きなクラスターが春であると仮定します

- 編集 -

  1. 画像に逆しきい値を適用し、フラッドフィルアルゴリズムでコーナーを塗りつぶします。
  2. findContoursとminAreaRectを使用して、最大の白いクラスターの回転したバウンディングボックスを見つけます
  3. 次のようにして、ボックスの長軸をトレースします
  4. 現在のピクセルを垂直に通る軸トレース軸線に沿った各ピクセル
  5. この線は、少なくとも2点でばねと交差します。
  6. 軸からの距離が大きい点を見つけます
  7. これにより、正弦関数と同様のポイントにコレクションが作成されます
  8. このコレクションのピークまたはクラスターを数えると、ループの数が2倍になります。

これはすべて、画像に高いノイズがないことを前提としています。

于 2012-12-12T18:16:34.800 に答える