(30)Air Band OpenCV2.4.13_Hough直线变换
2017-03-09 11:32
603 查看
本文是对OpenCV2.4.13文档的部分翻译,作个人学习之用,并不完整。
Hough直线变换:
用于检测直线的变换,为了应用变换首先需要一个边缘检测的预处理。
原理:
图像中的线条可以用两个变量来表示:
直角坐标系:如(m ,b);极坐标信息:(r ,θ)
我们通常使用指教坐标系来表示,因此一条直线可以表示为:
写成这样的形式
1.总的来说,对于点(x0,y0)可以定义一组通过该点的直线:
2.所以每一对(rθ ,θ)都可以表示通过(x0,y0)的直线
如果给定(x0,y0),画出通过它的一系列直线,可以得到一个正弦图像,例如x0=8,y0=6,在r-θ图像(r>0,0<θ<2π)中:
3.我们可以对一幅图像上的所有点执行上述操作,如果两个点的曲线在r-θ图像中某处相交,则这两点都属于一条直线,例如下图中增加x1=4,y1=9,x2=12,y2=3:
这三条线在一点(0.925 , 9.6)处相交,这些坐标就是参数(r,θ)或说直线(x0,y0)(x1,y1)(x2,y2)所在的位置。
4.总的来说一条线可以由一系列曲线的交点来检测,交点处的曲线越多,说明该点表示的直线上的点就越多。总的来说我们可以定义最小数目的阈值来检测一条直线。
5.这就是Hough直线变换所做的,持续跟踪图像中经过每点的直线所形成曲线的交点。交点的数量超过某阈值,就表示有这么一个交点参数为(θ,rθ)的直线存在。
标准和概率Hough直线变换:
1.标准直线变换
就是之前说明的内容,结果就是一个向量(θ,rθ),在OpenCV中用HoughLines函数来实现。
2.概率直线变换
Hough直线变换的更有效的实现,输出结果就是检测到的直线的端点(x0,y0,x1,y1),在OpenCV中用HoughLinesP来实现。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
/// Global variables
/** General variables */
Mat src, edges;//原图、边缘图
Mat src_gray;//灰度图
Mat standard_hough, probabilistic_hough;//标准Hough、概率Hough
int min_threshold = 50;
int max_trackbar = 150;
const char* standard_name = "Standard Hough Lines Demo";
const char* probabilistic_name = "Probabilistic Hough Lines Demo";
int s_trackbar = max_trackbar;
int p_trackbar = max_trackbar;
/// Function Headers
void help();
void Standard_Hough( int, void* );
void Probabilistic_Hough( int, void* );
/**
* @function main
*/
int main()
{
/// 载入图像
src = imread("building.jpg", 1 );
if( src.empty() )
{ help();
return -1;
}
/// 将图像转换为灰度图
cvtColor( src, src_gray, COLOR_RGB2GRAY );
/// 执行Canny边缘检测
Canny( src_gray, edges, 50, 200, 3 );
/// 创建滑动条选择阈值
char thresh_label[50];
sprintf( thresh_label, "Thres: %d + input", min_threshold );
namedWindow( standard_name, WINDOW_AUTOSIZE );
createTrackbar( thresh_label, standard_name, &s_trackbar, max_trackbar, Standard_Hough);
namedWindow( probabilistic_name, WINDOW_AUTOSIZE );
createTrackbar( thresh_label, probabilistic_name, &p_trackbar, max_trackbar, Probabilistic_Hough);
/// 初始化
Standard_Hough(0, 0);
Probabilistic_Hough(0, 0);
waitKey(0);
return 0;
}
/**
* @function help
* @brief Indications of how to run this program and why is it for
*/
void help()
{
printf("\t Hough Trans
a6e5
form to detect lines \n ");
printf("\t---------------------------------\n ");
printf(" Usage: ./HoughLines_Demo <image_name> \n");
}
/**
* @function Standard_Hough
*/
void Standard_Hough( int, void* )
{
vector<Vec2f> s_lines;
cvtColor( edges, standard_hough, CV_GRAY2BGR );
/// 1. 使用标准Hough变换(边缘检测输出结果(灰度图,其实是二值),直线向量,参数r的分辨率(1像素),参数θ的分辨率(1度=CV_PI/180),阈值:交叉点数量的最小值,srn和stn默认为0)
HoughLines( edges, s_lines, 1, CV_PI/180, min_threshold + s_trackbar, 0, 0 );
/// 显示结果:画出线条
for( size_t i = 0; i < s_lines.size(); i++ )
{
float r = s_lines[i][0], t = s_lines[i][1];
double cos_t = cos(t), sin_t = sin(t);
double x0 = r*cos_t, y0 = r*sin_t;
double alpha = 1000;
Point pt1( cvRound(x0 + alpha*(-sin_t)), cvRound(y0 + alpha*cos_t) );
Point pt2( cvRound(x0 - alpha*(-sin_t)), cvRound(y0 - alpha*cos_t) );
line( standard_hough, pt1, pt2, Scalar(255,0,0), 3, CV_AA);
}
imshow( standard_name, standard_hough );
}
/**
* @function Probabilistic_Hough
*/
void Probabilistic_Hough( int, void* )
{
vector<Vec4i> p_lines;
cvtColor( edges, probabilistic_hough, CV_GRAY2BGR );
/// 2. 使用概率Hough变换(边缘检测的输出结果(灰度图,实际上是二值),向量,参数r的分辨率(1像素),参数θ的分辨率(1度=CV_PI/180),阈值(检测直线的最小交点数),可以形成直线的最小点数(少于这个数字的点忽略),两点可以认为是在同一直线上的最大差距)
HoughLinesP( edges, p_lines, 1, CV_PI/180, min_threshold + p_trackbar, 30, 10 );
/// 显示结果
for( size_t i = 0; i < p_lines.size(); i++ )
{
Vec4i l = p_lines[i];
line( probabilistic_hough, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,0,0), 3, CV_AA);
}
imshow( probabilistic_name, probabilistic_hough );
}
结果:
改变阈值会改变检测到的直线数量,阈值越高线条更少
Hough直线变换:
用于检测直线的变换,为了应用变换首先需要一个边缘检测的预处理。
原理:
图像中的线条可以用两个变量来表示:
直角坐标系:如(m ,b);极坐标信息:(r ,θ)
我们通常使用指教坐标系来表示,因此一条直线可以表示为:
写成这样的形式
1.总的来说,对于点(x0,y0)可以定义一组通过该点的直线:
2.所以每一对(rθ ,θ)都可以表示通过(x0,y0)的直线
如果给定(x0,y0),画出通过它的一系列直线,可以得到一个正弦图像,例如x0=8,y0=6,在r-θ图像(r>0,0<θ<2π)中:
3.我们可以对一幅图像上的所有点执行上述操作,如果两个点的曲线在r-θ图像中某处相交,则这两点都属于一条直线,例如下图中增加x1=4,y1=9,x2=12,y2=3:
这三条线在一点(0.925 , 9.6)处相交,这些坐标就是参数(r,θ)或说直线(x0,y0)(x1,y1)(x2,y2)所在的位置。
4.总的来说一条线可以由一系列曲线的交点来检测,交点处的曲线越多,说明该点表示的直线上的点就越多。总的来说我们可以定义最小数目的阈值来检测一条直线。
5.这就是Hough直线变换所做的,持续跟踪图像中经过每点的直线所形成曲线的交点。交点的数量超过某阈值,就表示有这么一个交点参数为(θ,rθ)的直线存在。
标准和概率Hough直线变换:
1.标准直线变换
就是之前说明的内容,结果就是一个向量(θ,rθ),在OpenCV中用HoughLines函数来实现。
2.概率直线变换
Hough直线变换的更有效的实现,输出结果就是检测到的直线的端点(x0,y0,x1,y1),在OpenCV中用HoughLinesP来实现。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
/// Global variables
/** General variables */
Mat src, edges;//原图、边缘图
Mat src_gray;//灰度图
Mat standard_hough, probabilistic_hough;//标准Hough、概率Hough
int min_threshold = 50;
int max_trackbar = 150;
const char* standard_name = "Standard Hough Lines Demo";
const char* probabilistic_name = "Probabilistic Hough Lines Demo";
int s_trackbar = max_trackbar;
int p_trackbar = max_trackbar;
/// Function Headers
void help();
void Standard_Hough( int, void* );
void Probabilistic_Hough( int, void* );
/**
* @function main
*/
int main()
{
/// 载入图像
src = imread("building.jpg", 1 );
if( src.empty() )
{ help();
return -1;
}
/// 将图像转换为灰度图
cvtColor( src, src_gray, COLOR_RGB2GRAY );
/// 执行Canny边缘检测
Canny( src_gray, edges, 50, 200, 3 );
/// 创建滑动条选择阈值
char thresh_label[50];
sprintf( thresh_label, "Thres: %d + input", min_threshold );
namedWindow( standard_name, WINDOW_AUTOSIZE );
createTrackbar( thresh_label, standard_name, &s_trackbar, max_trackbar, Standard_Hough);
namedWindow( probabilistic_name, WINDOW_AUTOSIZE );
createTrackbar( thresh_label, probabilistic_name, &p_trackbar, max_trackbar, Probabilistic_Hough);
/// 初始化
Standard_Hough(0, 0);
Probabilistic_Hough(0, 0);
waitKey(0);
return 0;
}
/**
* @function help
* @brief Indications of how to run this program and why is it for
*/
void help()
{
printf("\t Hough Trans
a6e5
form to detect lines \n ");
printf("\t---------------------------------\n ");
printf(" Usage: ./HoughLines_Demo <image_name> \n");
}
/**
* @function Standard_Hough
*/
void Standard_Hough( int, void* )
{
vector<Vec2f> s_lines;
cvtColor( edges, standard_hough, CV_GRAY2BGR );
/// 1. 使用标准Hough变换(边缘检测输出结果(灰度图,其实是二值),直线向量,参数r的分辨率(1像素),参数θ的分辨率(1度=CV_PI/180),阈值:交叉点数量的最小值,srn和stn默认为0)
HoughLines( edges, s_lines, 1, CV_PI/180, min_threshold + s_trackbar, 0, 0 );
/// 显示结果:画出线条
for( size_t i = 0; i < s_lines.size(); i++ )
{
float r = s_lines[i][0], t = s_lines[i][1];
double cos_t = cos(t), sin_t = sin(t);
double x0 = r*cos_t, y0 = r*sin_t;
double alpha = 1000;
Point pt1( cvRound(x0 + alpha*(-sin_t)), cvRound(y0 + alpha*cos_t) );
Point pt2( cvRound(x0 - alpha*(-sin_t)), cvRound(y0 - alpha*cos_t) );
line( standard_hough, pt1, pt2, Scalar(255,0,0), 3, CV_AA);
}
imshow( standard_name, standard_hough );
}
/**
* @function Probabilistic_Hough
*/
void Probabilistic_Hough( int, void* )
{
vector<Vec4i> p_lines;
cvtColor( edges, probabilistic_hough, CV_GRAY2BGR );
/// 2. 使用概率Hough变换(边缘检测的输出结果(灰度图,实际上是二值),向量,参数r的分辨率(1像素),参数θ的分辨率(1度=CV_PI/180),阈值(检测直线的最小交点数),可以形成直线的最小点数(少于这个数字的点忽略),两点可以认为是在同一直线上的最大差距)
HoughLinesP( edges, p_lines, 1, CV_PI/180, min_threshold + p_trackbar, 30, 10 );
/// 显示结果
for( size_t i = 0; i < p_lines.size(); i++ )
{
Vec4i l = p_lines[i];
line( probabilistic_hough, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,0,0), 3, CV_AA);
}
imshow( probabilistic_name, probabilistic_hough );
}
结果:
改变阈值会改变检测到的直线数量,阈值越高线条更少
相关文章推荐
- (31)Air Band OpenCV2.4.13_Hough圆形变换
- (21)Air Band OpenCV2.4.13_其他形态学变换
- (33)Air Band OpenCV2.4.13_Affine变换
- (14)Air Band OpenCV2.4.13_基础作图
- OpenCV学习之Hough变换检测直线
- (17)Air Band OpenCV2.4.13_用xml和yaml文件进行输入和输出
- (25)Air Band OpenCV2.4.13_为图像添加边界
- (42)Air Band OpenCV2.4.13_为轮廓创建旋转的包围盒和椭圆
- (27)Air Band OpenCV2.4.13_Laplace算子
- (43)Air Band OpenCV2.4.13_图像矩
- (46)Air Band OpenCV2.4.13_级联分类器
- 【opencv2】直线hough变换
- (29)Air Band OpenCV2.4.13_Canny边缘检测
- python opencv -详解hough变换检测直线与圆
- (20)Air Band OpenCV2.4.13_腐蚀和膨胀
- opencv中标准Hough变换检测出的直线参数
- (26)Air Band OpenCV2.4.13_Solbel算子
- (36)Air Band OpenCV2.4.13_直方图比较
- (37)Air Band OpenCV2.4.13_反向投影
- OpenCV自学笔记5:Hough变换检测直线和圆