OpenCV_09 模版匹配和霍夫变换:霍夫线检测+霍夫圆检测
1 模板匹配
1.1 原理
所謂的模板匹配,就是在給定的圖片中查找和模板最相似的區域,該算法的輸入包括模板和圖片,整個任務的思路就是按照滑窗的思路不斷的移動模板圖片,計算其與圖像中對應區域的匹配度,最終將匹配度最高的區域選擇為最終的結果。
實現流程:
-
準備兩幅圖像:
1.原圖像(I):在這幅圖中,找到與模板相匹配的區域
2.模板(T):與原圖像進行比對的圖像塊
? -
滑動模板圖像和原圖像進行比對:
將模板塊每次移動一個像素 (從左往右,從上往下),在每一個位置,都計算與模板圖像的相似程度。
- 對于每一個位置將計算的相似結果保存在結果矩陣(R)中。如果輸入圖像的大小(WxH)且模板圖像的大小(wxh),則輸出矩陣R的大小為(W-w + 1,H-h + 1)將R顯示為圖像,如下圖所示:
- 獲得上述圖像后,查找最大值所在的位置,那么該位置對應的區域就被認為是最匹配的。對應的區域就是以該點為頂點,長寬和模板圖像一樣大小的矩陣。
1.2 實現
我們使用OpenCV中的方法實現模板匹配。
API:
res = cv.matchTemplate(img,template,method)參數:
- img: 要進行模板匹配的圖像
- Template :模板
- method:實現模板匹配的算法,主要有:
完成匹配后,使用cv.minMaxLoc()方法查找最大值所在的位置即可。如果使用平方差作為比較方法,則最小值位置是最佳匹配位置。
示例:
在該案例中,載入要搜索的圖像和模板,圖像如下所示:
模板如下所示:
通過matchTemplate實現模板匹配,使用minMaxLoc定位最匹配的區域,并用矩形標注最匹配的區域。
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 圖像和模板讀取 img = cv.imread('./img/wulin.png') template = cv.imread('./img/temp.png') # 獲取模板的大小,之后用于主圖像分塊 h,w,l = template.shape # 2 模板匹配 # 2.1 模板匹配 res = cv.matchTemplate(img, template, cv.TM_CCORR) # 2.2 返回圖像中最匹配的位置,確定左上角的坐標,并將匹配位置繪制在圖像上 # cv::minMaxLoc 從一個矩陣中找出全局的最大值和最小值。 min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) # 使用平方差時最小值為最佳匹配位置 top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) #繪制目標框 其目標框大小與 # cvRectangle(圖像,矩形的一個頂點,矩形對角線上的另一個頂點,線條顏色,矩形的線條的粗細程度); cv.rectangle(img, top_left, bottom_right, (0,255,0), 2) # 3 圖像顯示 plt.imshow(img[:,:,::-1]) plt.title('匹配結果'), plt.xticks([]), plt.yticks([]) plt.show()拓展:模板匹配不適用于尺度變換,視角變換后的圖像。
我們就要使用關鍵點匹配算法,比較經典的關鍵點檢測算法包括SIFT和SURF等,主要的思路是首先通過關鍵點檢測算法獲取模板和測試圖片中的關鍵點;然后使用關鍵點匹配算法處理即可,這些關鍵點可以很好的處理尺度變化、視角變換、旋轉變化、光照變化等,具有很好的不變性。
2 霍夫變換
霍夫變換常用來提取圖像中的直線和圓等幾何形狀,如下圖所示:
2.1 原理
變換后的空間我們叫做霍夫空間。即:笛卡爾坐標系中的一條直線,對應于霍夫空間中的一個點。反過來,同樣成立,霍夫空間中的一條線,對應于笛卡爾坐標系中一個點,如下所示:?
?
我們再來看下A、B兩個點,對應于霍夫空間的情形:
在看下三點共線的情況:
可以看出如果在笛卡爾坐標系的點共線,那么這些點在霍夫空間中對應的直線交于一點。
如果不止存在一條直線時,如下所示:
我們選擇盡可能多的直線匯成的點,上圖中三條直線匯成的A、B兩點,將其對應回笛卡爾坐標系中的直線:
?到這里我們似乎已經完成了霍夫變換的求解。但如果像下圖這種情況時:
上圖中的直線是x=2,那(k,q)怎么確定呢?
為了解決這個問題,我們考慮將笛卡爾坐標系轉換為極坐標。
在極坐標下是一樣的,極坐標中的點對應于霍夫空間的線,這時的霍夫空間是不在是參數(k,q)的空間,而是(ρ,θ)的空間,ρ是原點到直線的垂直距離,θ表示直線的垂線與橫軸順時針方向的夾角,垂直線的角度為0度,水平線的角度是180度。
我們只要求得霍夫空間中的交點的位置,即可得到原坐標系下的直線。
實現流程
假設有一個大小為100*?100的圖片,使用霍夫變換檢測圖片中的直線,則步驟如下所示:
-
直線都可以使用(ρ,θ)?表示,首先創建一個2D數組,我們叫做累加器,初始化所有值為0,行表示ρ?,列表示θ?。
該數組的大小決定了結果的準確性,若希望角度的精度為1度,那就需要180列。對于ρ,最大值為圖片對角線的距離,如果希望精度達到像素級別,行數應該與圖像的對角線的距離相等。
-
取直線上的第一個點(x,y),將其帶入直線在極坐標中的公式中,然后遍歷θ的取值:0,1,2,...,180,分別求出對應的ρ值,如果這個數值在上述累加器中存在相應的位置,則在該位置上加1.
-
取直線上的第二個點,重復上述步驟,更新累加器中的值。對圖像中的直線上的每個點都直線以上步驟,每次更新累加器中的值。
-
搜索累加器中的最大值,并找到其對應的(ρ,θ),就可將圖像中的直線表示出來。
2.2 霍夫線檢測
在OpenCV中做霍夫線檢測是使用的API是:
cv.HoughLines(img, rho, theta, threshold)參數:
-
img: 檢測的圖像,要求是二值化的圖像,所以在調用霍夫變換之前首先要進行二值化,或者進行Canny邊緣檢測
-
rho、theta: ρ?和θ的精確度
-
threshold: 閾值,只有累加器中的值高于該閾值時才被認為是直線。
霍夫線檢測的整個流程如下圖所示,這是在stackflow上一個關于霍夫線變換的解釋:
示例:
檢測下述圖像中的直線:
2.3 霍夫圓檢測[了解](霍夫梯度法)
原理
API
在OpenCV中檢測圖像中的圓環使用的是API是:
circles = cv.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0,maxRadius=0 )參數:
-
image:輸入圖像,應輸入灰度圖像
-
method:使用霍夫變換圓檢測的算法,它的參數是CV_HOUGH_GRADIENT
-
dp:霍夫空間的分辨率,dp=1時表示霍夫空間與輸入圖像空間的大小一致,dp=2時霍夫空間是輸入圖像空間的一半,以此類推
-
minDist:圓心之間的最小距離,如果檢測到的兩個圓心之間距離小于該值,則認為它們是同一個圓心
-
param1:邊緣檢測時使用Canny算子的高閾值,低閾值是高閾值的一半。
-
param2:檢測圓心和確定半徑時所共有的閾值
-
minRadius:所檢測到的圓半徑的最小值
-
maxRadius:所檢測到的圓半徑的最大值
返回:
- circles:輸出圓向量,包括三個浮點型的元素——圓心橫坐標,圓心縱坐標和圓半徑
實現
由于霍夫圓檢測對噪聲比較敏感,所以首先對圖像進行中值濾波。
import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 1 讀取圖像,并轉換為灰度圖 planets = cv.imread("./img/star.jpg") gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY) # 2 進行中值模糊,去噪點 img = cv.medianBlur(gay_img, 7) # 3 霍夫圓檢測 circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 200, param1=100, param2=30, minRadius=0, maxRadius=100) # 4 將檢測結果繪制在圖像上 for i in circles[0, :]: # 遍歷矩陣每一行的數據# cvCircle(源圖像指針, 畫圓的圓心坐標,圓的半徑,圓的顏色,圓的線條的粗細程度,線條的類型,圓心坐標點和半徑值的小數點位數)# 繪制圓形cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)# 繪制圓心cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3) # 5 圖像顯示 plt.figure(figsize=(10,8),dpi=100) plt.imshow(planets[:,:,::-1]),plt.title('霍夫變換圓檢測') plt.xticks([]), plt.yticks([]) plt.show()總結:
模板匹配
原理:在給定的圖片中查找和模板最相似的區域
API:利用cv.matchTemplate()進行模板匹配,然后
使用cv.minMaxLoc()搜索最匹配的位置。
霍夫線檢測
原理:將要檢測的內容轉換到霍夫空間中,利用累加器統計最優解,將檢測結果表示處理
API:cv2.HoughLines()
注意:該方法輸入是的二值化圖像,在進行檢測前要將圖像進行二值化處理
霍夫圓檢測
方法:霍夫梯度法
API:cv.HoughCircles()
總結
以上是生活随笔為你收集整理的OpenCV_09 模版匹配和霍夫变换:霍夫线检测+霍夫圆检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微型计算机中存储器分成哪几个等级?它们各
- 下一篇: react不同环境不同配置angular