霍夫直线变换
霍夫直线变换主要用于直线特征的检测,其主要思想如下
1.将图形中的点从空域坐标(x,y)转化为极坐标 x=ρcosθ,y=ρsinθ,R2=(ρcosθ)2+(ρsinθ)2
2.对极坐标进行变换,转化为θ与R的关系
R2=R2cos2θ+R2sin2θ
R=Rcos2θ+Rsin2θ
R=xcosθ+ysinθ
如图所示
在这两个三角形中,直线上任意一个点通过R=xcosθ+ysinθ都可以求得直线到原点距离,且只要点在直线上,R值就是固定不变的,所以直线在极坐标中的表达式得以确定
比如平面内有三个点,怎样判断他们是不是再一条直线上呢
y=kx+b,由于点是给定的,所以我们知道x和y的值,因此将k和b看成变量,映射到kb直角坐标系中就可以如下表示
但是这种表示方法没办法表示垂直于x轴的直线(斜率k不存在)的情况,因此需要转换到极坐标中,如果三个点三个方程能解出固定的ρ和θ,则过三点存在一条直线
变换完极坐标就是求解方程组的问题了
示例代码
#include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int main(int argc, char** argv) { Mat src, src_gray, dst; src = imread("1.jpg"); if (!src.data) { printf("load img error\n"); return -1; } char INPUT_TITLE[] = "Input img"; char OUTPUT_TITLE[] = "hough-line-detection"; namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE); namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE); imshow(INPUT_TITLE, src); Canny(src, src_gray, 100, 200); cvtColor(src_gray, dst, CV_GRAY2BGR); imshow("edge_image", src_gray); vector<Vec4f> plines; HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 0, 20); Scalar color = Scalar(0, 0, 255); for (size_t i = 0; i < plines.size(); ++i) { Vec4f hline = plines[i]; line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA); } imshow(OUTPUT_TITLE, dst); waitKey(0); return 0; }
先进行灰度转化,然后将检测结果颜色设为红色,以向量形式存放
HoughLinesP就是opencv中的霍夫直线变换api前两个是输入输出,1表示极坐标生成时扫描像素的步长,∏/180是横坐标取点的频率,第一个10表示最少重合点个数,第二个10表示两点间隔最大距离
结果如图
无情的摸鱼机器