【问题标题】:Detecting ellipse from a Mask uing CVInvoke.AbsDiff Method使用 CVInvoke.AbsDiff 方法从掩码中检测椭圆
【发布时间】:2020-09-08 15:43:02
【问题描述】:

我有一个随时间增长的椭圆。

为了检测椭圆,我使用了 CvInvoke.AbsDiff 方法。 我得到这样的图像

我想把这个椭圆放到fit-ellipse方法中,得到它的半径es。

这是我采取的方法。

            CvInvoke.AbsDiff(First, img, grayscale);
        CvInvoke.CvtColor(grayscale, grayscale, ColorConversion.Bgr2Gray);
        CvInvoke.GaussianBlur(grayscale, grayscale, new System.Drawing.Size(11, 11), 15, 15);
        CvInvoke.Threshold(grayscale, grayscale, Convert.ToInt16(Threshold), Convert.ToInt16(Threshold * 2), ThresholdType.Binary );
        Mat element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new System.Drawing.Size(3, 3), new System.Drawing.Point(-1, -1));

        CvInvoke.Dilate(grayscale, grayscale, element, new System.Drawing.Point(-1, 1), 5, BorderType.Constant, new MCvScalar(255, 255, 255));
        CvInvoke.Canny(grayscale, grayscale, Threshold, MaxThreshold * 2, 3);
        VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
        CvInvoke.FindContours(grayscale, contours, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxTc89Kcos);


        double area = 0;
        double ContourArea = 0;
        int contour = 0;
        int CenterX;
        int CenterY;
        for (int i = 0; i < contours.Size; i++)
        {

            System.Drawing.Rectangle rec = CvInvoke.BoundingRectangle(contours[i]);

            output.Draw(rec, new Bgr(255, 0, 255), 2);
            CenterX = ((rec.Width) / 2) + rec.X;
            CenterY = ((rec.Height) / 2) + rec.Y;
            ContourArea = rec.Width * rec.Height; ;

            if ((HWidth - CenterFactor) < CenterX && CenterX < (HWidth + CenterFactor) && (HHeight - CenterFactor) < CenterY && CenterY< (HHeight + CenterFactor) )
            {
                if (ContourArea < 1000000)
                    if (area < ContourArea)
                    {
                        area = ContourArea;
                        contour = i;

                    }
            }
        }
        //if (contour == 0)
        //{
        //    return arr;
        //}
        System.Drawing.Rectangle rect = CvInvoke.BoundingRectangle(contours[contour]);
        output.Draw(rect, new Bgr(0, 255, 0), 3);

但我不是每次都得到最好的椭圆。这是我得到的轮廓

还有其他方法吗?

【问题讨论】:

    标签: c# opencv emgucv


    【解决方案1】:

    虽然这种方法并不完美,但这可能是您可以采取的一个可能的方向。

    Mat input = CvInvoke.Imread(@"C:\Users\ajones\Desktop\Images\inputImg.png", ImreadModes.AnyColor);
    Mat input2 = input.Clone();
    
    Mat thresh = new Mat();
    CvInvoke.GaussianBlur(input, thresh, new System.Drawing.Size(7, 7), 10, 10);
    
    CvInvoke.Threshold(thresh, thresh, 3, 10, ThresholdType.Binary);
    
    CvInvoke.Imshow("The Thresh", thresh);
    CvInvoke.WaitKey(0);
    
    Mat output = new Mat();
    CvInvoke.CvtColor(thresh, output, ColorConversion.Bgr2Gray);
    
    VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
    
    CvInvoke.FindContours(output, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);
    CvInvoke.DrawContours(input, contours, -1, new MCvScalar(0, 255, 0), 3, LineType.FourConnected);
    
    CvInvoke.Imshow("The Image", input);
    CvInvoke.WaitKey(0);
    
    int biggest = 0;
    int index = 0;
    for (int i = 0; i<contours.Size; i++)
    {
        if (contours[i].Size > biggest)
        {
            biggest = contours[i].Size;
            index = i;
        }
    }
    
    CvInvoke.DrawContours(input2, contours, index, new MCvScalar(0, 255, 0), 3, LineType.FourConnected);
    
    CvInvoke.Imshow("The Image2", input2);
    CvInvoke.WaitKey(0);
    

    首先使用高斯滤镜对图像进行模糊处理。

    然后,使用二进制阈值。

    然后,找到图像上的所有轮廓

    最后,您需要做的就是对轮廓进行排序,直到找到最大的轮廓。

    就像我说的,它并不完全完美,但我应该帮助你朝着正确的方向前进。

    【讨论】:

      猜你喜欢
      • 2020-08-11
      • 2016-12-24
      • 2012-06-14
      • 2014-03-29
      • 2017-07-01
      • 2014-12-23
      • 2011-09-12
      • 1970-01-01
      • 2015-01-12
      相关资源
      最近更新 更多