C# 利用CVInvoke.AbsDiff方法从掩模中检测椭圆

C# 利用CVInvoke.AbsDiff方法从掩模中检测椭圆,c#,opencv,emgucv,C#,Opencv,Emgucv,我有一个椭圆,它随着时间而增长 为了检测椭圆,我使用了CvInvoke.AbsDiff方法。 我得到了这样的图像 我想把这个椭圆用椭圆法拟合,得到它的半径es 这就是我采取的方法 CvInvoke.AbsDiff(First, img, grayscale); CvInvoke.CvtColor(grayscale, grayscale, ColorConversion.Bgr2Gray); CvInvoke.GaussianBlur(

我有一个椭圆,它随着时间而增长

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

我想把这个椭圆用椭圆法拟合,得到它的半径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);
CvInvoke.AbsDiff(第一,img,灰度);
CvInvoke.CvtColor(灰度、灰度、颜色转换.Bgr2Gray);
高斯模糊(灰度,灰度,新系统。绘图。尺寸(11,11),15,15);
CvInvoke.Threshold(灰度、灰度、Convert.ToInt16(阈值)、Convert.ToInt16(阈值*2)、ThresholdType.Binary);
Mat element=CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,新系统.Drawing.Size(3,3),新系统.Drawing.Point(-1,-1));
CvInvoke.deflate(灰度,灰度,元素,新系统.绘图.点(-1,1),5,BorderType.常数,新MCvScalar(255,255,255));
Canny(灰度,灰度,阈值,最大阈值*2,3);
点轮廓向量的向量=点轮廓向量的新向量();
CvInvoke.FindContours(灰度、轮廓、null、RetrType.ccmp、ChainApproxMethod.chainApproxC89KCOS);
双面积=0;
双等高线面积=0;
int等高线=0;
int CenterX;
国际中心;
对于(int i=0;i
但我不是每次都能得到最好的椭圆。这是我得到的轮廓


有没有其他方法可以做到这一点?

尽管这种方法并不完全完美,但这可能是您可以采取的一个方向

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);
Mat input=CvInvoke.Imread(@“C:\Users\ajones\Desktop\Images\inputImg.png”,ImreadModes.AnyColor);
Mat input2=input.Clone();
垫脱粒=新垫();
高斯模糊(输入,阈值,新系统。绘图。尺寸(7,7),10,10);
阈值(thresh,thresh,3,10,ThresholdType.Binary);
CvInvoke.Imshow(“Thresh”,Thresh);
CvInvoke.WaitKey(0);
Mat输出=新Mat();
CvInvoke.CvtColor(阈值、输出、颜色转换.Bgr2Gray);
点轮廓向量的向量=点轮廓向量的新向量();
CvInvoke.FindContours(输出、轮廓、null、RetrType.External、ChainApproxMethod.ChainApproxSimple);
CvInvoke.DrawContours(输入,contours,-1,新MCvScalar(0,255,0),3,线型.FourConnected);
CvInvoke.Imshow(“图像”,输入);
CvInvoke.WaitKey(0);
int=0;
int指数=0;
for(int i=0;i最大)
{
最大=轮廓[i]。尺寸;
指数=i;
}
}
CvInvoke.DrawContours(输入2,等高线,索引,新MCvScalar(0,255,0),3,线型.四连通);
Imshow(“图像2”,输入2);
CvInvoke.WaitKey(0);
首先使用高斯滤波器模糊图像。

然后,使用二进制阈值。

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

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

正如我所说,这并不完全完美,但我应该帮助你朝着正确的方向前进