python霍夫变换检测直线_OpenCV-Python教程(9、使用霍夫变换检测直线)
相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++調用相應OpenCV函數的不同之處。這篇文章介紹在Python中使用OpenCV的霍夫變換檢測直線。
提示:
轉載請詳細注明原作者及出處,謝謝!
本文介紹在OpenCV-Python中使用霍夫變換檢測直線的方法。
本文不介詳細的理論知識,讀者可從其他資料中獲取相應的背景知識。筆者推薦清華大學出版社的《圖像處理與計算機視覺算法及應用(第2版) 》。
霍夫變換
Hough變換是經典的檢測直線的算法。其最初用來檢測圖像中的直線,同時也可以將其擴展,以用來檢測圖像中簡單的結構。
OpenCV提供了兩種用于直線檢測的Hough變換形式。其中基本的版本是cv2.HoughLines。其輸入一幅含有點集的二值圖(由非0像素表示),其中一些點互相聯系組成直線。通常這是通過如Canny算子獲得的一幅邊緣圖像。cv2.HoughLines函數輸出的是[float, float]形式的ndarray,其中每個值表示檢測到的線(ρ , θ)中浮點點值的參數。下面的例子首先使用Canny算子獲得圖像邊緣,然后使用Hough變換檢測直線。其中HoughLines函數的參數3和4對應直線搜索的步長。在本例中,函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線。最后一個參數是經過某一點曲線的數量的閾值,超過這個閾值,就表示這個交點所代表的參數對(rho, theta)在原圖像中為一條直線。具體理論可參考這篇文章。
#coding=utf-8
import cv2
import numpy as np
img = cv2.imread("/home/sunny/workspace/images/road.jpg", 0)
img = cv2.GaussianBlur(img,(3,3),0)
edges = cv2.Canny(img, 50, 150, apertureSize = 3)
lines = cv2.HoughLines(edges,1,np.pi/180,118) #這里對最后一個參數使用了經驗型的值
result = img.copy()
for line in lines[0]:
rho = line[0] #第一個元素是距離rho
theta= line[1] #第二個元素是角度theta
print rho
print theta
if (theta < (np.pi/4. )) or (theta > (3.*np.pi/4.0)): #垂直直線
#該直線與第一行的交點
pt1 = (int(rho/np.cos(theta)),0)
#該直線與最后一行的焦點
pt2 = (int((rho-result.shape[0]*np.sin(theta))/np.cos(theta)),result.shape[0])
#繪制一條白線
cv2.line( result, pt1, pt2, (255))
else: #水平直線
# 該直線與第一列的交點
pt1 = (0,int(rho/np.sin(theta)))
#該直線與最后一列的交點
pt2 = (result.shape[1], int((rho-result.shape[1]*np.cos(theta))/np.sin(theta)))
#繪制一條直線
cv2.line(result, pt1, pt2, (255), 1)
cv2.imshow('Canny', edges )
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
結果如下:
注意:
在C++中,HoughLines函數得到的結果是一個向量lines,其中的元素是由兩個元素組成的子向量(rho, theta),所以lines的訪問方式類似二維數組。因此,可以以類似:
std::vector<:vec2f>::const_iterator it= lines.begin();
float rho= (*it)[0];
float theta= (*it)[1];
這樣的方式訪問rho和theta。
而在Python中,返回的是一個三維的np.ndarray!。可通過檢驗HoughLines返回的lines的ndim屬性得到。如:
lines = cv2.HoughLines(edges,1,np.pi/180,118)
print lines.ndim
#將得到3
至于為什么是三維的,這和NumPy中ndarray的屬性有關(關于NumPy的相關內容,請移步至 NumPy簡明教程),如果將HoughLines檢測到的的結果輸出,就一目了然了:
#上面例子中檢測到的lines的數據
3 #lines.ndim屬性
(1, 5, 2) #lines.shape屬性
#lines[0]
[[ 4.20000000e+01 2.14675498e+00]
[ 4.50000000e+01 2.14675498e+00]
[ 3.50000000e+01 2.16420817e+00]
[ 1.49000000e+02 1.60570288e+00]
[ 2.24000000e+02 1.74532920e-01]]
===============
#lines本身
[[[ 4.20000000e+01 2.14675498e+00]
[ 4.50000000e+01 2.14675498e+00]
[ 3.50000000e+01 2.16420817e+00]
[ 1.49000000e+02 1.60570288e+00]
[ 2.24000000e+02 1.74532920e-01]]]
概率霍夫變換
觀察前面的例子得到的結果圖片,其中Hough變換看起來就像在圖像中查找對齊的邊界像素點集合。但這樣會在一些情況下導致虛假檢測,如像素偶然對齊或多條直線穿過同樣的對齊像素造成的多重檢測。
要避免這樣的問題,并檢測圖像中分段的直線(而不是貫穿整個圖像的直線),就誕生了Hough變化的改進版,即概率Hough變換(Probabilistic Hough)。在OpenCV中用函數cv::HoughLinesP 實現。如下:
#coding=utf-8
import cv2
import numpy as np
img = cv2.imread("/home/sunny/workspace/images/road.jpg")
img = cv2.GaussianBlur(img,(3,3),0)
edges = cv2.Canny(img, 50, 150, apertureSize = 3)
lines = cv2.HoughLines(edges,1,np.pi/180,118)
result = img.copy()
#經驗參數
minLineLength = 200
maxLineGap = 15
lines = cv2.HoughLinesP(edges,1,np.pi/180,80,minLineLength,maxLineGap)
for x1,y1,x2,y2 in lines[0]:
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
cv2.imshow('Result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
結果如下:
未完待續。。。
參考資料:
1、《Opencv2 Computer Vision Application Programming Cookbook》
2、《OpenCV References Manule》
如果覺得本文寫的還可以的話,請輕點“頂”,您的支持是我寫下去的動力之一。未完待續。。。如有錯誤請指正,本人會虛心接受并改正!謝謝!
總結
以上是生活随笔為你收集整理的python霍夫变换检测直线_OpenCV-Python教程(9、使用霍夫变换检测直线)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python无效数据怎么办_Python
- 下一篇: python 鱼c工作室作业_鱼C工作室