学习【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑---笔记
来源:互联网 发布:网页数据采集器 编辑:程序博客网 时间:2024/05/20 18:45
本文参考@浅墨_毛星云 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26977557
今天学习了教程【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑,表示对霍夫线变换如何由概念转化为代码,理解了很久,坐标图都画了好几页,因为是小白,理论知识不清楚,所以遇到一些问题,可能对有些人很基础,但对于我来说,还是难理解,不过终于明白,代码是怎么来的了,一定要好好记录一下,以免日后忘记~
还是老步骤,整理笔记
OpenCV中霍夫变换相关的知识点,以及了解了OpenCV中实现霍夫线变换的HoughLines、HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircles函数的使用方法。
一、引言
二、霍夫变换概述
三、霍夫线性变换
1、HoughLines( )函数示例代码
#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\opencv.hpp>#include<iostream>using namespace cv;using namespace std;int main(){//载入原始图和Mat变量定义Mat src=imread("img/line1.png",1);Mat dst,mid;//进行边缘检测和转化为灰度图Canny(src,mid,50,200,3);//进行一此canny边缘检测cvtColor(mid,dst,CV_GRAY2BGR);//转化边缘检测后的灰度图转化为三通道图//进行霍夫线变换 vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合HoughLines(mid,lines,1,CV_PI/180,150,0,0);//依次在图中绘制出每条线段for (size_t i = 0; i < lines.size(); i++){float rho=lines[i][0],theta=lines[i][1];Point pt1,pt2;double a=cos(theta),b=sin(theta);double x0=a*rho,y0=b*rho;//为什么这样?有配套的图片解释见下面效果图之后的补充部分,1000表示点(x0,y0),在直线,向上,向下1000的距离pt1.x=cvRound(x0+1000*(-b));pt1.y=cvRound(y0+1000*(a));pt2.x=cvRound(x0-1000*(-b));pt2.y=cvRound(y0-1000*(a));line(dst,pt1,pt2,Scalar(100,200,100),1,CV_AA);}//显示原始图imshow("1",src);//边缘检测后的图imshow("2",mid);//显示效果图imshow("3",dst);waitKey(0);return 0;}
原图:
canny检测的边缘图:
对应的HoughLines变换的效果图:
pt1与pt2点的计算方法 。 这里已知下图中的rh0 和θ,现在只需要求图中“任意”两点, 就能用cvLine画出pt1 -> pt2的直线 。 看看下页图, 就明白这里1000什么的是为什么了。
这里是取了点(x0,y0)在直线上上下1000的距离,那么用cvLine画出来的线段就是从pt1 -> pt2的了。那么pt1->pt2的直线距离就是2000。可以取其他的距离,不一定去1000,如600也可以。1.这个地方也许会出现检测出来的线段长度比pt1->pt2还大,即包含了我们画的线段 , 这是肯定的。2. 还会出现本来线段没有pt1->pt2这么长,那么我们画的就会过长了。 也是肯定会出现的情况。因为:CV_HOUGH_STANDARD方法 只能得出rh0 和 θ的值。 这两个值只能确定直线,而不能确定线段是从哪开始到哪结束。
通过上面的关系,可以推导出下面的式子成立:
pt1.x=cvRound(x0+1000*(-b));
pt1.y=cvRound(y0+1000*(a));
pt2.x=cvRound(x0-1000*(-b));
pt2.y=cvRound(y0-1000*(a));
2、HoughLinesP( )函数示例代码
#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\opencv.hpp>#include<opencv2\opencv.hpp>#include<iostream>using namespace cv;using namespace std;int main(){Mat src,dst,mid;src=imread("img/line2.png",1);//进行边缘检测和转化为灰度图Canny(src,mid,80,200,3);///进行一次canny边缘检测cvtColor(mid,dst,CV_GRAY2BGR);//将边缘检测后的灰度图转化为BRG三通道图//进行霍夫线变换vector<Vec4i> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合(vec4i)整型HoughLinesP(mid,lines,1,CV_PI/180,40,20,3);//依次在图中绘制出每条线段for (int i = 0; i<lines.size(); i++){Vec4i ll=lines[i];line(dst,Point(ll[0],ll[1]),Point(ll[2],ll[3]),Scalar(100,200,100),1,CV_AA);}imshow("1",src);imshow("2",mid);imshow("3",dst);waitKey(0);return 0;}
原图:
canny检测边缘图:
HoughLinesP变换效果图:
四、霍夫圆变换
HoughCircles( )函数示例代码
#include<opencv2\opencv.hpp>#include<iostream>using namespace cv;using namespace std;int main(){Mat src,dst,mid;src=imread("img/circle.png");imshow("1",src);//转为灰度图,进行GaussianBlur图像平滑cvtColor(src,mid,CV_BGR2GRAY);GaussianBlur(mid,mid,Size(9,9),0,0);//进行霍夫圆变换,每个向量中包含3个值,x,y,r所以<Vec3f>vector<Vec3f> circles;//第4,5个参数需要反复测试,不然检测出来的圆个数会很多HoughCircles(mid,circles,CV_HOUGH_GRADIENT,1.5,60,200,100,0,0);//依次在图中绘制出圆for (int i = 0; i < circles.size(); i++){//遍历每个圆轨的圆心centerPoint center(cvRound(circles[i][0]),cvRound(circles[i][1]));//遍历每个圆轨迹的半径rint r=cvRound(circles[i][2]); //绘制圆心 当第5个参数为负数时,表示填充,当为正数时,表示画圆的粗细circle(src,center,3,Scalar(0,0,100),-1,8,0);//绘制圆轮廓 circle(src,center,r,Scalar(10,100,30),2,8,0);}imshow("2",src);waitKey(0);return 0;}原图:
HoughCircles变换效果图:
五、综合案例
的HoughLinesP函数的基础上,为其添加了用于控制其第五个参数阈值threshold的滚动条。能通过调节滚动条,改变阈值,动态地控制霍夫线变换检测的线条多少。
代码如下:
#include<opencv2\opencv.hpp>#include<iostream>using namespace cv;using namespace std;//原始图、中间图和效果图Mat src,dst,mid;//定义一个矢量结构lines用于存放得到的线段矢量集合vector<Vec4i> lines;//变量接收的TrackBar位置参数int HoughLinesP_value=100;//回调函数void HoughLinesP_on(int,void*){//定义局部变量储存全局变量 Mat mid_p=mid.clone();Mat dst_p=dst.clone();vector<Vec4i> mylines; //调用HoughLinesP函数 HoughLinesP(mid_p,mylines,1,CV_PI/180,HoughLinesP_value+1,50,10); //循环遍历绘制每一条线段 for (int i = 0; i < mylines.size(); i++){Vec4i ll=mylines[i];Point p1(ll[0],ll[1]),p2(ll[2],ll[3]);line(dst_p,p1,p2,Scalar(100,200,100),1,8);} //显示图像 imshow("效果图",dst_p);}int main(){src=imread("img/line1.png",1);imshow("原图",src);//进行边缘检测和转化为灰度图 Canny(src,mid,50,200,3);cvtColor(mid,dst,CV_GRAY2BGR); //创建滚动条 namedWindow("效果图",1);createTrackbar("阈值","效果图",&HoughLinesP_value,200,HoughLinesP_on);//调用一次回调函数,调用一次HoughLinesP函数 HoughLinesP_on(HoughLinesP_value,0);HoughLinesP(mid,lines,1,CV_PI/180,80,50,10);imshow("效果图",dst);waitKey(0);return 0;}
原图:
不同阈值对应的HoughLinesP霍夫变换效果图:
- 学习【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑---笔记
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- [转]【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- OpenCV之十四 OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
- 【OpenCV学习笔记】十四、图像几何变换
- new、abstract、virtual、override,sealed关键字区别和使用代码示例
- linux C之access函数
- map--已知key取对应value
- 图像分割“Not All Pixels Are Equal: Difficulty-Aware Semantic Segmentation via Deep Layer Cascade”
- Java中堆和栈的分析
- 学习【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑---笔记
- 谷歌微软等科技巨头数据科学面试107道真题:你能答出多少?
- dokuwiki 居然不知道php5.6
- UVa 10934 (主要是思路)
- [网络]Unity中Http访问和下载
- LeetCode 142. Linked List Cycle II
- 04、vue.js 之绑定事件
- phlacon工具安装到phpstorm
- LinQ基本使用:查询数组