霍夫直線變換主要用於直線特征的檢測,其主要思想如下
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表示兩點間隔最大距離
結果如圖