OpenCV圖像處理|1.20 霍夫線變換
來自專欄 OpenCV圖像處理教程4 人贊了文章
概率霍夫線檢測HoughLinesP()、先提取邊緣再做直線檢測、畫線
1.20.1 霍夫直線變換原理霍夫變換直線檢測:是一種用來尋找直線的方法(還有霍夫圓檢測)。把圖像上的全部像素點變換到極坐標空間,每一點形成一條曲線,若某些曲線能相交於一點上,則這些像素點就在一條直線上。原理:屬於同一條直線上點在極坐標空(r, theta)必然在一個點上有最強的信號出現,根據此反算到平面坐標中就可以得到直線上各點的像素坐標,從而得到直線。前提條件:先完成對圖像的邊緣檢測(輸出是8位單通道),也即霍夫線變換的直接輸入只能是邊緣二值圖像。平面空間(空域)到極坐標空間(霍夫空間)轉換:一條直線在圖像二維空間可由兩個變數表示。例如:
在笛卡爾坐標系(直角坐標系和斜角坐標系的統稱): 可由參數(m,b)斜率和截距表示. 在極坐標系: 可由參數 (r,o)極徑(r或p)和極角表示:1)對於霍夫變換, 我們將用極坐標系來表示直線. 因此, 直線的表達式可為:化簡得:就可求出直線。
1.20.2 相關API實現OpenCV實現了以下兩種霍夫線變換:(1)標準霍夫線變換 - HoughLines原理在上面的部分已經說明了,它能給我們提供一組參數對 的集合來表示檢測到的直線,從平面坐標轉換到霍夫空間,最終輸出是 ,表示極坐標空間。
這個函數一般情況是有經驗的開發者使用,需要自己反變換到平面空間。HoughLines(InputArray src, // 輸入圖像,必須8-bit的灰度圖像OutputArray lines, // 輸出的極坐標來表示直線double rho, // 生成極坐標時候的像素掃描步長,一般取1,極坐標空間 r 的最大值double theta, //生成極坐標時候的角度步長,一般取值0~180度的角度每次掃描1度就是CV_PI/180int threshold, // 閾值,只有獲得足夠交點的極坐標點才被看成是直線double srn=0;// 是否應用多尺度(圖像金字塔)的霍夫變換,如果不是設置0表示經典霍夫變換,默認double stn=0;//是否應用多尺度的霍夫變換,如果不是設置0表示經典霍夫變換,默認double min_theta=0; // 表示角度掃描範圍 0 ~180之間, 默認即可
double max_theta=CV_PI // 表示角度掃描範圍 0 ~180之間, 默認)(2)概率霍夫線變換 - HoughLinesP這是執行起來效率更高的概率霍夫線變換(probabilistic Hough ),它輸出檢測到的直線的端點 。HoughLinesP( InputArray src, // 輸入圖像,必須8-bit的灰度圖像 OutputArray lines, // 輸出的極坐標來表示直線 double rho, // 生成極坐標時候的像素掃描步長,一般取1double theta, //生成極坐標時候的角度步長,一般取值CV_PI/180
int threshold, // 閾值,只有獲得足夠交點的極坐標點才被看成是直線,可以寫10 double minLineLength=0;// 最小直線長度 double maxLineGap=0;// 兩交點間允許的最大間隔,(經canny的梯度可能不連續,間隔調大) )/*直線檢測*/vector<Vec4f> plines; //定義一個浮點數,二維數組HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 30, 10);//概率霍夫線變換直線檢測,灰度輸入,像素步長,角度步長,交點閾值,最短長度,最大間隔(經canny的梯度可能不連續,間隔調大)應用步驟:
1)Canny提取邊緣 - Canny() Canny(src, src_gray, 150, 200); //提取邊緣 ,輸入圖像可以是RGB每個通道佔8位就行,輸出8位灰度圖像2)霍夫直線檢測 - HoughLinesP() vector<Vec4f> plines; //定義一個浮點數,二維數組 HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 30, 10);//概率霍夫線變換直線檢測,灰度輸入,像素步長,角度步長,交點閾值,最短長度,最大間隔(經canny的梯度可能不連續,間隔調大)3)畫直線 - line() line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 2, LINE_AA); //畫直線,LINE_AA反鋸齒完整程序:/*1.20 霍夫線變換 繪出檢測到的直線圖像*/#include <opencv2/opencv.hpp>#include <iostream> #include <math.h>using namespace cv;using namespace std;Mat src, dst, src_gray;int main(int argc, char** argv) { src = imread("E:/OpenCV/testimage/test7.jpg"); if (src.empty()) { printf("could not load image...
"); return -1; } char input_title[] = "input image"; namedWindow(input_title, CV_WINDOW_AUTOSIZE); imshow(input_title, src); /*Canny提取邊緣 extract edge*/ Canny(src, src_gray, 150, 200); //提取邊緣 ,輸入圖像可以是RGB每個通道佔8位就行,輸出8位灰度圖像 imshow("canny image", src_gray); /*霍夫直線檢測*/ vector<Vec4f> plines; //定義一個浮點數,二維數組 HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 30, 10);//概率霍夫線變換直線檢測,灰度輸入,像素步長,角度步長,交點閾值,最短長度,最大間隔(經canny的梯度可能不連續,間隔調大) /*將檢測的直線畫出來*/ Scalar color = Scalar(255, 0, 0); // 設置線顏色 cvtColor(src_gray, dst, CV_GRAY2BGR); //灰度轉彩色RGB 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, 2, LINE_AA); //畫直線,LINE_AA反鋸齒 } imshow("HoughLinesP image", dst); waitKey(0); return 0;}
推薦閱讀:
※圖像風格化演算法綜述三部曲之 (三) (Neural Style Transfer: A Review)
※第三篇:Scan to map 簡述
※文本檢測之CTPN
※DensePose開源了,人體姿態大規模識別也很高效 | Facebook·CVPR 2018
※[計算機視覺論文速遞] 2018-06-15 人臉專場