# 使用OPenCV剪切矩形

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Drawing;
using System.Windows.Forms;

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);
//仅考虑面积大于50的轮廓
if (CvInvoke.ContourArea(approxContour, false) > 50)
{
if (approxContour.Size == 3) //轮廓有3个顶点：三角形
{
System.Drawing.Point[] pts = approxContour.ToArray();
}
else if (approxContour.Size == 4) //轮廓有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
}
}
}
}
}
#endregion
#region 保存剪切的最大的矩形图片
Rectangle rectangle = new Rectangle(0, 0, src.Width, src.Height);
int maxWidth = 0;
//boxList = boxList.Where(p => p.Size.Width > 300).ToList();
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);//设置兴趣点—ROI（region of interest ）
var clone = src.Clone();
CvInvoke.Imwrite("剪切的矩形图片.bmp", clone); //保存结果图
#endregion
src.Dispose();
srcNewSize.Dispose();
grayImage.Dispose();
}

private void btnRectangle_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog frm = new System.Windows.Forms.OpenFileDialog();
frm.Filter = "(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif|All files(*.*)|*.*";
if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
CutRectangleImage(frm.FileName);
}
}

# 使用OPenCV剪切圆形

public void CutCircleImage(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);
//霍夫圆检测
CircleF[] circles = CvInvoke.HoughCircles(grayImage, HoughModes.Gradient, 2.0, 200.0, 100.0, 180.0, 5);
Rectangle rectangle = new Rectangle();
foreach (CircleF circle in circles)
{
var center = circle.Center;//圆心
{
rectangle = new Rectangle((int)(center.X - radius) * scale,
(int)radius * 2 * scale + scale,
(int)radius * 2 * scale + scale);
}
srcNewSize.Draw(circle, new Bgr(System.Drawing.Color.Blue), 4);
}
CvInvoke.Imwrite("原始图片.bmp", srcNewSize); //保存原始图片
{
MessageBox.Show("没有圆形");
}
CvInvoke.cvSetImageROI(srcNewSize.Ptr, rectangle);//设置兴趣点—ROI（region of interest ）
var clone = srcNewSize.Clone();
CvInvoke.Imwrite("剪切的圆形图片.bmp", clone); //保存结果图
src.Dispose();
srcNewSize.Dispose();
grayImage.Dispose();
}

|
12天前
|

opencv图像形态学

28 4
|
22天前
|

python利用opencv进行相机标定获取参数，并根据畸变参数修正图像附有全部代码（流畅无痛版）

42 3
|
1天前
|

C#图像爬虫实战：从Walmart网站下载图片
C#图像爬虫实战：从Walmart网站下载图片
18 1
|
20天前
|

49 1
|
1月前
|

37 2
|
3月前
|

【Qt&OpenCV 图像的感兴趣区域ROI】
【Qt&OpenCV 图像的感兴趣区域ROI】
85 1
|
3月前
|

【Qt&OpenCV 图像的模板匹配 matchTemplate/minMaxLoc】
【Qt&OpenCV 图像的模板匹配 matchTemplate/minMaxLoc】
49 1
|
2月前
|

OpenCV（Open Source Computer Vision Library）是一个开源的计算机视觉和机器学习库，它提供了大量的函数和工具，用于处理图像和视频数据。
OpenCV（Open Source Computer Vision Library）是一个开源的计算机视觉和机器学习库，它提供了大量的函数和工具，用于处理图像和视频数据。
38 0
|
3月前
|

【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
58 0
|
3月前
|

OpenCV中图像算术操作与逻辑操作
OpenCV中图像算术操作与逻辑操作
52 1