C#使用OpenCV剪切图像中的圆形和矩形的示例代码
前言
本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形。
准备工作
首先创建一个Wpf项目——WpfOpenCV,这里版本使用Framework4.7.2。
然后使用Nuget搜索【Emgu.CV】,如下图。
这里的Emgu.CV选择4.3.0.3890版本,然后安装Emgu.CV和Emgu.CV.runtime.windows。
使用OPenCV剪切矩形
现在,我们进入项目,进行OPenCV的调用。
首先引入命名空间,如下:
usingEmgu.CV; usingEmgu.CV.CvEnum; usingEmgu.CV.Structure; usingSystem.Drawing; usingSystem.Windows.Forms;
然后编写矩形剪切函数——CutRectangleImage。
函数里,我们先将图像进行缩放,这样可以有效的减少检测到的矩形数量。
再将图片处理成灰度模式,然后再高斯模糊,再边缘化。
然后,我们就可以在图片里查找图形轮廓了,当轮廓有三个顶点,那么它是三角形,如果有四个顶点,那么它是四边形;我们要截取矩形,所以这里要加一个角度的判断,四个角必须都在80-100度之间。
取到了顶点后,在依据顶点剪切图片就可以了。
下面是截取矩形的代码,代码中只截取了宽度最大的那个矩形。
publicvoidCutRectangleImage(stringimagePath)
{
Imagesrc=newImage(imagePath);
intscale=1;
if(src.Width>500)
{
scale=2;
}
if(src.Width>1000)
{
scale=10;
}
if(src.Width>10000)
{
scale=100;
}
varsize=newSize(src.Width/scale,src.Height/scale);
ImagesrcNewSize=newImage(size);
CvInvoke.Resize(src,srcNewSize,size);
//将图像转换为灰度
UMatgrayImage=newUMat();
CvInvoke.CvtColor(srcNewSize,grayImage,ColorConversion.Bgr2Gray);
//使用高斯滤波去除噪声
CvInvoke.GaussianBlur(grayImage,grayImage,newSize(3,3),3);
UMatcannyEdges=newUMat();
CvInvoke.Canny(grayImage,cannyEdges,60,180);//通过边缘化,然后取出轮廓
#region取三角形和矩形的顶点坐标
ListtriangleList=newList();
ListboxList=newList();//旋转的矩形框
using(VectorOfVectorOfPointcontours=newVectorOfVectorOfPoint())
{
CvInvoke.FindContours(cannyEdges,contours,null,RetrType.List,ChainApproxMethod.ChainApproxSimple);
intcount=contours.Size;
for(inti=0;i50)
{
if(approxContour.Size==3)//轮廓有3个顶点:三角形
{
System.Drawing.Point[]pts=approxContour.ToArray();
triangleList.Add(newTriangle2DF(pts[0],pts[1],pts[2]));
}
elseif(approxContour.Size==4)//轮廓有4个顶点
{
#region检测角度,如果角度都在[80,100]之间,则为矩形
boolisRectangle=true;
System.Drawing.Point[]pts=approxContour.ToArray();
LineSegment2D[]edges=Emgu.CV.PointCollection.PolyLine(pts,true);
for(intj=0;j100)
{
isRectangle=false;
break;
}
}
#endregion
if(isRectangle)boxList.Add(CvInvoke.MinAreaRect(approxContour));
}
}
}
}
}
#endregion
#region保存剪切的最大的矩形图片
Rectanglerectangle=newRectangle(0,0,src.Width,src.Height);
intmaxWidth=0;
//boxList=boxList.Where(p=>p.Size.Width>300).ToList();
for(inti=0;imaxWidth)
{
maxWidth=rectangleTemp.Width;
rectangle=rectangleTemp;
}
}
src.Draw(rectangle,newBgr(System.Drawing.Color.Red),4);//在图片中画线
CvInvoke.Imwrite("原始图片.bmp",src);//保存原始图片
CvInvoke.cvSetImageROI(src.Ptr,rectangle);//设置兴趣点—ROI(regionofinterest)
varclone=src.Clone();
CvInvoke.Imwrite("剪切的矩形图片.bmp",clone);//保存结果图
#endregion
src.Dispose();
srcNewSize.Dispose();
grayImage.Dispose();
}
然后编写一个打开文件的函数,在成功打开文件后调用CutRectangleImage。
privatevoidbtnRectangle_Click(objectsender,RoutedEventArgse)
{
System.Windows.Forms.OpenFileDialogfrm=newSystem.Windows.Forms.OpenFileDialog();
frm.Filter="(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif|Allfiles(*.*)|*.*";
if(frm.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
CutRectangleImage(frm.FileName);
}
}
然后运行项目,点击剪切矩形文件。
然后到debug文件夹下,查看结果。
测试结果如下图所示:
图中红线为检测到矩形后,手动画上去的矩形轮廓。
使用OPenCV剪切圆形
编写矩形剪切函数——CutCircleImage。
函数里,我们依然先将图像进行缩放,为了有效的减少检测到的圆形数量。
再将图片处理成灰度模式,然后再高斯模糊。
然后再使用霍夫圆检测函数,获取圆的圆心和半径。
最后再根据圆心和半径计算出最小矩形,然后将圆剪切并保存。
代码如下:
publicvoidCutCircleImage(stringimagePath)
{
Imagesrc=newImage(imagePath);
intscale=1;
if(src.Width>500)
{
scale=2;
}
if(src.Width>1000)
{
scale=10;
}
if(src.Width>10000)
{
scale=100;
}
varsize=newSize(src.Width/scale,src.Height/scale);
ImagesrcNewSize=newImage(size);
CvInvoke.Resize(src,srcNewSize,size);
//将图像转换为灰度
UMatgrayImage=newUMat();
CvInvoke.CvtColor(srcNewSize,grayImage,ColorConversion.Bgr2Gray);
//使用高斯滤波去除噪声
CvInvoke.GaussianBlur(grayImage,grayImage,newSize(3,3),3);
//霍夫圆检测
CircleF[]circles=CvInvoke.HoughCircles(grayImage,HoughModes.Gradient,2.0,200.0,100.0,180.0,5);
Rectanglerectangle=newRectangle();
floatmaxRadius=0;
foreach(CircleFcircleincircles)
{
varcenter=circle.Center;//圆心
varradius=circle.Radius;//半径
if(radius>maxRadius)
{
maxRadius=radius;
rectangle=newRectangle((int)(center.X-radius)*scale,
(int)(center.Y-radius)*scale,
(int)radius*2*scale+scale,
(int)radius*2*scale+scale);
}
srcNewSize.Draw(circle,newBgr(System.Drawing.Color.Blue),4);
}
CvInvoke.Imwrite("原始图片.bmp",srcNewSize);//保存原始图片
if(maxRadius==0)
{
MessageBox.Show("没有圆形");
}
CvInvoke.cvSetImageROI(srcNewSize.Ptr,rectangle);//设置兴趣点—ROI(regionofinterest)
varclone=srcNewSize.Clone();
CvInvoke.Imwrite("剪切的圆形图片.bmp",clone);//保存结果图
src.Dispose();
srcNewSize.Dispose();
grayImage.Dispose();
}
运行项目进行测试,结果如下:
----------------------------------------------------------------------------------------------------
到此,C#使用OpenCV剪切图像中的圆形和矩形就已经介绍完了。
代码已经传到Github上了,欢迎大家下载。
Github地址:https://github.com/kiba518/OpenCv_CutImage
到此这篇关于C#使用OpenCV剪切图像中的圆形和矩形的文章就介绍到这了,更多相关C#剪切图像中的圆形和矩形内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。