Visual studio 霍格圆不';t在OpenCV中正确检测圆
我使用的是Visual Studio 2015、OpenCV.3和EmguCV.3。 我的代码如下所示,结果如图所示。我知道问题是HoughCircles函数的输入值,但我不知道哪些输入适合这张图片。谢谢你的帮助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>
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
以下是从左到右的结果:
< /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,对你合适吗?