利用Opencv中Houghline方法實(shí)現(xiàn)直線檢測(cè)
利用Opencv中的Houghline方法進(jìn)行直線檢測(cè)—python語(yǔ)言
這是給Python部落翻譯的文章,請(qǐng)?jiān)谶@里看原文。
在圖像處理中,霍夫變換用來(lái)檢測(cè)任意能夠用數(shù)學(xué)公式表達(dá)的形狀,即使這個(gè)形狀被破壞或者有點(diǎn)扭曲。
下面我們將看到利用HoughLine算法來(lái)闡述霍夫變化進(jìn)行直線檢測(cè)的原理,把此算法應(yīng)用到特點(diǎn)圖像的邊緣檢測(cè)是可取的。邊緣檢測(cè)方法請(qǐng)參考這篇文章–邊緣檢測(cè)。
Houghline算法基礎(chǔ)
直線可以表示為y=mx+c,或者以極坐標(biāo)形式表示為r=xcosθ+ysinθ,其中r是原點(diǎn)到直線的垂直距離,θ是水平軸順時(shí)針?lè)较虻酱怪本€的夾角(這個(gè)方向取決于坐標(biāo)的形式,在OpenCV就是采用這種極坐標(biāo)形式)。
因此任意的曲線都可以用兩個(gè)參數(shù)(r,θ)表示。
HoughLine算法原理:
- 首先建立一個(gè)二維的數(shù)組或者累加器(用來(lái)保存這兩個(gè)參數(shù)),并初始化為零;
- 這個(gè)二維數(shù)組的行代表不同的r,而列代表角度θ;
- 數(shù)組的大小取決于算法的精度。假設(shè)所需角度的精度精確到1∘,那么就需要180列(直線的最大角度是180)。
- 對(duì)于r,最大的可能距離是圖像的對(duì)角長(zhǎng)度,因此若需要一個(gè)像素的精度,那么需要把行數(shù)設(shè)為圖像對(duì)角線的長(zhǎng)度。
例子:
假設(shè)一幅100x100的圖像,在圖像中間有一條水平直線。設(shè)直線的第一個(gè)點(diǎn)的坐標(biāo)為(x,y),在直線方程中,令參數(shù)θ=0,12,⋯,180,觀查參數(shù)r變化。對(duì)每一個(gè)參數(shù)對(duì)(r,θ),在累加器中將(r,θ)對(duì)應(yīng)的單元格中的值遞增1,比如現(xiàn)在在累加器中,某個(gè)單元(50,90)的值等于1,其它的值也如此。
對(duì)于直線上的第二個(gè)點(diǎn),重復(fù)上述操作。將得到的參數(shù)對(duì)(r,θ)的對(duì)應(yīng)值繼續(xù)遞增,然后(50,90)對(duì)應(yīng)的值等于2。實(shí)現(xiàn)上我們是對(duì)參數(shù)對(duì)(r,θ)進(jìn)行投票,對(duì)直線上的每一個(gè)點(diǎn)重復(fù)上述操作,對(duì)每一個(gè)點(diǎn),單元格(50,90)對(duì)應(yīng)的值會(huì)遞增,或者說(shuō)投票給參數(shù)對(duì)(50,90),而會(huì)或者不會(huì)投票給其它參數(shù)對(duì)。以這種方式,最后單元格(50,90)的值將會(huì)是最大的值。然后搜索累加器的最大值,將會(huì)找到參數(shù)對(duì)(50,90)。也就是說(shuō),在圖像中找到了到原點(diǎn)距離為50,角度為90的一條直線。
上述算法的過(guò)程被封裝成OpenCV函數(shù)cv2.HoughLines(),函數(shù)返回(r,θ)的一個(gè)數(shù)組,其中r的單位為像素,θ的單位為弧度。
# Python program to illustrate HoughLine # method for line detection import cv2 import numpy as np # Reading the required image in # which operations are to be done. # Make sure that the image is in the same # directory in which this python program is img = cv2.imread('xyz.jpg') # Convert the img to grayscale gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # Apply edge detection method on the image edges = cv2.Canny(gray,50,150,apertureSize = 3) # This returns an array of r and theta values lines = cv2.HoughLines(edges,1,np.pi/180, 200) # The below for loop runs till r and theta values # are in the range of the 2d array for r,theta in lines[0]: # Stores the value of cos(theta) in a a = np.cos(theta) # Stores the value of sin(theta) in b b = np.sin(theta) # x0 stores the value rcos(theta) x0 = a*r # y0 stores the value rsin(theta) y0 = b*r # x1 stores the rounded off value of (rcos(theta)-1000sin(theta)) x1 = int(x0 + 1000*(-b)) # y1 stores the rounded off value of (rsin(theta)+1000cos(theta)) y1 = int(y0 + 1000*(a)) # x2 stores the rounded off value of (rcos(theta)+1000sin(theta)) x2 = int(x0 - 1000*(-b)) # y2 stores the rounded off value of (rsin(theta)-1000cos(theta)) y2 = int(y0 - 1000*(a)) # cv2.line draws a line in img from the point(x1,y1) to (x2,y2). # (0,0,255) denotes the colour of the line to be #drawn. In this case, it is red. cv2.line(img,(x1,y1), (x2,y2), (0,0,255),2) # All the changes made in the input image are finally # written on a new image houghlines.jpg cv2.imwrite('houghlines3.jpg', img)
函數(shù)(cv2.HoughLines(edges, 1, np.pi/180,200))
- 第一個(gè)參數(shù)是輸入圖像,且必須是二值圖像,在進(jìn)行霍夫變換之前需要采用閾值方法的邊緣檢測(cè);
- 第二和第三個(gè)參數(shù)分別是r,θ對(duì)應(yīng)的精度;
- 第四個(gè)參數(shù)是閾值,判定為直線投票數(shù)的最小值;
- 注意,投票數(shù)取決于直線上點(diǎn)的個(gè)數(shù),因此這個(gè)閾值代表了檢測(cè)到的直線的最短長(zhǎng)度。
總結(jié)
- 在圖像分析應(yīng)用中,邊緣分割點(diǎn)的坐標(biāo)(即X,Y)是已知的,在直線的參數(shù)方程中作為輸入,而r,θ是我們要找的未知變量;
- 對(duì)每一個(gè)角度θ,求出r的值,也就是將笛卡爾圖像空間的點(diǎn)映射到霍夫參數(shù)極坐標(biāo)空間的曲線,這種點(diǎn)到曲線的變換就是直線的霍夫變換;
- 這種變換是通過(guò)量化霍夫參數(shù)為有限的間隔或者累加器單元來(lái)實(shí)現(xiàn)的,隨著算法的運(yùn)行,每一個(gè)(X,Y)轉(zhuǎn)換成離散的(r,θ)曲線,曲線上的點(diǎn)對(duì)應(yīng)的累加器(二維數(shù)組)的值會(huì)遞增;
- 累加器中的峰值就代表了圖像中有相應(yīng)直線的存在。
霍夫變換的應(yīng)用
- 用于分離圖像中特殊形狀的特征;
- 可以容忍特征邊界描述的誤差,并且不受噪聲的干擾;
- 廣泛用于條形碼掃描、驗(yàn)證和識(shí)別。
文章作者是Pratima Upadhyay,如果你喜歡GeeksforGeeks,并且愿意分享,可以利用contribute.geeksforgeeks.org寫文章,然后發(fā)送到contribute@geeksforgeeks.org,在GeeksforGeeks中看到自己的文章,幫助更多的Geeks。
若發(fā)現(xiàn)錯(cuò)誤歡迎指正,也歡迎評(píng)論。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
django 通過(guò)ajax完成郵箱用戶注冊(cè)、激活賬號(hào)的方法
本篇文章主要介紹了django 通過(guò)ajax完成郵箱用戶注冊(cè)、激活賬號(hào)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04python實(shí)戰(zhàn)練習(xí)做一個(gè)隨機(jī)點(diǎn)名的程序
讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Python實(shí)現(xiàn)一個(gè)隨機(jī)點(diǎn)名的程序,大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-10-10詳解Python如何利用pdfplumber提取PDF中的表格
pdfplumber 是一個(gè)開(kāi)源的 python 工具庫(kù) ,它可以輕松的獲取 PDF 文本內(nèi)容、標(biāo)題、表格、尺寸等各種信息,今天來(lái)介紹如何使用它來(lái)提取 PDF 中的表格,文中通過(guò)代碼和圖片講解的非常詳細(xì),需要的朋友可以參考下2024-04-04python將多個(gè)文本文件合并為一個(gè)文本的代碼(便于搜索)
源代碼目錄一般很詳細(xì),每個(gè)代碼文件都不長(zhǎng),一般只占幾十行而已。在跟著書(shū)籍學(xué)習(xí)的過(guò)程中,可以打開(kāi)源代碼運(yùn)行之后查看效果,或者適當(dāng)修改看看變化,這都是很好的掌握技術(shù)的好辦法。2011-03-03python面向?qū)ο蠓▽?shí)現(xiàn)圖書(shū)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python面向?qū)ο蠓▽?shí)現(xiàn)圖書(shū)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04淺談pycharm導(dǎo)入pandas包遇到的問(wèn)題及解決
這篇文章主要介紹了淺談pycharm導(dǎo)入pandas包遇到的問(wèn)題及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06