有些情况, 我们会需要提取直线的详细参数, 下面介绍如何提取直线
霍夫变换(Hough Transformation)
其中很大一部分都在应用霍夫变换 及其 各种版本来提取直线
关于霍夫变换的理解, 这里有个检测圆的供参考 http://blog.youkuaiyun.com/traumland/article/details/51077293
这里个人总结下: 霍夫变换的基本思想, 将原本的平面曲线参数方程转化成 , 以曲线上点作为已知,
把曲线方程的参数当作未知项, 在参数空间作出图形.(原本已知所有参数时可以求出曲线上的这些点)
当交于某公共点上图形最多时(peak), 这个公共点(peak)对应的参数便可作为整个图形的参数.
霍夫变换最开始提出来时, 直线方程用的是斜截式
因为考虑到直线两种极端情况, 水平和竖直
所以按斜率是否大于1, 使用了不同的方程
k < 1 时 y = kx +b
k>=1 时 y = 1/k x + 1/b
就避免了因为 y = mx + c 中 m,c 过大而不好讨论(m,c代表直线方程的参数)
在Duda,Hart 71 中, 提出了用
ρ = x cos θ + y sin θ
来表示直线, 也就是现在常见的表示形式
提供了减少计算量的方法
最好看看hough变换的源码, 因为opencv只提供了直线和圆的函数, 其他的需要自己去写
opencv标准霍夫变换源码及注释:http://blog.youkuaiyun.com/traumland/article/details/51319644
下面示例下opencv霍夫变换函数的使用
注: sobel算子使用的方法不太正确, 这里仅作示例用. 两图求得的edge不一样
详细请看http://blog.youkuaiyun.com/traumland/article/details/51074705
cv::Mat G,Gx,Gy,G_otsu;
cv::Sobel(srcEmpty,Gx,CV_8U,1,0,3);
cv::Sobel(srcEmpty,Gy,CV_8U,0,1,3);
G = Gx + Gy;
cv::threshold(G,G_otsu,0,255,cv::THRESH_OTSU);
if(debugflag)
cv::imshow("Edge",G_otsu);
cv::Mat dst(srcEmpty.size(),CV_8UC3);
std::vector<cv::Vec2f> lines;
cv::HoughLines(G_otsu, lines,1, CV_PI/180, 30,0,0);
for( size_t i = 0; i < lines.size(); i++ ){
float rho = lines[i][0];
float theta = lines[i][1];
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
cv