OpenCvSharp手绘ROI区域+模板匹配+霍夫变换检测圆的边界
最终效果如下:
左侧为检测图片、右侧为模板,右下角textbox为轮毂中心的像素坐标
操作步骤:
1、点击打开图像选择一张比较不错的图片,用于画模板;
2、在picturebox中画取ROI区域生成模板(拖拽线不显示就合理利用微软提供的画形状的方法和合理使用picturebox.Refresh()即可解决);
3、重新选取一张待检测图片,点击模板匹配,即可找到ROI区域并把圆的边界和圆心找到;
完整代码如下(代码还有待改善):
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Linq;
using System.Windows.Forms;
using Point = OpenCvSharp.Point;
using Size = OpenCvSharp.Size;namespace DrawROI
{public partial class Form1 : Form{private System.Drawing.Point RectStartPoint, tempEndPoint;bool blnDraw;Mat ImageROI;Mat OrgMat;private string FilePath;public Form1(){InitializeComponent();}private void pictureBox1_MouseDown(object sender, MouseEventArgs e){RectStartPoint = e.Location; //获得鼠标按下的pictureBox上坐标Invalidate();blnDraw = true;//判断标志}private void pictureBox1_MouseMove(object sender, MouseEventArgs e){if (blnDraw){if (e.Button != MouseButtons.Left)//判断是否按下左键{return;}tempEndPoint = e.Location; //记录框的位置和大小//pictureBox上开始点坐标//Rect.Location = new System.Drawing.Point(//Math.Min(RectStartPoint.X, tempEndPoint.X),//Math.Min(RectStartPoint.Y, tempEndPoint.Y));pictureBox上矩形大小//Rect.Size = new System.Drawing.Size(//Math.Abs(RectStartPoint.X - tempEndPoint.X),//Math.Abs(RectStartPoint.Y - tempEndPoint.Y));pictureBox1.Invalidate();// 最后点位置int X0, Y0;Utilities.ConvertCoordinates(pictureBox1, out X0, out Y0, e.X, e.Y);//在控件中//textBox1.Text = Convert.ToString("pictureBox最后点坐标" + e.X + " ," + e.Y); //pictureBox 上终点坐标//textBox2.Text = Convert.ToString("pictureBox开始点坐标" + Rect.X + " ," + Rect.Y); //开始点坐标//textBox3.Text = Convert.ToString("pictureBox的Width" + Rect.Width + " ," + Rect.Height);//大小//Create ROI 感兴趣区域Utilities.ConvertCoordinates(pictureBox1, out X0, out Y0, RectStartPoint.X, RectStartPoint.Y);int X1, Y1;Utilities.ConvertCoordinates(pictureBox1, out X1, out Y1, tempEndPoint.X, tempEndPoint.Y);//感兴趣区域 左上点坐标-宽-高//RealImageRect.Location = new System.Drawing.Point(// Math.Min(X0, X1),// Math.Min(Y0, Y1));//RealImageRect.Size = new System.Drawing.Size(// Math.Abs(X0 - X1),// Math.Abs(Y0 - Y1));//textBox4.Text = "原图像上最后点坐标: X:" + X0 + " Y:" + Y0;//textBox5.Text = "原图像上RealImageRect: X:" + RealImageRect.X + " Y:" + RealImageRect.Y; // 原图像-左上点坐标//textBox6.Text = "原图像上RealImageRectSize: X:" + RealImageRect.Width + " Y:" + RealImageRect.Height; // 原图像-大小Rect tmp_Rect = new Rect(Math.Min(X0, X1), Math.Min(Y0, Y1), Math.Abs(X0 - X1), Math.Abs(Y0 - Y1));ImageROI = new Mat(OrgMat, tmp_Rect);//新建一个mat,把roi内的图像加载到里面去。//Cv2.ImWrite("4.jpg",ImageROI); //保存 }}private void pictureBox1_MouseUp(object sender, MouseEventArgs e){// mouseUp 结束以后 将图像显示在pictureBox2控件中pictureBox2.Image = ImageROI.ToBitmap();//***************************************//blnDraw = false; //结束绘制 }private void button1_Click(object sender, EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.ShowDialog();FilePath = openFileDialog.FileName;OrgMat = new Mat(FilePath, ImreadModes.Grayscale);OrgMat.MedianBlur(3);pictureBox1.Image = BitmapConverter.ToBitmap(OrgMat);}private void button3_Click(object sender, EventArgs e){if (ImageROI == null){MessageBox.Show("请先绘制模板");return;}Mat RoiClone = ImageROI.Clone();Mat mat3 = new Mat();//创建result的模板,就是MatchTemplate里的第三个参数//mat3.Create(mat1.Cols - mat2.Cols + 1, mat1.Rows - mat2.Rows + 1, MatType.CV_32FC1);//进行匹配(1母图,2模版子图,3返回的result,4匹配模式)Cv2.MatchTemplate(OrgMat, RoiClone, mat3, TemplateMatchModes.SqDiff);//对结果进行归一化(这里我测试的时候没有发现有什么用,但在opencv的书里有这个操作,应该有什么神秘加成,这里也加上)Cv2.Normalize(mat3, mat3, 1, 0, NormTypes.MinMax, -1);//double minValue, maxValue;Point minLocation, maxLocation;/// 通过函数 minMaxLoc 定位最匹配的位置/// (这个方法在opencv里有5个参数,这里我写的时候发现在有3个重载,看了下可以直接写成拿到起始坐标就不取最大值和最小值了)/// minLocation和maxLocation根据匹配调用的模式取不同的点Cv2.MinMaxLoc(mat3, out minLocation, out maxLocation);Mat OrgMatClone = OrgMat.Clone();//画出匹配的矩,//Cv2.Rectangle(mask, maxLocation, new Point(maxLocation.X + mat2.Cols, maxLocation.Y + mat2.Rows), Scalar.Red, 2);Cv2.Rectangle(OrgMatClone, minLocation, new Point(minLocation.X + RoiClone.Cols, minLocation.Y + RoiClone.Rows), Scalar.Red, 2);//Cv2.ImShow("mat1", mat1);//Cv2.ImShow("mat2", mat2);//霍夫圆检测:使用霍夫变换查找灰度图像中的圆。/** 参数:* 1:输入参数: 8位、单通道、灰度输入图像* 2:实现方法:目前,唯一的实现方法是HoughCirclesMethod.Gradient* 3: dp :累加器分辨率与图像分辨率的反比。默认=1* 4:minDist: 检测到的圆的中心之间的最小距离。(最短距离-可以分辨是两个圆的,否则认为是同心圆- src_gray.rows/8)* 5:param1: 第一个方法特定的参数。[默认值是100] canny边缘检测阈值低* 6:param2: 第二个方法特定于参数。[默认值是100] 中心点累加器阈值 – 候选圆心* 7:minRadius: 最小半径* 8:maxRadius: 最大半径* */CircleSegment[] cs = Cv2.HoughCircles(RoiClone, HoughMethods.Gradient, 1, 80, 70, 100, 100, 200);for (int i = 0; i < cs.Count(); i++){//画圆Cv2.Circle(OrgMatClone, (int)(cs[i].Center.X + minLocation.X), (int)(cs[i].Center.Y + minLocation.Y), (int)cs[i].Radius, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);//加强圆心显示Cv2.Circle(OrgMatClone, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);textBox1.Text = cs[i].Center.X.ToString();textBox2.Text = cs[i].Center.Y.ToString();}//pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;pictureBox1.Image = BitmapConverter.ToBitmap(OrgMatClone);}//private void pictureBox1_Paint(object sender, PaintEventArgs e)//{// if (blnDraw)// {// if (pictureBox1.Image != null)// {// if (Rect != null && Rect.Width > 0 && Rect.Height > 0)// {// e.Graphics.DrawRectangle(new Pen(Color.Red, 1), Rect);//重新绘制颜色为红色// }// }// }//}public class Utilities{//坐标转换//**************************************//* 图片左边转换,//* Input输入: pictureBox 坐标X,Y//* Output输出: Image 图像上对应的坐标//**************************************//public static void ConvertCoordinates(PictureBox pic,out int X0, out int Y0, int x, int y){int pic_hgt = pic.ClientSize.Height;int pic_wid = pic.ClientSize.Width;int img_hgt = pic.Image.Height;int img_wid = pic.Image.Width;X0 = x;Y0 = y;switch (pic.SizeMode){case PictureBoxSizeMode.AutoSize:case PictureBoxSizeMode.StretchImage:X0 = (int)(img_wid * x / (float)pic_wid);Y0 = (int)(img_hgt * y / (float)pic_hgt);break;}}}
OpenCvSharp手绘ROI区域+模板匹配+霍夫变换检测圆的边界相关推荐
- Python 采集87个手绘风格PPT模板
源码下载链接:ppt.rar - 蓝奏云 PPT下载链接:https://pan.baidu.com/s/1HUAEe_-4IEV6ttOKC_VPuA?pwd=96px 提取码:96px 采集的参 ...
- 使用模板匹配方法检测苹果缺陷
""" 使用模板匹配方法检测苹果缺陷 """ import cv2 import matplotlib.pyplot as plt#读取待检 ...
- Canny算子与霍夫变换检测圆与直线
目录 引言 一.canny算子 二.canny算子代码 三.霍夫变换检测直线 四.霍夫变换检测直线代码 五.霍夫变换检测直线效果 六.霍夫变换检测圆 七.霍夫变换检测圆代码 八.霍夫变换检测圆效果 引 ...
- 霍夫变换MATLAB怎么实现,做过Matlab关于霍夫变换检测圆的高手请进
Hough变换对圆的检测 Hough变换的基本原理在于,利用点与线的对偶性,将图像空间的线条变为参数空间的聚集点,从而检测给定图像是否存在给定性质的曲线. Hough对圆的检测程序如下 完整的程序及 ...
- 霍夫变换检测圆c 语言,c++ 霍夫变换检测直线
通常这是一幅边缘图像,比如来自 Canny算子.cv:: Houghlines函数的输出是 cV::Vec2f向量,每个元素都是一对代表检测到的直线的浮点数(p,0).在下例中 我们首先应用 Cann ...
- Matlab findcircle函数实现 霍夫变换——检测圆
Matlab findcircle函数实现 霍夫变换--检测圆 实现了基于霍夫变换的findcircle函数,function[circlefind]=findcircle(img,minr,maxr ...
- opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用
opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用 1)cvHonghLines2:直线 2)cvHoughCircles:该函数用Hough变换在二值图像中 ...
- [模板匹配霍夫变换]——模板匹配分析、霍夫变换分析
一.模板匹配分析 所谓模板匹配,就是在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最 ...
- halcon窗体的移动和缩放_Halcon hWindowControl 鼠标缩放平移区域模板匹配绘制
如题所示标题,想同时表达两个意思:1:缩放平移绘制区域,2:创建模板匹配区域并保存.被一个技术问题卡住折腾了近大半天时间+熬夜2个小时,经过不懈努力,反复验证各参数意义,找到了问题的原因,终于攻克难题 ...
最新文章
- 提高图形匹配精度,亮风台提出「完全可训练」的图匹配方法|CVPR 2020 Oral
- ogre研究之第一个程序(二)
- python编写抢座位软件_程序员硬核Python抢票教程”,帮你抢回家车票
- 中海达数据怎么转rinex_hds2003下载-中海达HDS2003数据处理软件下载20120530 官方版-中海达GPS数据转RINEX格式西西软件下载...
- 杭电4786--Fibonacci Tree(生成树)
- 嵌入在网页上Flash媒体播放器(1)
- 程序员必备算法——算法相关链接总结
- 字符串分割的时候用StringUtils.split()方法代替string自带的split,特殊字符不用转义
- VC6.0和VC2005项目配置详解
- 项目管理软件 OpenProj
- Python常用模块大全
- office2007无法卸载 无法安装
- Unity VR太空射击游戏教程
- 图片转svg并动态修改其颜色
- STM32F103ZET6如何驱动DS18B20温度传感器
- PHP随机生成英文大小写
- scribd.com文档下载
- geoip php 获取城市,Laravel 中利用 GeoIP 获取用户地理位置信息
- DRM应用程序进阶 (atomic-crtc)
- MySQL基础知识,如果有疏漏、错误的地方请大家指出