書名:OpenCV計算機視覺編程攻略(第3版)
作者:[加]羅伯特·拉戈尼爾
譯者:相銀初
出版社:人民郵電出版社
出版時間:2018-05
ISBN:9787115480934
一、HoughLinesP函數
- 爲解決上述問題(即測出的結果重複)並檢測到線段(即包含端點的直線),人們提出了霍夫變換的改進版。這就是概率霍夫變換,在OpenCV中通過cv::HoughLinesP函數實現。我們用它創建LineFinder類,封裝函數的參數:
class LineFinder {
private:
// 原始圖像
cv::Mat img;
// 包含被檢測直線的端點的向量
std::vector<cv::Vec4i> lines;
// 累加器分辨率參數
double deltaRho;
double deltaTheta;
// 確認直線之前必須收到的最小投票數
int minVote;
// 直線的最小長度
double minLength;
// 直線上允許的最大空隙
double maxGap;
public:
// 默認累加器分辨率是1像素,1度
// 沒有空隙,沒有最小長度
LineFinder() : deltaRho(1), deltaTheta(PI/180),
minVote(10), minLength(0.), maxGap(0.) {}
- 對應的設置方法:
// 設置累加器的分辨率
void setAccResolution(double dRho, double dTheta) {
deltaRho= dRho;
deltaTheta= dTheta;
}
// 設置最小投票數
void setMinVote(int minv) {
minVote= minv;
}
// 設置直線長度和空隙
void setLineLengthAndGap(double length, double gap) {
minLength= length;
maxGap= gap;
}
二、檢測霍夫線段的代碼
// 應用概率霍夫變換
std::vector<cv::Vec4i> findLines(cv::Mat& binary) {
lines.clear();
cv::HoughLinesP(binary, lines,
deltaRho, deltaTheta, minVote,
minLength, maxGap);
return lines;
}
- 這個方法返回cv::Vec4i類型的向量,包含每條被檢測線段的開始端點和結束端點的座標。我們可以用下面的方法在圖像上繪製檢測到的線段:
// 在圖像上繪製檢測到的直線
void drawDetectedLines(cv::Mat &image,
cv::Scalar color=cv::Scalar(255,255,255)) {
// 畫直線
std::vector<cv::Vec4i>::const_iterator it2= lines.begin();
while (it2! =lines.end()) {
cv::Point pt1((*it2)[0], (*it2)[1]);
cv::Point pt2((*it2)[2], (*it2)[3]);
cv::line( image, pt1, pt2, color);
++it2;
}
}
- 輸入圖像不變,可以用下面的次序檢測直線:
// 創建LineFinder類的實例
LineFinder finder;
// 設置概率霍夫變換的參數
finder.setLineLengthAndGap(100,20);
finder.setMinVote(60);
// 檢測直線並畫線
std::vector<cv::Vec4i> lines= finder.findLines(contours);
finder.drawDetectedLines(image);
-
得到如下結果。