环境Win7-64+VS2012+EmguCV3.0.0
使用Hough变换在灰度图像中查找圆圈:HoughCircles()
public static CircleF[] HoughCircles(
IInputArray image,//输入图像,8位单通道灰度图像
HoughType method,//检测方法使用。目前,唯一实现的方法是CV_HOUGH_GRADIENT
double dp,//累加器分辨率与图像分辨率的反比。例如,如果dp = 1,则累加器具有与输入图像相同的分辨率。如果dp = 2,则累加器的宽度和高度都是一半
double minDist,//检测到的圆的中心之间的最小距离。太小会多检,太大会漏检
double param1 = 100,//传递给Canny()检测器的两个阈值中的较高的阈值(较高的是较低的两倍左右)
double param2 = 100,//检测阶段圆心的累加器阈值。越小,可得到越多的圆
int minRadius = 0,//最小圆半径
int maxRadius = 0//最大圆半径
)
按照Emgu CV3+C#图像处理(一)新建一个C#控制台应用程序,然后引用相应的dll文件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
//从文件加载图像
String imagePath = "E:\\image\\01.jpg";
Image src = new Image(@imagePath);
CvInvoke.Imshow("src", src);
//将图像转换为灰度
UMat grayImage = new UMat();
CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);
//使用高斯滤波去除噪声
CvInvoke.GaussianBlur(grayImage, grayImage, new Size(5, 5), 3);
//CvInvoke.Imshow("Blur Image", grayImage);
//霍夫圆检测
CircleF[] circles = CvInvoke.HoughCircles(grayImage, HoughType.Gradient, 2.0, 20.0, 100.0, 180.0, 5);
#region draw circles
Image circleImage = src.Clone();
foreach (CircleF circle in circles)
circleImage.Draw(circle, new Bgr(Color.Blue), 4);
CvInvoke.Imshow("HoughCircles", circleImage);
CvInvoke.WaitKey(0);
#endregion
}
}
}
使用概率Hough变换在二进制图像中查找线段:HoughLinesP()
public static LineSegment2D[] HoughLinesP(
IInputArray image,//8位单通道二进制图像
double rho,//累加器的距离分辨率,以像素为单位
double theta,累加器的角度分辨率,以弧度表示
int threshold,//累加器阈值参数,只返回达到票数的
double minLineLength = 0,//最小线长,过短的线段被放弃
double maxGap = 0//在同一行上的点之间允许的最大距离
)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
//从文件加载图像
String imagePath = "E:\\image\\line.jpg";
Image src = new Image(@imagePath);
CvInvoke.Imshow("src", src);
//将图像转换为灰度
UMat grayImage = new UMat();
CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);
//使用高斯滤波去除噪声
CvInvoke.GaussianBlur(grayImage, grayImage, new Size(5, 5), 3);
//CvInvoke.Imshow("Blur Image", grayImage);
#region Lines detection
UMat cannyEdges = new UMat();
CvInvoke.Canny(grayImage, cannyEdges, 100, 120);
//CvInvoke.Imshow("Canny Image", cannyEdges);
LineSegment2D[] lines = CvInvoke.HoughLinesP(cannyEdges, 1, Math.PI / 20.0, 30, 80, 30);
#endregion
#region draw lines
Image lineImage = src.Clone();
foreach (LineSegment2D line in lines)
lineImage.Draw(line, new Bgr(Color.HotPink), 2);
CvInvoke.Imshow("lineImage", lineImage);
CvInvoke.WaitKey();
#endregion
}
}
}
官方例程里有一个检测矩形三角形的,看着很不错,特此贴一下:
示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
using Emgu.CV.Structure;
using Emgu.CV.Util;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
//从文件加载图像
String imagePath = "E:\\image\\010.jpg";
Image src = new Imagebyte>(@imagePath);
CvInvoke.Imshow("src", src);
//将图像转换为灰度
UMat grayImage = new UMat();
CvInvoke.CvtColor(src, grayImage, ColorConversion.Bgr2Gray);
//使用高斯滤波去除噪声
CvInvoke.GaussianBlur(grayImage, grayImage, new Size(3, 3), 3);
//CvInvoke.Imshow("Blur Image", grayImage);
#region Canny and edge detection
UMat cannyEdges = new UMat();
CvInvoke.Canny(grayImage, cannyEdges, 60, 180);
CvInvoke.Imshow("Canny Image", cannyEdges);
#endregion
#region Find triangles and rectangles
List triangleList = new List();
List boxList = new List(); //旋转的矩形框
using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
{
CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
int count = contours.Size;
for (int i = 0; i < count; i++)
{
using (VectorOfPoint contour = contours[i])
using (VectorOfPoint approxContour = new VectorOfPoint())
{
CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.08, true);
//仅考虑面积大于50的轮廓
if (CvInvoke.ContourArea(approxContour, false) > 50)
{
if (approxContour.Size == 3) //轮廓有3个顶点:三角形
{
Point[] pts = approxContour.ToArray();
triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
}
else if (approxContour.Size == 4) //轮廓有4个顶点
{
#region determine if all the angles in the contour are within [80, 100] degree
bool isRectangle = true;
Point[] pts = approxContour.ToArray();
LineSegment2D[] edges = PointCollection.PolyLine(pts, true);
for (int j = 0; j < edges.Length; j++)
{
double angle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
if (angle < 80 || angle > 100)
{
isRectangle = false;
break;
}
}
#endregion
if (isRectangle) boxList.Add(CvInvoke.MinAreaRect(approxContour));
}
}
}
}
}
#endregion
//显示结果
#region draw triangles and rectangles
Image triangleRectangleImage = src.CopyBlank();
foreach (Triangle2DF triangle in triangleList)
triangleRectangleImage.Draw(triangle, new Bgr(Color.DarkBlue), 2);
CvInvoke.Imshow("triangleRectangleImage", triangleRectangleImage);
Image RectangleImage = src.CopyBlank();
foreach (RotatedRect box in boxList)
RectangleImage.Draw(box, new Bgr(Color.DarkOrange), 2);
CvInvoke.Imshow("RectangleImage", RectangleImage);
CvInvoke.WaitKey();
#endregion
}
}
}
Emgu CV Library Documentation::CvInvoke.HoughCircles Method
Emgu CV Library Documentation::CvInvoke.HoughLinesP Method
Emgu CV Library Documentation::Shape (Triangle, Rectangle, Circle, Line) Detection in CSharp