Visual studio 霍格圆不';t在OpenCV中正确检测圆

Visual studio 霍格圆不';t在OpenCV中正确检测圆,visual-studio,emgucv,opencv3.0,Visual Studio,Emgucv,Opencv3.0,我使用的是Visual Studio 2015、OpenCV.3和EmguCV.3。 我的代码如下所示,结果如图所示。我知道问题是HoughCircles函数的输入值,但我不知道哪些输入适合这张图片。谢谢你的帮助 Image<Gray, byte> OriginalImage = new Image<Gray, byte>(Openfile.FileName); Image<Gray, byte>

我使用的是Visual Studio 2015、OpenCV.3和EmguCV.3。 我的代码如下所示,结果如图所示。我知道问题是HoughCircles函数的输入值,但我不知道哪些输入适合这张图片。谢谢你的帮助

                Image<Gray, byte> OriginalImage = new Image<Gray, byte>(Openfile.FileName);
                Image<Gray, byte> ResizedImage = OriginalImage.Resize(OriginalImage.Width / 2, OriginalImage.Height / 2, Emgu.CV.CvEnum.Inter.Cubic);

                //********** Convert Image to Binary
                Image<Gray, byte> smoothImg = 
                ResizedImage.SmoothGaussian(5);
                smoothImg._Erode(5);
                smoothImg._Dilate(5);
                Image<Gray, byte> BinaryImage = 
                smoothImg.ThresholdBinary(new Gray(20), new Gray(255));

                //********** Find Circles
                Image<Rgb, byte> ROIImgScaledCircles = ROIImgScaled.Convert<Rgb, byte>();
                CircleF[] circles = smoothImg.HoughCircles(
                    new Gray(180),//cannyThreshold
                    new Gray(60),//circleAccumulatorThreshold
                    2.0, //dp:Resolution of the accumulator used to detect centers of the circles
                    10.0, //min distance 
                    10, //min radius
                    128 //max radius
                    )[0]; //Get the circles from the first channel
                foreach (CircleF cir in circles)
                {
                    ROIImgScaledCircles.Draw(cir, new Rgb(235, 20, 30), 1);
                }                   
                pbxCircles.Image = ROIImgScaledCircles.ToBitmap();
Image OriginalImage=新图像(Openfile.FileName);
Image ResizedImage=OriginalImage.Resize(OriginalImage.Width/2,OriginalImage.Height/2,Emgu.CV.CvEnum.Inter.Cubic);
//**********将图像转换为二进制
图像平滑img=
大小图像。平滑高斯(5);
磨蚀(5);
平滑扩张(5);
图像二进制图像=
smoothImg.ThresholdBinary(新灰度(20),新灰度(255));
//**********找圈
Image roimgscaledcircles=roimgscaled.Convert();
CircleF[]圆=平滑img.HoughCircles(
新灰色(180),//cannyThreshold
新灰色(60),//圆形或阈值
2.0,//dp:用于检测圆心的累加器的分辨率
10.0,//最小距离
10,//最小半径
128//最大半径
)[0]; //从第一个通道获取圆
foreach(圆中的cirlef cir)
{
图(cir,新Rgb(235,20,30),1);
}                   
pbxCircles.Image=roimgscaledcircles.ToBitmap();
原始图像:

创建的圈子:


使用完整的形状,您可能会发现检测边缘然后查找轮廓更容易。下面是一个例子:

Image original=新图像(@“E:\Downloads\original.jpg”);
UMat灰度=新UMat();
UMat-pyrdown=新的UMat();
UMat canny=新的UMat();
双筒保持=128;
CvInvoke.CvtColor(原始、灰度、颜色转换.Bgr2Gray);
//去除噪声并运行边缘检测
CvInvoke.PyrDown(灰度,PyrDown);
CvInvoke.PyrUp(pyrdown,灰度);
CvInvoke.Canny(灰度,Canny,cannyThreshold,cannyThreshold*2);
图像结果=original.Copy();
//找到并画圆
点轮廓向量的向量=点轮廓向量的新向量();
CvInvoke.FindContours(canny、contours、null、RetrType.List、ChainApproxMethod.ChainApproxSimple);
//CvInvoke.DrawContours(结果,contours,-1,新的MCvScalar(0,0255));
对于(int i=0;i
以下是从左到右的结果:

  • 原始图像
  • 模糊图像(使用pyrdown/pyrup)
  • canny边缘检测结果
  • 由等高线重建圆
  • < /P> < P>这里是一个解决方案(基于,而不是EMGUCV),它允许C代码非常接近所有在C++或Python中找到的OpenCV代码,但是你可以很容易地将它转换回EMGUCV。 我已经删除了腐蚀和放大步骤(在本例中,这只是过度破坏了原始图像)

    我使用的是hough圆调用上的循环(改变与累加器分辨率的反比),以确保我检测到多个圆,而不是我不感兴趣的圆

      int blurSize = 5;
      using (var src = new Mat("2Okrv.jpg"))
      using (var gray = src.CvtColor(ColorConversionCodes.BGR2GRAY))
      using (var blur = gray.GaussianBlur(new Size(blurSize, blurSize), 0))
      using (var dst = src.Clone())
      {
          // this hashset will automatically store all "unique" detected circles
          // circles are stored modulo some "espilon" value, set to 5 here (half of min size of hough circles below)
          var allCircles = new HashSet<CircleSegment>(new CircleEqualityComparer { Epsilon = 5 });
    
          // vary inverse ratio of accumulator resolution
          // depending on image, you may vary start/end/step
          for (double dp = 1; dp < 5; dp += 0.2)
          {
              // we use min dist = 1, to make sure we can detect concentric circles
              // we use standard values for other parameters (canny, ...)
              // we use your min max values (the max may be important when dp varies)
              var circles = Cv2.HoughCircles(blur, HoughMethods.Gradient, dp, 1, 100, 100, 10, 128);
              foreach (var circle in circles)
              {
                  allCircles.Add(circle);
              }
          }
    
          // draw final list of unique circles
          foreach (var circle in allCircles)
          {
              Cv2.Circle(dst, circle.Center, (int)circle.Radius, Scalar.FromRgb(235, 20, 30), 1);
          }
    
          // display images
          using (new Window("src image", src))
          using (new Window("dst image", dst))
          {
              Cv2.WaitKey();
          }
      }
    
      public class CircleEqualityComparer : IEqualityComparer<CircleSegment>
      {
          public double Epsilon { get; set; }
    
          public bool Equals(CircleSegment x, CircleSegment y) => x.Center.DistanceTo(y.Center) <= Epsilon && Math.Abs(x.Radius - y.Radius) <= Epsilon;
    
          // bit of a hack... we return a constant so only Equals is used to compare two circles
          // since we have only few circles that's ok, we don't play with millions...
          public int GetHashCode(CircleSegment obj) => 0;
      }
    
    int fullsize=5;
    使用(var src=new Mat(“2Okrv.jpg”))
    使用(var gray=src.CvtColor(ColorConversionCodes.BGR2GRAY))
    使用(var blur=gray.GaussianBlur(新大小(blurSize,blurSize),0))
    使用(var dst=src.Clone())
    {
    //此哈希集将自动存储所有检测到的“唯一”圆圈
    //圆圈按“espilon”值存储,此处设置为5(以下为hough圆圈最小尺寸的一半)
    var allCircles=newhashset(newcircleequalitycomparer{Epsilon=5});
    //改变累加器分辨率的反比
    //根据图像的不同,您可以改变开始/结束/步骤
    对于(双dp=1;dp<5;dp+=0.2)
    {
    //我们使用最小距离=1,以确保我们能够检测到同心圆
    //我们对其他参数使用标准值(canny,…)
    //我们使用您的最小-最大值(当dp变化时,最大值可能很重要)
    var circles=Cv2.HoughCircles(模糊,HoughMethods.Gradient,dp,1100,100,10,128);
    foreach(圆中的变量圆)
    {
    所有圆。添加(圆);
    }
    }
    //绘制唯一圆的最终列表
    foreach(所有圆中的变量圆)
    {
    Cv2.圆(dst,圆。中心,(int)圆。半径,标量。从RGB(235,20,30),1);
    }
    //显示图像
    使用(新窗口(“src图像”,src))
    使用(新窗口(“dst图像”,dst))
    {
    Cv2.WaitKey();
    }
    }
    公共类CircleEqualityComparer:IEqualityComparer
    {
    公共双ε{get;set;}
    
    public bool Equals(CircleSegment x,CircleSegment y)=>x.Center.DistanceTo(y.Center)你能提供原始图像吗?我想你需要2个圆?@SimonMourier我编辑了这个问题并添加了原始图像。事实上,是的,我需要2个圆。我使用opencvsharp(非常接近c++/python示例),而不是emgucv,对你合适吗?