目录
- 前言
- 准备工作
- 使用OPenCV剪切矩形
- 使用OPenCV剪切圆形
前言
本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形。
准备工作
首先创建一个Wpf项目——WpfOpenCV,这里版本使用Framework4.7.2。
然后使用Nuget搜索【Emgu.CV】,如下图。

这里的Emgu.CV选择4.3.0.3890版本,然后安装Emgu.CV和Emgu.CV.runtime.windows。
使用OPenCV剪切矩形
现在,我们进入项目,进行OPenCV的调用。
首先引入命名空间,如下:
然后编写矩形剪切函数——CutRectangleImage。
函数里,我们先将图像进行缩放,这样可以有效的减少检测到的矩形数量。
再将图片处理成灰度模式,然后再高斯模糊,再边缘化。
然后,我们就可以在图片里查找图形轮廓了,当轮廓有三个顶点,那么它是三角形,如果有四个顶点,那么它是四边形;我们要截取矩形,所以这里要加一个角度的判断,四个角必须都在80-100度之间。
取到了顶点后,在依据顶点剪切图片就可以了。
下面是截取矩形的代码,代码中只截取了宽度最大的那个矩形。
public void CutRectangleImage(string imagePath)
{
Image<Bgr, Byte> src = new Image<Bgr, byte>(imagePath);
int scale = 1;
if (src.Width > 500)
{
scale = 2;
}
if (src.Width > 1000)
{
scale = 10;
}
if (src.Width > 10000)
{
scale = 100;
}
var size = new Size(src.Width / scale, src.Height / scale);
Image<Bgr, Byte> srcNewSize = new Image<Bgr, byte>(size);
CvInvoke.Resize(src, srcNewSize, size);
UMat grayImage = new UMat();
CvInvoke.CvtColor(srcNewSize, grayImage, ColorConversion.Bgr2Gray);
CvInvoke.GaussianBlur(grayImage, grayImage, new Size(3, 3), 3);
UMat cannyEdges = new UMat();
CvInvoke.Canny(grayImage, cannyEdges, 60, 180);
#region 取三角形和矩形的顶点坐标
List<Triangle2DF> triangleList = new List<Triangle2DF>();
List<RotatedRect> boxList = new List<RotatedRect>();
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);
if (CvInvoke.ContourArea(approxContour, false) > 50)
{
if (approxContour.Size == 3)
{
System.Drawing.Point[] pts = approxContour.ToArray();
triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
}
else if (approxContour.Size == 4)
{
#region 检测角度,如果角度都在 [80, 100] 之间,则为矩形
bool isRectangle = true;
System.Drawing.Point[] pts = approxContour.ToArray();
LineSegment2D[] edges = Emgu.CV.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 保存剪切的最大的矩形图片
Rectangle rectangle = new Rectangle(0, 0, src.Width, src.Height);
int maxWidth = 0;
for (int i = 0; i < boxList.Count(); i++)
{
RotatedRect box = boxList[i];
Rectangle rectangleTemp = box.MinAreaRect();
rectangleTemp = new Rectangle(rectangleTemp.X * scale, rectangleTemp.Y * scale, rectangleTemp.Width * scale + scale, rectangleTemp.Height * scale + scale);
if (rectangleTemp.Width > maxWidth)
{
maxWidth = rectangleTemp.Width;
rectangle = rectangleTemp;
}
}
src.Draw(rectangle, new Bgr(System.Drawing.Color.Red), 4);
CvInvoke.Imwrite("原始图片.bmp", src);
CvInvoke.cvSetImageROI(src.Ptr, rectangle);
var clone = src.Clone();
CvInvoke.Imwrite("剪切的矩形图片.bmp", clone);
#endregion
src.Dispose();
srcNewSize.Dispose();
grayImage.Dispose();
}
然后编写一个打开文件的函数,在成功打开文件后调用CutRectangleImage。
然后运行项目,点击剪切矩形文件。

然后到debug文件夹下,查看结果。
测试结果如下图所示:

图中红线为检测到矩形后,手动画上去的矩形轮廓。
使用OPenCV剪切圆形
编写矩形剪切函数——CutCircleImage。
函数里,我们依然先将图像进行缩放,为了有效的减少检测到的圆形数量。
再将图片处理成灰度模式,然后再高斯模糊。
然后再使用霍夫圆检测函数,获取圆的圆心和半径。
最后再根据圆心和半径计算出最小矩形,然后将圆剪切并保存。
代码如下:
运行项目进行测试,结果如下:

----------------------------------------------------------------------------------------------------
到此,C#使用OpenCV剪切图像中的圆形和矩形就已经介绍完了。
代码已经传到Github上了,欢迎大家下载。
Github地址:https://github.com/kiba518/OpenCv_CutImage
到此这篇关于C#使用OpenCV剪切图像中的圆形和矩形的文章就介绍到这了,更多相关C#剪切图像中的圆形和矩形内容请搜索得得之家以前的文章希望大家以后多多支持得得之家!