opencv學習筆記(六)霍夫直線檢測和圓檢測

2021-10-24 15:32:13 字數 3356 閱讀 5495

1.霍夫變換直線檢測和圓檢測

霍夫變換是一種從空間域到極座標域的轉換。已知二維空間的一條直線有很多表現方式,例如截距式斜率式比如:y=kx+b,一旦我們知道k和b,就知道了這條直線,而k和b在座標上表示的只是乙個點而已,如果直線的k相同也就是直線平行,那麼表現在kb座標域也就是條k直線。那麼問題在於,如何在kb座標系表示乙個點呢?顯然不是很好表示,因為過乙個點直線的kb不同的話,kb值表示了一整個座標系。如果點表示出來是一條直線或者曲線是不是就很好了呢?

霍夫變換和這種想法類似,歸根到底是尋找直線的不同表現方法,霍夫變換使用原點到直線的距離p和對乙個角度θ表示方程為:

ρ =x

cosθ

+ysi

nθ\rho =xcos\theta+ysin\theta

ρ=xcos

θ+ys

inθ而過乙個點的直線,在相應極座標域中表示為一條正弦曲線,正弦曲線相交兩點就共線,這樣就達到了一開始的目的,找到了一條直線。

變換到極座標中,從[0~360]空間,可以得到r的大小

屬於同一條直線上點在極座標空(r, theta)必然在乙個點上有最強的訊號出現,根據此反算到平面座標中就可以得到直線上各點的畫素座標。從而得到直線

同樣根據類似原理可以進行任意形狀的檢測,歸根到底就是找出形狀的點的相同之處,例如使用乙個關於角度的函式和乙個關於距離的函式表達任意形狀,根據已知形狀構建直角空間到這兩個函式之間的對映關係,在將一幅圖中的所有點都去進行該變換,查表如果點都集中在乙個地方說明滿足形狀這一特徵。可以總結為變換(找特徵)+閾值(分類)問題。

圓檢測的原始碼原理

api:

直線檢測:

cv::houghlinesp(

inputarray src, // 輸入影象,必須8-bit的灰度影象

outputarray lines, // 輸出的極座標來表示直線

double rho, // 生成極座標時候的畫素掃瞄步長 一般取1

double theta, //生成極座標時候的角度步長,一般取值cv_pi/180

int threshold, // 閾值,只有獲得足夠交點的極座標點才被看成是直線

double minlinelength=0;// 最小直線長度

double maxlinegap=0;// 最大間隔

返回vec2 rho 和theta

cv::houghlines(

inputarray src, // 輸入影象,必須8-bit的灰度影象

outputarray lines, // 輸出的極座標來表示直線

double rho, // 生成極座標時候的畫素掃瞄步長

double theta, //生成極座標時候的角度步長,一般取值cv_pi/180

int threshold, // 閾值,只有獲得足夠交點的極座標點才被看成是直線

double srn=0;// 是否應用多尺度的霍夫變換,如果不是設定0表示經典霍夫變換

double stn=0;//是否應用多尺度的霍夫變換,如果不是設定0表示經典霍夫變換

double min_theta=0; // 表示角度掃瞄範圍 0 ~180之間, 預設即可

double max_theta=cv_pi

返回vec4 兩點座標

圓檢測:

houghcircles(

inputarray image, // 輸入影象 ,必須是8位的單通道灰度影象

outputarray circles, // 輸出結果,發現的圓資訊

int method, // 方法 - hough_gradient

double dp, // dp = 1;

double mindist, // 10 最短距離-可以分辨是兩個圓的,否則認為是同心圓- src_gray.rows*/8*

double param1, // canny edge detection low threshold

double param2, // 中心點累加器閾值 – 候選圓心

int minradius, // 最小半徑

int maxradius//最大半徑

返回vec3 圓心和半徑

**案例:

#include"pch.h"

#include#includeusing namespace std;

using namespace cv;

mat src, gray_src, dst_line, dst_circle;

int main(int argc, char** ar**)

canny(src, gray_src, 150, 200);

cvtcolor(gray_src, dst_line, cv_gray2bgr);

dst_line.copyto(dst_circle);

namedwindow("input", cv_window_autosize);

imshow("input", gray_src);

vectorlines;//選擇容器型別

//api缺陷在於返回的是ρ和θ,代表一條直線,並不是返回這些點。因此畫出來的直線之能是全屏直線,無法是某段線段。

houghlines(gray_src, lines, 1, cv_pi / 180, 70, 0, 0);//返回型別是含有θ和ρ的向量lines

for (size_t i = 1; i < lines.size(); i++)

vectorplines;

houghlinesp(gray_src, plines, 1, cv_pi / 180, 30, 0, 0);//返回空間域座標,也就是點的座標因此出來的結果是線段

for (size_t i = 1; i < plines.size(); i++)

namedwindow("output", cv_window_autosize);

imshow("output", dst_line);

vectorcir;

houghcircles(gray_src, cir, hough_gradient, 1,10,40,40,100);

for (size_t i = 1; i < cir.size(); i++)

namedwindow("output2", cv_window_autosize);

imshow("output2", dst_circle);

waitkey(0);

return 0;

}

結果:

Opencv 霍夫變換 直線

注意 下面的解釋屬於bradski和kaehler 的 學習opencv 一書。hough line變換是用於檢測直線的變換。為了應用變換,首先需要邊緣檢測預處理。如你所知,影象空間中的一行可以用兩個變數表示。例如 在笛卡爾座標系中 引數 m,b 在極座標系中 引數 r,對於hough 變換,我們將...

OpenCV學習筆記(八)之霍夫直線變換

老規矩 妹妹鎮樓 前提條件 邊緣檢測已經完成 平面空間到極座標空間轉換 在影象平面空間上的多個點對映到 r 座標空間中,形成多條曲線。多條曲線有共同的交點,即表明這幾個點在影象平面空間中是共線的。標準的霍夫變換cv houghlines從平面座標轉換到霍夫空間,最終輸出是 r 表示極座標空間。霍夫變...

opencv 霍夫變換 直線檢測

用來做直線檢測 前提條件是邊緣檢測已經完成,一般用canny來做。cv houghlinesp inputarray src,輸入影象,必須8 bit的灰度影象 outputarray lines,輸出的極座標來表示直線 double rho,生成極座標時候的畫素掃瞄步長,一般是1 double t...