霍夫變換---OpenCV-Python開發(fā)指南(35)

什么是霍夫變換

霍夫變換是一種在圖像中尋找直線瘦赫,圓形以及其他簡單形狀的方法。霍夫變換采用類似于投票的方式來獲取當(dāng)前圖像內(nèi)的形狀集合刃永,該變換由Paul Hough(霍夫)于1962年首次提出。

最初的霍夫變換只能用于檢測直線羊精,經(jīng)過發(fā)展后斯够,霍夫變換不僅能夠識別直線,還能識別其他簡單的圖形結(jié)構(gòu)喧锦,常見的有圓形读规,橢圓等。

HoughLines函數(shù)

在OpenCV中燃少,它給我們提供了cv2.HoughLines()函數(shù)來實現(xiàn)霍夫直線變換束亏,該函數(shù)要求所有操作的原圖是一個二值圖像,所以在進行霍夫變換之前供汛,需要將圖像進行二值化處理枪汪。或者進行Canny邊緣檢測怔昨。

其完整定義如下:

def HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None):

image:原始圖形雀久,必須是8位單通道的二值圖像

rho:以像素為單位的距離r的精度。一般情況下趁舀,使用的精度是1

theta:為角度θ的精度赖捌。一般情況下,使用的精度是Π/180矮烹,表示要搜索所有可能的角度

threshold:閾值越庇。該值越小,判定出直線就越多奉狈。識別直線時卤唉,要判定多少個點位于該直線上。在判定直線是否存在時仁期,對直線所穿過的點的數(shù)量進行評估桑驱,如果直線所穿過的點的數(shù)量小于閾值,則認(rèn)為這些點恰好在算法構(gòu)成直線跛蛋,但是在原始圖像中該直線并不存在熬的;如果大于閾值,則認(rèn)為直線存在赊级。所以押框,如果閾值越小,就會得到較多的直線理逊;閾值越大橡伞,就會得到較少的直線

lines:返回值盒揉,它的每個元素都是一對浮點數(shù),表示檢測到的直線的參數(shù)兑徘,即(r,θ)预烙。是numpy.ndarray類型。

HoughLines實戰(zhàn)

了解了函數(shù)常用的參數(shù)之后道媚。下面扁掸,我們通過一個棋盤來進行霍夫變換。代碼如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("35.jpg")
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis('off')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

lines = cv2.HoughLines(edges, 1, np.pi / 180, 140)
for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 1000 * (-b))
    y1 = int(y0 + 1000 * (a))
    x2 = int(x0 - 1000 * (-b))
    y2 = int(y0 - 1000 * (a))
    cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
plt.subplot(122)
plt.imshow(img, cmap="gray")
plt.axis('off')
plt.show()

運行之后最域,效果如下:


1.png

HoughLinesP實戰(zhàn)

使用HoughLines雖然可以完成霍夫變換谴分,但其本身存在非常嚴(yán)重的誤檢測。為了解決這個問題镀脂,OpenCV加入了概率霍夫變換函數(shù)cv2.HoughLinesP()函數(shù)牺蹄。

其完整定義如下:

def HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None): 

image:原始圖像,比如為8位單通道二值圖像

rho:同上

theta:同上

threshold:同上

lines:同上

minLineLength:用來控制”接受直線的最小長度“的值薄翅。默認(rèn)值為0

maxLineGap:用來控制接受共線線段之間的最小間隔沙兰,即在一條直線中兩點的最大間隔。如果兩點間的間隔超過了參數(shù)maxLineGap的值翘魄,就認(rèn)為這兩點不在一條直線上鼎天。默認(rèn)值為0

將上面的例子,使用HoughLinesP改進以下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("35.jpg")
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis('off')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 10, 10)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 5)
plt.subplot(122)
plt.imshow(img, cmap="gray")
plt.axis('off')
plt.show()

運行之后暑竟,效果如下:

2.png

可以看到斋射,這里我們通過函數(shù)HoughLinesP,將棋盤線完整的全標(biāo)記出來了但荤。

HoughCircles實戰(zhàn)

霍夫變換出來用來檢測直線外罗岖,我們還可以用來檢測其他的幾何對象。實際上腹躁,只要是能用一個方程式表示的對象桑包,都適合用霍夫變換來檢測。

其中纺非,我們就可以使用霍夫圓變換來檢測圖像中的圓哑了。這里我們只需要考慮圓心坐標(biāo)(x,y)與半徑r共3個參數(shù)铐炫。

在OpenCV中要經(jīng)過2個步驟:

  1. 找出可能存在圓的位置(圓心)
  2. 根據(jù)1計算半徑

在OpenCV中垒手,它給我們提供的霍夫圓變換函數(shù)為cv2.HoughCircle()蒜焊。該函數(shù)也是將Canny邊緣檢測與霍夫變換結(jié)合倒信,唯一的區(qū)別是,不要我們進行Canny邊緣檢測泳梆,該函數(shù)自動先進行Canny邊緣檢測鳖悠。

其完整定義如下:

def HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None): 

image:原始圖像榜掌,8位單通道灰度圖像

method:檢測方法,HOUGH_GRADIENT是唯一可用的參數(shù)值乘综。該參數(shù)代表霍夫圓檢測中兩輪檢測所使用的方法

dp:累計器分辨率憎账,它是一個分割比例,用來指定圖像分辨率與圓心累加器分辨率的比例卡辰。例如胞皱,如果dp=1,則輸入圖像和累加器具有相同的分辨率

minDist:圓心間最小間距九妈。該值被作為閾值來使用反砌,如果存在圓心間距小于該值的多個圓,則僅有一個會被檢測出來萌朱。因此宴树,如果該值太小,則會有很多臨近的圓被檢測出來晶疼;如果該值很大酒贬,則可能會在檢測時漏掉很多圓

circles:返回值,有圓心坐標(biāo)和半徑構(gòu)成的numpy.ndarray類型翠霍。

param1:該參數(shù)缺省锭吨,默認(rèn)100。它對應(yīng)的是Canny邊緣檢測器的高閾值(低閾值是高閾值的二分之一)

param2:圓心位置必須受到的投票數(shù)寒匙。只有在第1論篩選的過程中耐齐,投票數(shù)超過該值的圓,才有資格進入第2輪的篩選蒋情。因此埠况,該值越大,檢測到的圓越少棵癣;該值越小辕翰,檢測到的圓越多。也是缺省值狈谊,默認(rèn)100

minRadius:圓半徑最小值喜命,小于該值的圓不會被檢測出來。也是缺省值河劝,默認(rèn)0壁榕,不起作用

maxRadius:圓半徑的最大值,大于該值的圓不會被檢測出來赎瞎。也是缺省值牌里,默認(rèn)0,不起作用

下面,我們來用一個奧運五環(huán)的照片牡辽,進行霍夫圓變換喳篇。代碼如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("35_1.jpg")
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis('off')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 300, param1=50, param2=20,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
    cv2.circle(img, (i[0], i[1]), i[2], (255, 0, 0), 12)
    cv2.circle(img, (i[0], i[1]), 2, (255, 0, 0), 12)

plt.subplot(122)
plt.imshow(img, cmap="gray")
plt.axis('off')
plt.show()

運行之后,效果如下:


3.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末态辛,一起剝皮案震驚了整個濱河市麸澜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奏黑,老刑警劉巖炊邦,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異熟史,居然都是意外死亡铣耘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門以故,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜗细,“玉大人,你說我怎么就攤上這事怒详÷剑” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵昆烁,是天一觀的道長吊骤。 經(jīng)常有香客問我,道長静尼,這世上最難降的妖魔是什么白粉? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮鼠渺,結(jié)果婚禮上鸭巴,老公的妹妹穿的比我還像新娘。我一直安慰自己拦盹,他們只是感情好鹃祖,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著普舆,像睡著了一般恬口。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沼侣,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天祖能,我揣著相機與錄音,去河邊找鬼蛾洛。 笑死养铸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揭厚,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扶供!你這毒婦竟也來了筛圆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤椿浓,失蹤者是張志新(化名)和其女友劉穎太援,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扳碍,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡提岔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了笋敞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碱蒙。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夯巷,靈堂內(nèi)的尸體忽然破棺而出赛惩,到底是詐尸還是另有隱情,我是刑警寧澤趁餐,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布喷兼,位于F島的核電站,受9級特大地震影響后雷,放射性物質(zhì)發(fā)生泄漏季惯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一臀突、第九天 我趴在偏房一處隱蔽的房頂上張望勉抓。 院中可真熱鬧,春花似錦候学、人聲如沸琳状。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽念逞。三九已至,卻和暖如春边翁,著一層夾襖步出監(jiān)牢的瞬間翎承,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工符匾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叨咖,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像甸各,于是被迫代替她去往敵國和親垛贤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容