opencv+python Hough變換的基本原理
Hough變換思想(參數空間變換):
在原始圖像坐標系下的一個點對應了參數坐標系中的一條直線,同樣參數坐標系的一條直線對應了原始坐標系下的一個點,然後,原始坐標系下呈現直線的所有點,它們的斜率和截距是相同的,所以它們在參數坐標系下對應於同一個點。這樣在將原始坐標系下的各個點投影到參數坐標系下之後,看參數坐標系下有沒有聚集點,這樣的聚集點就對應了原始坐標系下的直線。
在實際應用中,y=kx+b形式的直線方程沒有辦法表示x=c形式的直線(這時候,直線的斜率為無窮大)。所以實際應用中,是採用參數方程p=xcos(theta)+y*sin(theta)。這樣,圖像平面上的一個點就對應到參數p—theta平面上的一條曲線上,其它的還是一樣。
Hough變換思想(參數空間劃分網格統計):
為了檢測出直角坐標X-Y中由點所構成的直線,可以將極坐標a-p量化成許多小格。根據直角坐標中每個點的坐標(x,y),在a = 0-180°內以小格的步長計算各個p值,所得值落在某個小格內,便使該小格的累加記數器加1。當直角坐標中全部的點都變換後,對小格進行檢驗,計數值最大的小格,其(a,p)值對應於直角坐標中所求直線。
Hough變換的程序實現:
import cv2
import numpy as np
#hough變換的程序實現
img = cv2.imread("building.jpg")#讀取圖片
img2 = img.copy()
gray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#將圖片轉換為灰度圖
edges = cv2.Canny(gray,50,150,apertureSize = 3)#canny演算法提取輪廓
#基於概率的hough變換......................................................
lines_Probabilitys = cv2.HoughLinesP(edges,1,np.pi/180,30,minLineLength=100,maxLineGap=10)#概率hough變換
lines_Probability = lines_Probabilitys[:,0,:]#提取為二維
for x1,y1,x2,y2 in lines_Probability[:]:
cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)
cv2.namedWindow("HoughLines_Probabilitys", 2) #創建一個窗口
cv2.imshow("HoughLines_Probabilitys", img) #顯示原始圖片
#標準的hough變換......................................................
lines_standards = cv2.HoughLines(edges,1,np.pi/180,200) #標準hough變換查找直線
#繪製hough變換後找到的所有直線,返回數據是一個二位數組
for lines_standard in lines_standards:
for rho,theta in lines_standard:
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(img2,(x1,y1),(x2,y2),(0,0,255),2)
print(lines_standards)#列印出找到的直線的極坐標系坐標、
cv2.namedWindow("HoughLines_standards", 2) #創建一個窗口
cv2.imshow("HoughLines_standards", img2) #顯示原始圖片
cv2.waitKey()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
函數參數解釋:
HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)
image: 必須是二值圖像,推薦使用canny邊緣檢測的結果圖像;
rho: 線段以像素為單位的距離精度,double類型的,推薦用1.0
theta: 線段以弧度為單位的角度精度,推薦用numpy.pi/180
threshod: 累加平面的閾值參數,int類型,超過設定閾值才被檢測出線段,值越大,基本上意味著檢出的線段越長,檢出的線段個數越少。根據情況推薦先用100試試
lines:這個參數的意義未知,發現不同的lines對結果沒影響,但是不要忽略了它的存在
minLineLength:線段以像素為單位的最小長度,根據應用場景設置
maxLineGap:同一方向上兩條線段判定為一條線段的最大允許間隔(斷裂),超過了設定值,則把兩條線段當成一條線段,值越大,允許線段上的斷裂越大,越有可能檢出潛在的直線段
cvHoughLines2( CvArr* image, void* line_storage, int method,double rho, double theta, int threshold,double param1=0, double param2=0 );
image輸入 8-比特、單通道 (二值) 圖像,其內容可能被函數所改變
line_storage檢測到的線段存儲.
method
CV_HOUGH_STANDARD - 傳統或標準 Hough 變換. 每一個線段由兩個浮點數 (ρ, θ)表示,其中 ρ 是點與原點 (0,0) 之間的距離, θ 線段與 x-軸之間的夾角。因此,矩陣類型必須是 CV_32FC2 type.
CV_HOUGH_PROBABILISTIC - 概率 Hough 變換(如果圖像包含一些長的線性分割,則效率更高). 它返回線段分割而不是整個線段。每個分割用起點和終點來表示,所以矩陣(或創建的序列)類型是 CV_32SC4.
CV_HOUGH_MULTI_SCALE - 傳統 Hough 變換的多尺度變種。線段的編碼方式與CV_HOUGH_STANDARD 的一致。
rho與象素相關單位的距離精度
theta弧度測量的角度精度
threshold閾值參數。如果相應的累計值大於 threshold, 則函數返回的這個線段.
param1第一個方法相關的參數:
對傳統 Hough 變換,不使用(0).
對概率 Hough 變換,它是最小線段長度.
對多尺度 Hough 變換,它是距離精度 rho 的分母 (大致的距離精度是 rho 而精確的應該是 rho / param1 ).
param2第二個方法相關參數:
對傳統 Hough 變換,不使用 (0).
對概率 Hough 變換,這個參數表示在同一條直線上進行碎線段連接的最大間隔值(gap), 即當同一條直線上的兩條碎線段之間的間隔小於 param2 時,將其合二為一。
對多尺度 Hough 變換,它是角度精度 theta 的分母 (大致的角度精度是 theta 而精確的角度應該是 theta / param2).
檢測效果:
---------------------
打開今日頭條,查看更多圖片作者:逗創創
原文:https://blog.csdn.net/u014005758/article/details/88403937
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
※如何使用Netty技術設計一個百萬級的消息推送系統
※EF Core的三種主要關係類型
TAG:程序員小新人學習 |