參考課程:
【黑馬程序員 OpenCV入門教程】
[https://www.bilibili.com/video/BV1Fo4y1d7JL]
@ZZHow(ZZHow1024)
1.1幾何變換
-
圖像縮放
- 對圖像的大小進行調整,即使圖像放大或縮小
cv2.resize(src, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)
- 參數
-
src:輸入圖像
-
dsize:絕對尺寸,直接指定調整后圖像的大小
-
fx, fy:相對尺寸,將 dsize 設置為 None,然后將 fx 和 fy 設置為比例因子即可
-
interpolation:插值方法
插值 含義 cv2.INTER_LINEAR 雙線性插值法 cv2.INTER_NEAREST 量近鄰插值 cv2.INTER_AREA 像素區域重采樣**(默認)** cv2.INTER_CUBIC 雙三次插值
-
-
圖像平移
- 將圖像按照指定方向和距離,移動到相應的位置
cv2.warpAffine(image, M, dsize)
- 參數
- image:輸入圖像
- M:2 × 3 移動矩陣
-
對于 (x,y)(x, y)(x,y) 處的像素點,要把它移動到 (x+tx,y+ty)(x + t_x, y + t_y)(x+tx?,y+ty?) 處時,MMM 矩陣應如下設置
M=[10tx01ty]M = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix}M=[10?01?tx?ty??]
-
注意:將 MMM 設置為
np.float32
類型的 NumPy 數組
-
- dsize:輸出圖像的大小
- 注意:輸出圖像的大小應該是 (寬度, 高度) 的形式,width=列數,height=行數
-
圖像旋轉
-
將圖像按照某個位置轉動一定角度的過程,旋轉中圖像仍保持這原始尺寸
-
假設圖像逆時針旋轉 θ\thetaθ,則根據坐標轉換可得旋轉轉換為
{x′=rcos(α?θ)y′=rsin(α?θ)\begin{cases}? ?x' = r cos(\alpha - \theta) \\? ?y' = r sin(\alpha - \theta)\end{cases}{??x′=rcos(α?θ)??y′=rsin(α?θ)?
其中 r=x2+y2,sinα=yx2+y2,cosα=xx2+y2r = \sqrt{x^2 + y^2}, sin\alpha = \frac{y}{\sqrt{x^2 + y^2}}, cos\alpha = \frac{x}{\sqrt{x^2 + y^2}}r=x2+y2?,sinα=x2+y2?y?,cosα=x2+y2?x?
代入公式有
{x′=xcosθ+ysinθy′=?xsinθ+ycosθ\begin{cases} x' = x cos\theta + y sin\theta \\ y' = -x sin\theta + ycos\theta\end{cases}{x′=xcosθ+ysinθy′=?xsinθ+ycosθ?
也可以寫成
[x′y′1]=[xy1][cosθ?sinθ0sinθcosθ0001]\begin{bmatrix}? ?x' & y' & 1\end{bmatrix}?=?\begin{bmatrix}? ?x & y & 1\end{bmatrix}\begin{bmatrix}? ?cos\theta & -sin\theta & 0 \\? ?sin\theta & cos\theta & 0 \\? ?0 & 0 & 1\end{bmatrix}[??x′?y′?1?]?=?[??x?y?1?]???cosθ??sinθ??0??sinθcosθ0?001??
原點修正
[x′′y′′1]=[x′y′1][1000?10lefttop1]=[xy1][cosθ?sinθ0sinθcosθ0001][1000?10lefttop1]\begin{bmatrix}? ?x'' & y'' & 1\end{bmatrix}?=?\begin{bmatrix}? ?x' & y' & 1\end{bmatrix}\begin{bmatrix}? ?1 & 0 & 0 \\? ?0 & -1 & 0 \\? ?left & top & 1\end{bmatrix}?=?\begin{bmatrix}? ?x & y & 1\end{bmatrix}\begin{bmatrix}? ?cos\theta & -sin\theta & 0 \\? ?sin\theta & cos\theta & 0 \\? ?0 & 0 & 1\end{bmatrix}\begin{bmatrix}? ?1 & 0 & 0 \\? ?0 & -1 & 0 \\? ?left & top & 1\end{bmatrix}[??x′′?y′′?1?]?=?[??x′?y′?1?]???1??0??left?0?1top?001???=?[??x?y?1?]???cosθ??sinθ??0??sinθcosθ0?001?????1??0??left?0?1top?001??
cv2.getRotationMatrix2D(center, angle, scale)
- 參數
- center:旋轉中心
- angle:旋轉角度
- scale:縮放比例
- 返回
M:旋轉矩陣,調用cv.warpAffine()
完成圖像的旋轉
-
-
仿射變換
-
圖像的仿射變換涉及到圖像的形狀位置角度的變化,是深度學習預處理中常到的功能,仿射變換主要是對圖像的縮放,旋轉,翻轉和平移等操作的組合
-
在OpenCV中,仿射變換的矩陣是一個 2 × 3 的矩陣
M=[AB]=[a00a01b0a10a11b1]M?=?\begin{bmatrix}? ?A & B\end{bmatrix}?=?\begin{bmatrix}? ?a_{00} & a_{01} & b_0 \\? ?a_{10} & a_{11} & b_1 \\\end{bmatrix}M?=?[??A?B?]?=?[??a00???a10??a01?a11??b0?b1??]
-
其中左邊的 2 × 2 子矩陣 AAA 是線性變換矩陣,右邊的 2 × 1 子矩陣 BBB 是平移項
A=[a00a01a10a11],B=[b0b1]A?=?\begin{bmatrix}? ?a_{00} & a_{01} \\? ?a_{10} & a_{11} \\\end{bmatrix},B?=?\begin{bmatrix}? ?b_0 \\? ?b_1 \\\end{bmatrix}A?=?[??a00???a10??a01?a11??],B?=?[??b0???b1??]
-
對于圖像上的任一位置 (x,y)(x, y)(x,y),仿射變換執行的是如下的操作
Taffine=A[xy]+B=M[xy1]T_{affine}?=A\begin{bmatrix}? ?x \\? ?y \\\end{bmatrix}?+?B?=?M\begin{bmatrix}? ?x \\? ?y \\? ?1 \\\end{bmatrix}Taffine??=A[??x??y?]?+?B?=?M???x??y??1??
-
注意:對于圖像而言,寬度方向是 x,高度方向是 y,坐標的順序和圖像像素對應下標一致,原點的位置不是左下角而是右上角,y 的方向也不是向上,而是向下
-
在 OpenCV 中
cv2.getAffineTransform
會創建一個 2 × 3 的矩陣,最后這個矩陣會被傳給函數cv2.warpAffine
-
-
透射變換
-
透射變換是視角變化的結果,是指利用透視中心、像點、目標點三點共線的條件,按透視旋轉定律使承影面(透視面)繞跡線(透視軸)旋轉某一角度,破壞原有的投影光線束,仍能保持承影面上投影幾何圖形不變的變換
-
它的本質將圖像投影到一個新的視平面,其通用變換公式為
[x′y′z′]=[uvw][a00a01a02a10a11a12a20a21a22]\begin{bmatrix}? ?x' & y' & z'\end{bmatrix}?=?\begin{bmatrix}? ?u & v & w\end{bmatrix}\begin{bmatrix}? ?a_{00} & a_{01} & a_{02} \\? ?a_{10} & a_{11} & a_{12} \\? ?a_{20} & a_{21} & a_{22} \\\end{bmatrix}[??x′?y′?z′?]?=?[??u?v?w?]???a00???a10???a20??a01?a11?a21??a02?a12?a22???
其中,(u,v)(u, v)(u,v) 是原始的圖像像素坐標,www 取值為 1,(x=x′/z′,y=y’/z’)(x = x' / z', y = y’ / z’)(x=x′/z′,y=y’/z’) 是透射變換后的結果
后面的矩陣稱為透視變換矩陣,一般情況下,我們將其分為三部分
T=[a00a01a02a10a11a12a20a21a22]=[T1T2T3a22]T?=?\begin{bmatrix}? ?a_{00} & a_{01} & a_{02} \\? ?a_{10} & a_{11} & a_{12} \\? ?a_{20} & a_{21} & a_{22} \\\end{bmatrix}?=?\begin{bmatrix}? ?T_1 & T_2 \\? ?T_3 & a_{22} \\\end{bmatrix}T?=????a00???a10???a20??a01?a11?a21??a02?a12?a22????=?[??T1???T3??T2?a22??]
其中,T1T_1T1? 表示對圖像進行線性變換,T2T_2T2? 對圖像進行平移,T3T_3T3? 表示對圖像進行投射變換,a22a_{22}a22? 一般設為 1
-
在 OpenCV 中,我們要找到四個點,其中任意三個不共線,然后獲取變換矩陣 TTT,再進行透射變換
- 通過函數
cv2.getPerspectiveTransform
找到變換矩陣,將cv2.warpPerspective
應用于此 3 × 3 變換矩陣
- 通過函數
-
-
圖像金字塔
- 圖像多尺度表達的一種,最主要用于圖像的分割,是一種以多分辨率來解釋圖像的有效但概念簡單的結構
- 金字塔的底部是待處理圖像的高分辨率表示,而頂部是低分辨率的近似,層級越高,圖像越小,分辨率越低
cv2.pyrUp(image) # 對圖像進行上采樣 cv2.pyrDown(image) # 對圖像進行下采樣
-
案例演示:geometric_transformation.ipynb
1.2形態學操作
-
連通性
- 在圖像中,最小的單位是像素,每個像素周圍有 8 個鄰接像素,常見的鄰接關系有 3 種
- 4 鄰接:像素 p(x,y)p(x, y)p(x,y) 的 4 鄰域是:(x+1,y);(x?1,y);(x,y+1);(x,y?1)(x+1, y); (x-1, y); (x, y+1); (x, y-1)(x+1,y);(x?1,y);(x,y+1);(x,y?1),用 N4(P)N_4(P)N4?(P) 表示像素 ppp 的 4 鄰接
- 8 鄰接:像素 p(x,y)p(x, y)p(x,y) 的 8 鄰域是:4 鄰域的點 + D 鄰域的點,用 N8(p)N_8(p)N8?(p) 表示像素 p 的 8 鄰域
- D 鄰接:像素 p(x,y)p(x, y)p(x,y) 的 D 鄰域是:(x+1,y+1);(x?1,y?1);(x?1,y+1);(x+1,y?1)(x+1, y+1); (x-1, y-1); (x-1, y+1); (x+1, y-1)(x+1,y+1);(x?1,y?1);(x?1,y+1);(x+1,y?1),用 ND(P)N_D(P)ND?(P) 表示像素 ppp 的 DDD 鄰接
- 連通性是描述區域和邊界的重要概念,兩個像素連通的兩個必要條件是
- 兩個像素的位置是否相鄰
- 兩個像素的灰度值是否滿足特定的相似性準則
- 根據連通性的定義,有 4 聯通、8 聯通和 mmm 聯通三種
- 4 連通:對于具有值 VVV 的像素 ppp 和 qqq,如果 qqq 在集合 N4(p)N_4(p)N4?(p) 中,則稱這兩個像素是 4 連通
- 8 連通:對于具有值 VVV 的像素 ppp 和 qqq,如果 qqq 在集合 N8(p)N_8(p)N8?(p) 中,則稱這兩個像素是 8 連通
- mmm 連通:對于具有值 VVV 的像素 ppp 和 qqq,如果 qqq 在集合 N4(p)N_4(p)N4?(p) 中或 qqq 在集合 ND(p)N_D(p)ND?(p) 中,并且 N4(P)N_4(P)N4?(P) 與 N4(g)N_4(g)N4?(g) 的交集為空(沒有值 VVV 的像素),則稱這兩個像素是 mmm 連通的,即 4 連通和 DDD 連通的混合連通
- 在圖像中,最小的單位是像素,每個像素周圍有 8 個鄰接像素,常見的鄰接關系有 3 種
-
腐蝕和膨脹
-
腐蝕:時原圖中的高亮區域被蠶食,效果圖擁有比原圖更小的高亮區域,是求局部最小值的操作
-
膨脹:使圖像中高亮部分擴張,效果圖擁有比原圖更大的高亮區域,是求局部最大值的操作
-
腐蝕
- 用一個結構元素掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為 1,則該像素為 1,否則為 0
cv2.erode(image, kernel, iterations)
- 參數
- image:要處理的圖像
- kernel:核結構
- iterations:腐蝕的次數,默認是 1
-
膨脹
- 用一個結構元素掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為 0,則該像素為 0,否則為 1
cv2.dilate(image, kernel, iterations)
- 參數
- image:要處理的圖像
- kernel:核結構
- iterations:腐蝕的次數,默認是 1
-
-
開閉運算
- 開運算
- 開運算是先腐蝕后膨脹
- 作用:分離物體,消除小區域
- 特點:消除噪點,去除小的干擾塊,而不影響原來的圖像
- 閉運算
- 與開運算相反,是先膨脹后腐蝕
- 作用:是消除/閉合物體里面的孔洞
- 特點:可以填充閉合區域
cv2.morphologyEx(image, op, kernel)
- 參數
- img:要處理的圖像
- op:處理方式,開運算
cv.MORPH_OPEN
,閉運算cv.MORPH_CLOSE
- kernel:核結構
- 開運算
-
禮帽和黑帽
- 禮帽運算
- 原圖像與 “開運算“ 的結果圖之差
- 數學表達式:dst=tophat(src,element)=src?open(src,element)dst = tophat(src, element) = src - open(src, element)dst=tophat(src,element)=src?open(src,element)
- 作用:
- 用來分離比鄰近點亮一些的斑塊
- 當一幅圖像具有大幅的背景的時候,而微小物品比較有規律的情況下,可以使用頂帽運算進行背景提取
- 黑帽運算
- ”閉運算“ 的結果圖與原圖像之差
- 數學表達式:dst=blackhat(src,element)=close(src,element)?srcdst = blackhat(src, element) = close(src, element) - srcdst=blackhat(src,element)=close(src,element)?src
- 作用:用來分離比鄰近點暗一些的斑塊
cv2.morphologyEx(image, op, kernel)
- 參數
-
image:要處理的圖像
-
op:處理方式
參數 功能 cv.MORPH_CLOSE 閉運算 cv.MORPH_OPEN 開運算 cv.MORPH_TOPHAT 禮帽運算 cv.MORPH_BLACKHAT 黑帽運算 -
kernel:核結構
-
- 禮帽運算
-
案例演示:morphological_operations.ipynb
1.3圖像平滑
- 圖像噪聲
- 椒鹽噪聲(脈沖噪聲)
- 是一種隨機出現的白點或者黑點,可能是亮的區域有黑色像素或是在暗的區域有白色像素(或是兩者皆有)
- 成因:影像訊號受到突如其來的強烈干擾而產生、類比數位轉換器或位元傳輸錯誤等
- 例如
- 失效的感應器導致像素值為最小值
- 飽和的感應器導致像素值為最大值
- 例如
- 高斯噪聲(正態噪聲)
- 是指噪聲密度函數服從高斯分布的一類噪聲
- 高斯隨機變量 zzz 的概率密度函數:p(z)=12πσe?(z?μ)22σ2p(z) = \frac{1}{\sqrt{2\pi}σ} e^{\frac{-(z - μ)^2}{2σ^2}}p(z)=2π?σ1?e2σ2?(z?μ)2?
- 其中,zzz 表示灰度值, 表示 zzz 的平均值或期望值,σσσ 表示 zzz 的標準差;標準差的平方 σ2σ^2σ2 稱為 zzz 的方差
- 椒鹽噪聲(脈沖噪聲)
- 濾波器
-
均值濾波
- 采用均值濾波模板對圖像噪聲進行濾除
- 令 SxyS_{xy}Sxy? 表示中心在 (x,y)(x, y)(x,y) 點,尺寸為 m×nm×nm×n 的矩形子圖像窗口的坐標
組 - 數學表達式:f^(x,y)=1mn∑(s,t)∈Sxyg(s,t)\hat{f}(x, y) = \frac{1}{mn}\sum_{(s, t) ∈ S_{xy}}g(s, t)f^?(x,y)=mn1?∑(s,t)∈Sxy??g(s,t)
- 優點:算法簡單,計算速度較快
- 缺點:去噪的同時去除了很多細節部分,將圖像變得模糊
cv2.blur(src, ksize, anchor, borderType)
- 參數
- src:輸入圖像
- ksize:卷積核的大小
- anchor:默認值 (?1,?1)(-1, -1)(?1,?1),表示核中心
- borderType:邊界類型
-
高斯濾波
- 二維高斯是構建高斯濾波器的基礎
- 概率分布函數:G(x,y)=12πσ2exp{?x2+y22σ2}G(x, y) = \frac{1}{2\piσ^2}exp\{-\frac{x^2 + y^2}{2σ^2}\}G(x,y)=2πσ21?exp{?2σ2x2+y2?}
- 高斯平滑在從圖像中去除高斯噪聲方面非常有效
- 高斯平滑的流程
- 確定權重矩陣
- 計算高斯模糊
cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
- 參數
- src:輸入圖像
- ksize:高斯卷積核的大小
- 注意:卷積核的寬度和高度都應為奇數,且可以不同
- sigmaX:水平方向的標準差
- sigmaY:垂直方向的標準差,默認值為 0,表示與 sigmaX 相同
- borderType:填充邊界類型
-
中值濾波
- 中值濾波是一種典型的非線性濾波技術,基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值
- 中值濾波對椒鹽噪聲來說尤其有用,因為它不依賴于鄰域內那些與典型值差別很大的值
cv2.medianBlur(src, ksize)
- 參數
- src:輸入圖像
- ksize:卷積核的大小
-
- 案例演示:image_smoothing.ipynb
1.4直方圖
-
灰度直方圖
-
原理
- 直方圖是對數據進行統計的一種方法,并且將統計值組織到一系列實現定義好的 bin 當中
- 其中,bin 為直方圖中經常用到的一個概念,可以譯為直條或組距,其數值是從數據中計算出的特征統計量,這些數據可以是諸如梯度、方向、色彩或任何其他特征
- 注意:直方圖是根據灰度圖進行繪制的,而不是彩色圖像
- 直方圖的一些術語和細節:
- dims:需要統計的特征數目
- bins:每個特征空間子區段的數目,可譯為直條或組距
- range:要統計特征的取值范圍
- 直方圖的意義:
- 直方圖是圖像中像素強度分布的圖形表達方式
- 它統計了每一個強度值所具有的像素個數
- 不同的圖像的直方圖可能是相同的
- 直方圖是對數據進行統計的一種方法,并且將統計值組織到一系列實現定義好的 bin 當中
-
直方圖的計算和繪制
- 使用 OpenCV 中的方法統計直方圖,并使用 matplotlib 將其繪制出來
cv2.calcHist([image], [channel], mask, [histSize], [range])
- image:原圖像,當傳入函數時應該用中括號口括起來
- channel:通道
- 如果輸入圖像是灰度圖,它的值就是[1]
- 如果是彩色圖像的話,傳入的參數可以是 [0], [1], [2] 它們分別對應著通道 B, G, R
- mask:掩模圖像
- histSize:bin 的數目
- range:像素值范圍,通常為 [0, 256]
-
-
掩膜的應用
- 掩膜是用選定的圖像、圖形或物體,對要處理的圖像進行擋,來控制圖像處理的區域
- 用途
- 提取感興趣區域
- 屏蔽作用
- 結構特征提取
- 特殊形狀圖像制作
-
直方圖均衡化
- 原理:把原始圖像的灰度直方圖從比較集中的某個灰度區間變成在更廣泛灰度范圍內的分布
- 應用:擴大圖像像素值的分布范圍,提高圖像的對比度
cv2.equalizeHist(image)
- 參數
- image:灰度圖像
-
自適應的直方圖均衡化
- 對整個圖像進行直方圖均衡化效果并不好
- 自適應的直方圖均衡化:整幅圖像被分成很多小塊,這些小塊被稱為 tiles(在 OpenCV 中 tiles 的大小默認是 8 × 8),然后再對每一個小塊分別進行直方圖均衡化,最后為了去除每一個小塊之間的邊界,再使用雙線性差值對每一小塊進行拼接
cl = cv2.createCLAHE(clipLimit, tileGridSize) result = cl.apply(image)
- createCLAHE 參數
- clipLimit:對比度限制,默認是 40
- tileGridSize:分塊的大小,默認為 8 × 8
- apply 參數
- image:灰度圖像
-
案例演示:histogram.ipynb
1.5邊緣檢測
-
概述
- 目的:標識數字圖像中亮度變化明顯的點
- 作用:大幅度地減少了數據量,并且剔除了可以認為不相關的信息,保留了圖像重要的結構屬性
- 邊緣檢測方法
- 基于搜索
- 通過尋找圖像一階導數中的最大值來檢測邊界,然后利用計算結果估計邊緣的局部方向,通常采用梯度的方向,并利用此方向找到局部梯度模的最大值
- 代表算法:Sobel 算子和 Scharr 算子
- 基于零穿越
- 通過尋找圖像二階導數零穿越來尋找邊界
- 代表算法:Laplacian 算子
- 基于搜索
-
Sobel 算子
- Sobel 邊緣檢測算法比較簡單,實際應用中效率比 Canny 效率更高,但是邊緣不如Canny 檢測的準確
- 注意:當內核大小為 3 時,Sobel 內核可能產生比較明顯的誤差,為解決這一問題,我們使用 Scharr 函數,但該函數僅作用于大小為 3 的內核
- Scharr 函數該函數的運算與 Sobel 函數一樣快,但結果卻更加精確
cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
- 參數
- src:傳入的圖像
- ddepth:圖像的深度
- dx 和 dy:指求導的階數,0 表示這個方向上沒有求導,取值為0、1
- ksize:是 Sobel 算子的大小,即卷積核的大小,必須為奇數 1、3、5、7,默認為 3
- 注意:如果 ksize=-1,就演變成為 3 × 3 的 Scharr 算子
- scale:縮放導數的比例常數,默認情況為沒有伸縮系數
- borderType:圖像邊界的模式,默認值為 cv2.BORDER_DEFAULT
Scale_abs = cv2.convertScaleAbs(x) # 格式轉換 result = cv2.addWeighted(src1, alpha, src2, beta) # 圖像混合
-
Laplacian 算子
- Laplacian 是利用二階導數來檢測邊緣
cv2.Laplacian(src, ddepth, ksize)
- 參數
- src:需要處理的圖像
- ddepth:圖像的深度,-1 表示采用的是原圖像相同的深度,目標圖像的深度必須大于等于原圖像的深度
- ksize:算子的大小,即卷積核的大小,必須為 1, 3, 5, 7
-
Canny 邊緣檢測
- Canny 邊緣檢測算法是一種非常流行的邊緣檢測算法,是 John F. Canny 于 1986 年提出的,被認為是最優的邊緣檢測算法
- 原理
- 噪聲去除:高斯濾波
- 計算圖像梯度:sobel 算子,計算梯度大小和方向
- 非極大值抑制:利用梯度方向像素來判斷當前像素是否為邊界點
- 滯后閾值:設置兩個閾值,確定最終的邊界
cv2.Canny(image, threshold1, threshold2)
- 參數
- image:灰度圖
- threshold1:minval,較小的閾值將間斷的邊緣連接起來
- threshold2:maxval,較大的閾值檢測圖像中明顯的邊緣
-
案例演示:edge_detection.ipynb
1.6模板匹配
- 在給定的圖片中查找和模板最相似的區域,該算法的輸入包括模板和圖片,整個任務的思路就是按照滑窗的思路不斷的移動模板圖片,計算其與圖像中對應區域的匹配度,最終將匹配度最高的區域選擇為最終的結果
cv2.matchTemplate(image, template, method)
- 參數
- img:要進行模板匹配的圖像
- template:模板
- method:實現模板匹配的算法
- 平方差匹配(
cv.TM_SQDIFF
):利用模板與圖像之間的平方差進行匹配,最好的匹配是 0,匹配越差,匹配的值越大 - 相關匹配(
cv.TM_CCORR
):利用模板與圖像間的乘法進行匹配,數值越大表示匹配程度較高,越小表示匹配效果差 - 利用相關系數匹配(
cv.TM_CCOEFF
):利用模板與圖像間的相關系數匹配,1 表示完美的匹配,-1 表示最差的匹配
- 平方差匹配(
- 完成匹配
- 使用
cv.minMaxLoc
方法查找最大值所在的位置即可 - 如果使用平方差作為比較方法,則最小值位置是最佳匹配位置
- 使用
- 案例演示:template_matching.ipynb
1.7霍夫變換
-
霍夫變換常用來提取圖像中的直線和圓等幾何形狀
-
霍夫線檢測
cv2.HoughLines(image, rho, theta, threshold)
- 參數
- img:檢測的圖像,要求是二值化的圖像,所以在調用霍夫變換之前首先要進行二值化,或者進行 Canny 邊緣檢測
- rho:ρρρ 的精確度
- theta:θθθ 的精確度
- threshold:閾值,只有累加器中的值高于該閾值時才被認為是直線
- 參數
-
霍夫圓檢測
- OpenCV 中使用霍夫梯度法進行圓形的檢測
- 霍夫梯度法將霍夫圓檢測范圍兩個階段
- 檢測圓心
- 利用圓心推導出圓半徑
cv2.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:所檢測到的圓半徑的最大值
-
案例演示:hough_transform.ipynb