目錄
一、模板匹配
模板匹配原理
1、單模板之間的匹配
(1)讀取并顯示待匹配的圖片和模板圖片
(2)模板匹配并繪制匹配位置的外接矩形
(3)顯示最終的效果?
2、模板與多個對象匹配,僅匹配當前的模板
(1)讀取并顯示待匹配的圖片和模板灰度圖片
(2)?模板匹配
(3)設置閾值
3、匹配相同模板的全角度
(1)讀取并顯示待匹配的圖片和模板灰度圖片,旋轉模板得到所有的能匹配到的模板。
(2)模板匹配并繪制外接矩形
二、打包與np.where()函數
1、np.where()函數
(1) 作為條件選擇器(類似三元表達式)
(2) 作為條件索引獲取器(省略 x 和 y)
2、打包與解包
(1)打包
(2)解包
3、反轉列表
三、圖像的旋轉
1、使用numpy方法實現旋轉
(1)順時針旋轉90度
(2)逆時針旋轉90度
2、使用opencv的方法實現圖像旋轉
(1)順時針旋轉90度
(2)逆時針旋轉90度
(3)旋轉180度
一、模板匹配
模板匹配是一種用于查找與模板圖像(補丁)匹配(相似)的圖像區域的技術。
為了識別匹配區域,我們必須通過滑動來將模板圖像與源圖像進行比較:
?????????一次移動一個像素(從左到右,從上到下)。在每個位置,都會計算一個度量(度量計算公式),以便它表示該位置的匹配“好”或“壞”程度
模板匹配原理
?
匹配原理:模板從圖片的左上角逐一進行匹配,針對每一個匹配位置(位置坐標是模板左上角坐標),都會根據matchTemplate()函數設置的計算方法得到一個對應的得分值,不同的匹配方法數值大小的效果是不同的,找到最優的匹配結果返回。
函數API:
????????cv2.matchTemplate(image, templ, method, result=None, mask=None)
????????????????image:待搜索圖像
????????????????templ:模板圖像
????????????????method:計算匹配程度的方法,可以有:
????????? TM_SQDIFF 平方差匹配法:該方法采用平方差來進行匹配;匹配越好,值越小;匹配越差,值越大。
????????? TM_CCORR 相關匹配法:該方法采用乘法操作;數值越大表明匹配程度越好。
? ????????TM_CCOEFF 相關系數匹配法:數值越大表明匹配程度越好。
????????? TM_SQDIFF_NORMED 歸一化平方差匹配法,匹配越好,值越小;匹配越差,值越大。
????????? TM_CCORR_NORMED 歸一化相關匹配法,數值越大表明匹配程度越好。
? ????????TM_CCOEFF_NORMED 歸一化相關系數匹配法,數值越大表明匹配程度越好。
????????返回匹配結果的矩陣,其中每個元素表示該位置與模板的匹配程度
如果想了解matchTemplate的method的具體計算方法和matchTemplate的基礎知識,可以前往OpenCv的官網查看更詳細的知識OpenCV: Template Matching。
1、單模板之間的匹配
可樂模板匹配代碼
(1)讀取并顯示待匹配的圖片和模板圖片
kele = cv2.imread('kele.png')
template = cv2.imread('template.png')
cv2.imshow('kele',kele)
cv2.imshow('template',template)
cv2.waitKey(0)
(2)模板匹配并繪制匹配位置的外接矩形
cv2.minMaxLoc()可以獲取矩陣中的最小值和最大值,以及最小值的索引號和最大值的索引號
h, w = template.shape[:2] #獲取模板圖片的高和寬res = cv2.matchTemplate(kele, template, cv2.TM_CCOEFF_NORMED) #返回匹配結果的矩陣,其中每個元素表示該位置與模板的匹配程度
# cv2.minMaxLoc可以獲取矩陣中的最小值和最大值,以及最小值的索引號和最大值的索引號
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 最小值、最大值、最小值位置、最大值位置
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h) #獲得圖片右下角坐標
kele_template = cv2.rectangle(kele, top_left, bottom_right, (0, 255, 0), 2) # 繪制矩形
(3)顯示最終的效果?
cv2.imshow('kele_template', kele_template)
cv2.waitKey(0)
2、模板與多個對象匹配,僅匹配當前的模板
?模板:
待匹配對象:?
(1)讀取并顯示待匹配的圖片和模板灰度圖片
import cv2
import numpy as np
#(這里用到了兩種方法來將彩色圖片轉化為灰度圖)img_rgb=cv2.imread('../data/tuall.jpg')
img_gray=cv2.cvtColor(img_rgb,cv2.COLOR_BGRA2GRAY)
tuone=cv2.imread('../data/tuone.jpg',0)
(2)?模板匹配
h,w=tuone.shape[:2]
# 使用模板匹配方法進行模板匹配
res=cv2.matchTemplate(img_gray,tuone,cv2.TM_CCOEFF_NORMED)
(3)設置閾值
np.where()函數:過濾出符合條件的數值。
閾值設置原理:
在進行多對象匹配時,常常要設置閾值保證能夠完全框選到對象,當閾值設置為0.9時,所有滿足大于0.9的外接矩形都會被繪制出來,如果這個閾值數據設置的更小,那么符合條件的位置就越多,表現在圖上的特征就是有更多的框,框的線更粗。
反轉:
loc的數據,下面表示的是行和列,但是在opencv中行時用y表示,列時用x表示,所以按照x,y表示的話,下面給出的數據是,(y,x),繪制矩形時應該是x和y,所以這里要做反轉。
# 設置匹配閾值
threshold=0.9
#獲取匹配結果中所有符合閾值的點的坐標
loc=np.where(res>=threshold) #如果得分大于閾值,返回大于閾值的索引for pt in zip(*loc[::-1]): #反轉打包#在原圖上繪制矩形框cv2.rectangle(img_rgb,pt,(pt[0]+w,pt[1]+h),(0,255,0),1)cv2.imshow('1',img_rgb)
cv2.waitKey(0)
3、匹配相同模板的全角度
待匹配的圖像上有很多個可以匹配上的圖,但是匹配的模板需要旋轉才能匹配上
將圖片上的所有的圖像模板都匹配上
(1)讀取并顯示待匹配的圖片和模板灰度圖片,旋轉模板得到所有的能匹配到的模板。
import cv2
import numpy as npimg_rgb=cv2.imread('../data/tuall.jpg')
img_gray=cv2.cvtColor(img_rgb,cv2.COLOR_BGRA2GRAY)tuone=cv2.imread('../data/tuone.jpg',0)
tuone1=cv2.rotate(tuone,cv2.ROTATE_90_CLOCKWISE) #順時針旋轉90度
tuone2=cv2.rotate(tuone,cv2.ROTATE_90_COUNTERCLOCKWISE) #逆時針旋轉90度
tuone3=cv2.rotate(tuone,cv2.ROTATE_180) #旋轉180度
tuones=[tuone,tuone1,tuone2,tuone3]
(2)模板匹配并繪制外接矩形
h,w=tuone.shape[:2]
# 使用模板匹配方法進行模板匹配
for tu in tuones:res=cv2.matchTemplate(img_gray,tu,cv2.TM_CCOEFF_NORMED)# 設置匹配閾值threshold=0.9#獲取匹配結果中所有符合閾值的點的坐標loc=np.where(res>=threshold)for pt in zip(*loc[::-1]):#在原圖上繪制矩形框cv2.rectangle(img_rgb,pt,(pt[0]+w,pt[1]+h),(0,0,255),1)cv2.imshow('1',img_rgb)
cv2.waitKey(0)
二、打包與np.where()函數
1、np.where()函數
(1) 作為條件選擇器(類似三元表達式)
語法
np.where(condition, x=None, y=None)
condition
:布爾數組或表達式,用于指定條件。x, y
(可選):當條件為?True
?時返回?x
?對應位置的元素,為?False
?時返回?y
?對應位置的元素。- 返回值:形狀與?
condition
?相同的數組,元素來自?x
?或?y
。
示例:
import numpy as npa = np.array([1, 2, 3, 4, 5])
# 將大于 3 的元素替換為 10,否則保持原值
result = np.where(a > 3, 10, a)
print(result) # 輸出: [ 1 2 3 10 10]# 更復雜的條件(結合邏輯運算)
b = np.array([10, 20, 30, 40])
condition = (a > 2) & (b < 35) # 同時滿足兩個條件
result = np.where(condition, a * 2, b // 2)
print(result) # 輸出: [ 2 4 6 20](僅前3個元素滿足條件,最后一個不滿足,取 b//2=20)
(2) 作為條件索引獲取器(省略 x 和 y)
??語法
np.where(condition)
- 作用:返回滿足條件?
condition
?的元素的索引(以元組形式表示,每個元素對應數組的一個維度)。 - 返回值:元組?
(ind1, ind2, ..., indn)
,其中?indi
?是第?i
?維滿足條件的索引數組。
示例:
a = np.array([1, 2, 3, 4, 4, 5])
# 獲取值為 4 的元素的索引
indices = np.where(a == 4)
print(indices) # 輸出: (array([3, 4]),)(一維數組,索引為 3 和 4)# 二維數組示例
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
condition = b > 5
indices = np.where(condition)
print(indices) # 輸出: (array([1, 2, 2]), array([2, 0, 1, 2])),對應行和列的索引
2、打包與解包
(1)打包
a=[1,2,3]
b=[4,5,6]# 使用zip將他們按位置進行配對
zipped=zip(a,b)
print(list(zipped))
# 輸出:[(1,4),(2,5),(3,6)]
(2)解包
????????zip(*iterables)將多個可迭代對象(列表、元組)進行解壓操作
# 假設我們已經有了一個打包好的zip對象
zipped=zip(a,b)# #使用*運算符解包,得到轉置的結果
unzipped=zip(*zipped)
loc = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]# 1. loc[::-1]:反轉列表
reversed_loc = loc[::-1]
print(reversed_loc) # 輸出: [[7, 8, 9], [4, 5, 6], [1, 2, 3]]# 2. *reversed_loc:解包列表
# 此時相當于 zip([7, 8, 9], [4, 5, 6], [1, 2, 3])# 3. zip(*reversed_loc):使用 zip 函數進行打包
zipped = zip(*reversed_loc)
for pt in zipped:print(pt)
# 輸出:
# (7, 4, 1)
# (8, 5, 2)
# (9, 6, 3)
?
3、反轉列表
假設?loc = [(1, 2), (3, 4), (5, 6)]
(3 個坐標點):
- 反轉列表:
loc[::-1] = [(5, 6), (3, 4), (1, 2)]
三、圖像的旋轉
1、使用numpy方法實現旋轉
讀取圖片并重設圖片大小
import cv2
import numpy as npimg=cv2.imread("../data/kele.png")
img=cv2.resize(img,dsize=None,fx=0.5,fy=0.5)cv2.imshow('yuantu',img)
(1)順時針旋轉90度
# 旋轉90度,k=-1,表示順時針旋轉90度
rotated_image1=np.rot90(img,k=-1)
cv2.imshow('totated_image1',rotated_image1)
(2)逆時針旋轉90度
# 旋轉90度,k=1,表示逆時針旋轉90度
rotated_image2=np.rot90(img,k=1)
cv2.imshow('retated_image',rotated_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()
2、使用opencv的方法實現圖像旋轉
(1)順時針旋轉90度
rotated_image=cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE) #順時針旋轉90
cv2.imshow('shun90',img)
(2)逆時針旋轉90度
rotated_image1=cv2.rotate(img,cv2.ROTATE_90_COUNTERCLOCKWISE) #逆時針旋轉90度
cv2.imshow('ni90',rotated_image1)
(3)旋轉180度
rotated_image2=cv2.rotate(img,cv2.ROTATE_180) #旋轉180度
cv2.imshow('180',rotated_image2)
cv2.waitKey(0)