一、圆检测
Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 30, 80, 20, 40, 80);
- 检测 最短距离为30,阈值80,累加值20,半径在[40,80]之间的圆。
二、圆环切割
Mat maskROI = Mat.Zeros(dst.Size(), dst.Type());
Cv2.Circle(maskROI, (int)cs[0].Center.X, (int)cs[0].Center.Y, (int)cs[0].Radius+10, new Scalar(255, 255, 255), 30, LineTypes.AntiAlias);
- 在mask黑色背景下,画一个圆,半径+10,厚度30的环,填充白色
Mat myROI = new Mat();
src_img.CopyTo(myROI, maskROI);
- 原始图形与掩膜遮挡,完成图像的切割。
圆环的截取
三、掩膜
-
掩膜(binary Mask)
通俗地讲就是一个遮挡板,喷漆,或者雕刻或者喷漆的时候,会用一个特定形状的遮板放在被修改的材料上,按照挡板的形状就可以很贴合地得到最后你想要的图案。掩膜就是这么个东西。 -
【二元掩膜】
binary Mask 叫做二元掩膜。因为在图像处理的时候,计算机识别图像是将图像当作一个矩阵,你要把一个遮挡板放在一个图像上进行操作,图像矩阵和另外一个“遮挡板”矩阵进行乘积运算,从而得到你想要的结果。举例来说:
图中可以看出,经过掩膜处理之后,其他的部分都被“掩膜”中的0值过滤掉了,剩余的部分就是想要的部分。
四、掩膜的作用
因为整个特性,在计算机视觉中,人们常用掩膜来作以下作用:
- 提取感兴趣区:
用预先制作的感兴趣区掩膜与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0; - 屏蔽作用:
用掩膜对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计; - 结构特征提取:
用相似性变量或图像匹配方法检测和提取图像中与掩膜相似的结构特征; - 特殊形状图像的制作。
「暖仔会飞」的博客:
https://blog.csdn.net/qq_42902997/article/details/105003522
五、程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sunny.UI;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace Ky_HoughCircle
{
public partial class Form1 : UIForm
{
public Form1()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
}
private Image image = null;
private Mat dst = new Mat();
private Mat src_img;
string filePath = "";
//private static int Num = 20;
private List<Mat> reList = new List<Mat>();
private int step = 1;
public struct CircleSegment0
{
public Point2f Center;
public float Radius;
};
CircleSegment0[] cs0 = new CircleSegment0[10];
private void openImage_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "选择操作的图片";
openFileDialog.Filter = "图片 *.jpg|*.jpg|*.bmp|*.bmp|图像*.png|*.png";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
image = Image.FromFile(filePath);
src_img = Cv2.ImRead(filePath);
Mat tem1 = new Mat();
src_img.CopyTo(tem1);
if (reList.Count > 0)
{
reList[0] = tem1;
}
else
{
reList.Add(tem1);
}
}
if (filePath != "")
{
picBoxShowDel.Image = image;
picShowOri.Image = image;
}
}
private void uiButton2_Click(object sender, EventArgs e)
{
{
//1:因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做)
Mat m1 = new Mat();
Cv2.MedianBlur(src_img, m1, 3); // ksize必须大于1且是奇数
//2:转为灰度图像
Mat m2 = new Mat();
Cv2.CvtColor(m1, m2, ColorConversionCodes.BGR2GRAY);
//3:霍夫圆检测:使用霍夫变换查找灰度图像中的圆。
CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 30, 80, 20, 40, 80);
src_img.CopyTo(dst);
for (int i = 0; i < cs.Count(); i++)
{
//画圆
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, new Scalar(0, 0, 255), 5, LineTypes.AntiAlias);
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius+30, new Scalar(0, 255, 255), 3, LineTypes.AntiAlias);
//加强圆心显示
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 3, LineTypes.AntiAlias);
cs0[i].Center = cs[i].Center;
cs0[i].Radius = cs[i].Radius;
int x0 = (int)cs[i].Center.X;
int y0 = (int)cs[i].Center.Y;
//显示圆心坐标
Cv2.PutText(dst, i.ToString() + "(" + x0.ToString() + "," + y0.ToString() + ")", new OpenCvSharp.Point(x0 - 100, y0 + 200), 0, 1.25, new OpenCvSharp.Scalar(0, 0, 255), 2);
}
//using (new Window("OutputImage", WindowMode.AutoSize, dst))
picBoxShowDel.Image = dst.ToBitmap();
Mat maskROI = Mat.Zeros(dst.Size(), dst.Type());//在mask黑色背景下,画一样的圆,填充白色
Cv2.Circle(maskROI, (int)cs[0].Center.X, (int)cs[0].Center.Y, (int)cs[0].Radius+10, new Scalar(255, 255, 255), 30, LineTypes.AntiAlias);
Mat myROI = new Mat();
src_img.CopyTo(myROI, maskROI);
pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(myROI);
}
}
}
}










网友评论