본문 바로가기

C# 윈도우 프로그래밍

Geometric model finder C#(2)

 

이번장에서는 geometric 모델 파인더에 대해 이어서 설명하도록 하겠다.

 

Geometric 모델 파인더에서 기본 모델을 만드는 과정은 전장을 참고 하시면 되고.
 

이게 근데 깨끗한 이미지면 모르겠지만 컨투어가 깔끔하게 안따질때 필요없는 컨투어를 좀 지우는 과정이 있으면 편리하다 물론 모폴로지 연산으로만도 다 할수도있지만 그것만으로도 충분하지 못할수도있으므로,

 

모델을 우선 geometric 을 얻기위해 findcontour명령으로 contours 리스트를 받아온 상태에서

 

Mat tt = new Mat();
for (int i = 0; i < contour1.Length; i++)
{

    for (int j = 0; j < contour1[i].Length; j++)
    {
        int x = contour1[i][j].X;
        int y = contour1[i][j].Y;
        if ((initpoint.X <= x) && (movepoint.X >= x) && (movepoint.Y >= y) && (initpoint.Y <= y))
        {
            Cv2.DrawContours(화면Mat, contour1, i, Scalar.Yellow);
            if (!drawinglist.Contains(i))
            {
                drawinglist.Add(i);
            }
            break;
        }
    }
    tt = 화면Mat.Clone();

}
Cv2.Rectangle(tt, initpoint, movepoint, new Scalar(255, 0, 0));
 

마우스로 드래그해서 해당 좌표에 해당하는 컨투어들을 선택하게 하면 된다.

 

 

 

 

이제 생성된 Geometric 모델로 이미지에서 찾는걸 구현하면.

 

Mat tk = 원본Mat.Clone();
using (Mat src = new Mat())
using (Mat gx = new Mat())
using (Mat gy = new Mat())
using (Mat direction = new Mat())
using (Mat magnitude = new Mat())
{
    if (tk.Channels() > 1)
    {
        Cv2.CvtColor(tk, src, ColorConversionCodes.RGB2GRAY);
    }
    else
    {
        tk.CopyTo(src);
    }
    //  Cv2.Canny(src, src, 0, 10);
    /// use the sobel filter on the source image which returns the gradients in the X (Gx) and Y (Gy) direction.
    Cv2.Sobel(src, gx, MatType.CV_64F, 1, 0, 3);
    Cv2.Sobel(src, gy, MatType.CV_64F, 0, 1, 3);

/// compute the magnitude and direction
    Cv2.CartToPolar(gx, gy, magnitude, direction);

    var minScore = 0.8;
    var greediness = 0.8;
    /// ncc match search
    long noOfCordinates = results0.Count;
    double normMinScore = minScore / noOfCordinates; // normalized min score
    double normGreediness = (1 - greediness * minScore) / (1 - greediness) / noOfCordinates;
    double partialScore = 0;
    double resultScore = 0;
    OpenCvSharp.Point center = new OpenCvSharp.Point();

    for (int i = 0, h = src.Height; i < h; i++)
    {
        for (int j = 0, w = src.Width; j < w; j++)
        {
            double partialSum = 0;
            for (var m = 0; m < noOfCordinates; m++)
            {
                var item = results0[m];
                var curX = (int)(j + item.Offset.X);
                var curY = (int)(i + item.Offset.Y);
                var iTx = item.Derivative.X;
                var iTy = item.Derivative.Y;
                if (curX < 0 || curY < 0 || curY > src.Height - 1 || curX > src.Width - 1)
                    continue;

                var iSx = gx.At<double>(curY, curX, 0);
                var iSy = gy.At<double>(curY, curX, 0);

                if ((iSx != 0 || iSy != 0) && (iTx != 0 || iTy != 0))
                {
                    var mag = magnitude.At<double>(curY, curX, 0);
                    var matGradMag = mag == 0 ? 0 : 1 / mag; // 1/√(dx²+dy²)
                    partialSum += ((iSx * iTx) + (iSy * iTy)) * (item.Magnitude * matGradMag);
                }

                var sumOfCoords = m + 1;
                partialScore = partialSum / sumOfCoords;
                if (partialScore < Math.Min((minScore - 1) + normGreediness * sumOfCoords, normMinScore * sumOfCoords))
                    break;
            }
            if (partialScore > Convert.ToDouble(Labelvalue.Text))
            {
                resultScore = partialScore;
                center.X = j;
                center.Y = i;
                if (tk.Channels() <2)
                {
                    Cv2.CvtColor(tk, tk, ColorConversionCodes.GRAY2RGB);
                }
                             
                Cv2.DrawContours(tk, new[] { results0.Select(_ => _.Offset.ToPoint()) }, -1, Scalar.LightGreen, 2, offset: center);
                Cv2.Circle(tk, center, 5, Scalar.Red, -1);

            }
        }
    }
                
}
ImageShow.Source = BitmapSourceConverter.ToBitmapSource(tk);
 

컨투어대한 모델 정보를 result에 가져와서 일치하는지 paritialscore점수로 판단해서 찾으면 된다.

 

각각의 파라미터에대한 설명은 앞장을 참고하시길.

 

 

반응형