HoughLinesP函数(概率检测直线)
2015-08-26 17:20
267 查看
统计概率霍夫线变换
这是执行起来效率更高的霍夫线变换. 它输出检测到的直线的端点
在OpenCV 中它通过函数 HoughLinesP 来实现
这个程序是用来做什么的?
加载一幅图片
对图片进行 标准霍夫线变换 或是 统计概率霍夫线变换.
分别在两个窗口显示原图像和绘出检测到直线的图像.
我们将要说明的例程能从 这里 下载。
一个更高级的版本 (能同时演示标准霍夫线变换和统计概率霍夫线变换并带有活动条来改变变换的阈值) 能从 这里 下载。
加载图片
用Canny算子对图像进行边缘检测
现在我们将要执行霍夫线变换. 我们将会说明怎样使用OpenCV的函数做到这一点:
标准霍夫线变换
首先, 你要执行变换:
带有以下自变量:
dst: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图)
lines: 储存着检测到的直线的参数对
的容器
* rho : 参数极径
以像素值为单位的分辨率. 我们使用 1 像素.
theta: 参数极角
以弧度为单位的分辨率.
我们使用 1度 (即CV_PI/180)
threshold: 要”检测” 一条直线所需最少的的曲线交点
srn and stn: 参数默认为0. 查缺OpenCV参考文献来获取更多信息.
通过画出检测到的直线来显示结果.
统计概率霍夫线变换
首先, 你要执行变换:
带有以下自变量:
dst: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图) * lines: 储存着检测到的直线的参数对
的容器
rho : 参数极径
以像素值为单位的分辨率.
我们使用 1 像素.
theta: 参数极角
以弧度为单位的分辨率.
我们使用 1度 (即CV_PI/180)
threshold: 要”检测” 一条直线所需最少的的曲线交点 * minLinLength: 能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.
maxLineGap: 能被认为在一条直线上的亮点的最大距离.
通过画出检测到的直线来显示结果.
显示原始图像和检测到的直线:
等待用户按键推出程序
Note
得到的结果使用的是在上面 代码 部分提到的更高级版代码. 霍夫线变换的代码没有改变, 唯一不同的是在GUI的部分加入了活动条可动态改变阈值.输入图像为:
通过执行统计概率霍夫线变换我们能得到下面的结果:
当你使用滑动条来改变 阈值 的时候会观察到检测到线的数目的改变. 这是因为: 如果你设置了一个更大的阈值, 能检测到的线的数目将更少 (你需要更多的点来表示一条能检测到的直线).
这是执行起来效率更高的霍夫线变换. 它输出检测到的直线的端点
在OpenCV 中它通过函数 HoughLinesP 来实现
代码
这个程序是用来做什么的?加载一幅图片
对图片进行 标准霍夫线变换 或是 统计概率霍夫线变换.
分别在两个窗口显示原图像和绘出检测到直线的图像.
我们将要说明的例程能从 这里 下载。
一个更高级的版本 (能同时演示标准霍夫线变换和统计概率霍夫线变换并带有活动条来改变变换的阈值) 能从 这里 下载。
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; void help() { cout << "\nThis program demonstrates line finding with the Hough transform.\n" "Usage:\n" "./houghlines <image_name>, Default is pic1.jpg\n" << endl; } int main(int argc, char** argv) { const char* filename = argc >= 2 ? argv[1] : "pic1.jpg"; Mat src = imread(filename, 0); if(src.empty()) { help(); cout << "can not open " << filename << endl; return -1; } Mat dst, cdst; Canny(src, dst, 50, 200, 3); cvtColor(dst, cdst, CV_GRAY2BGR); #if 0 vector<Vec2f> lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 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; 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( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); } #else vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 ); for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); } #endif imshow("source", src); imshow("detected lines", cdst); waitKey(); return 0; }
代码说明
加载图片Mat src = imread(filename, 0); if(src.empty()) { help(); cout << "can not open " << filename << endl; return -1; }
用Canny算子对图像进行边缘检测
Canny(src, dst, 50, 200, 3);
现在我们将要执行霍夫线变换. 我们将会说明怎样使用OpenCV的函数做到这一点:
标准霍夫线变换
首先, 你要执行变换:
vector<Vec2f> lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
带有以下自变量:
dst: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图)
lines: 储存着检测到的直线的参数对
的容器
* rho : 参数极径
以像素值为单位的分辨率. 我们使用 1 像素.
theta: 参数极角
以弧度为单位的分辨率.
我们使用 1度 (即CV_PI/180)
threshold: 要”检测” 一条直线所需最少的的曲线交点
srn and stn: 参数默认为0. 查缺OpenCV参考文献来获取更多信息.
通过画出检测到的直线来显示结果.
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; 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( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); }
统计概率霍夫线变换
首先, 你要执行变换:
vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
带有以下自变量:
dst: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图) * lines: 储存着检测到的直线的参数对
的容器
rho : 参数极径
以像素值为单位的分辨率.
我们使用 1 像素.
theta: 参数极角
以弧度为单位的分辨率.
我们使用 1度 (即CV_PI/180)
threshold: 要”检测” 一条直线所需最少的的曲线交点 * minLinLength: 能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.
maxLineGap: 能被认为在一条直线上的亮点的最大距离.
通过画出检测到的直线来显示结果.
for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); }
显示原始图像和检测到的直线:
imshow("source", src); imshow("detected lines", cdst);
等待用户按键推出程序
waitKey();
结果
Note得到的结果使用的是在上面 代码 部分提到的更高级版代码. 霍夫线变换的代码没有改变, 唯一不同的是在GUI的部分加入了活动条可动态改变阈值.输入图像为:
通过执行统计概率霍夫线变换我们能得到下面的结果:
当你使用滑动条来改变 阈值 的时候会观察到检测到线的数目的改变. 这是因为: 如果你设置了一个更大的阈值, 能检测到的线的数目将更少 (你需要更多的点来表示一条能检测到的直线).
相关文章推荐
- 监督算法大比拼之BP、SVM、adaboost非线性多分类实验
- android执行移动动画后按钮点击错位问题解决
- 数据结构:胜者树与败者树
- Python sys.path.append
- 【使用JSOUP实现网络爬虫】使用DOM方法来遍历一个文档
- I NEED A OFFER! 1203 (01背包变形+数学)
- leetcode 153 : Find Minimum in Rotated Sorted Array
- 返回一张可以随意拉伸不变形的图片
- MongoDB基本使用
- ThreadLocalTest
- python generator 的惰性计算
- Android资源访问机制—获取Resources对象
- 同步方法
- Badboy自动化测试工具 导出脚本用于JMeter性能测试
- 1.6 网络编程之 UDP通信
- 1.5 MFC封装思想
- ASP.NET数据绑定方法集合
- hdu 2489 漫步校园
- [MySQL] 主流存储引擎介绍
- C++与Java虚函数的区别