計算機視覺之多模板匹配

簡介

計算機視覺第一課opencv(四)保姆級教學

之前說過模糊匹配只是對于單個目標進行匹配,今天我們就來學習一下如何對多個目標進行匹配

一、多目標匹配

????????對于這個圖片我們要匹配下面那個箭頭,我們可以發現圖中是有兩個位置相同的箭頭,之前我們說的模糊匹配是尋找匹配值最大的,那兩個怎么尋找呢?

1.基本步驟


1.圖像準備
????????模板圖像:需要被匹配的目標圖像,通常是一個較小的圖像塊。
????????輸入圖像:在其中進行搜索以找到與模板圖像相似的多個區域的圖像。
2.圖像預處理
????????轉換為灰度圖像:在進行模板匹配之前,通常需要將輸入圖像和模板圖像轉換為灰度圖像,因為灰度圖像中的像素值僅表示亮度,不受顏色影響,更適合進行匹配。
????????降噪和增強:根據需要,可以對圖像進行降噪處理以提高匹配準確性,或進行增強處理以突出目標特征。
3.執行模板匹配
????????使用模板匹配算法(如OpenCV中的cv2.matchTemplate()函數)在輸入圖像中搜索與模板圖像相似的區域。
模板匹配算法會生成一個結果圖像,其中每個像素的值表示該位置與模板圖像的匹配程度。
4.定位匹配區域
????????使用cv2.minMaxLoc()等函數在結果圖像中找到匹配度最高的區域(或多個區域,如果設置了適當的閾值)。
根據匹配位置在原圖中繪制矩形框或其他標記,以指示匹配到的目標。
5.處理多個匹配
????????如果需要匹配多個目標,并且這些目標在圖像中可能以不同的尺寸、方向或旋轉角度出現,則可能需要使用更復雜的算法,如尺度不變特征變換(SIFT)、加速穩健特征(SURF)或ORB等。
????????對于簡單的多目標匹配,可以通過設置較低的匹配閾值來找到多個匹配區域,并分別處理它們。
6.優化和驗證
????????根據需要調整模板匹配算法的參數(如匹配方法、閾值等),以優化匹配結果。
????????對匹配結果進行驗證,確保它們確實是所需的目標,并排除誤匹配。

# 導入必要的庫:cv2用于圖像處理,numpy用于數值計算
import cv2
import numpy as np# 讀取原始彩色圖像(默認讀取為BGR格式,而非RGB)
img_rgb = cv2.imread('beijing.jpg')
# 將彩色圖像轉為灰度圖:模板匹配通常在單通道灰度圖上進行,減少計算量和干擾
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
# 讀取模板圖像:flags=0表示以灰度模式讀取(直接得到單通道圖像)
template = cv2.imread('jiantou.jpg', flags=0)# 獲取模板的高和寬:shape返回(高, 寬, 通道數),[:2]取前兩個值(高h和寬w)
h, w = template.shape[:2]# 執行模板匹配:在灰度圖上滑動模板,計算每個位置的匹配度
# 參數說明:
# - img_gray:待匹配的灰度圖像(大圖像)
# - template:模板圖像(小圖像)
# - cv2.TM_CCOEFF_NORMED:匹配方法(歸一化相關系數匹配)
# 返回值res:是一個矩陣,每個元素表示模板在對應位置的匹配度(范圍[-1,1],1為完美匹配)
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)# 設定匹配閾值:只有匹配度≥0.9的區域才被認為是有效匹配(過濾低匹配度的干擾)
threshold = 0.9# 獲取所有符合閾值的匹配點坐標:
# np.where(res >= threshold)返回滿足條件的索引,格式為(行坐標數組, 列坐標數組)
# 例如:(array([5, 10]), array([3, 7]))表示有兩個匹配點,坐標為(5,3)和(10,7)
loc = np.where(res >= threshold)# 遍歷所有匹配點,在原圖上繪制矩形框標記
# zip(*loc[::-1])的作用:將坐標從(行,列)轉為(列,行)(OpenCV中坐標是(x,y)即列在前,行在后)
for pt in zip(*loc[::-1]):# 繪制矩形:# - img_rgb:要繪制的圖像(原始彩色圖,方便直觀查看)# - pt:矩形左上角坐標(x,y)# - (pt[0]+w, pt[1]+h):矩形右下角坐標(左上角x+模板寬,左上角y+模板高)# - color=(0,0,255):矩形顏色(BGR格式,這里是紅色)# - thickness=1:矩形線寬cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), color=(0, 0, 255), thickness=1)# 顯示標記后的圖像:第一個參數是窗口名稱(空字符串表示默認窗口),第二個參數是圖像
cv2.imshow('', img_rgb)
# 等待用戶按鍵輸入:0表示無限等待(直到按下任意鍵關閉窗口)
cv2.waitKey(0)

局限性
????????只能匹配與模板方向、大小完全一致的目標。如果目標在圖像中旋轉了(比如箭頭方向變了),則無法檢測到。那我們就繼續探索一下如何去匹配旋轉的目標

二、圖像旋轉

????????為了解決上述局限性,需要先掌握如何旋轉圖像。這部分提供了兩種旋轉方法,用于后續生成不同角度的模板。

import cv2
import numpy as np# 方法一:使用numpy的rot90函數旋轉(按90度倍數旋轉)
img = cv2.imread('../kele.png')  # 讀取圖像(以彩色模式)
# np.rot90參數說明:
# - 第一個參數:要旋轉的圖像
# - k:旋轉次數(每次90度),k=1表示逆時針轉90度,k=-1(或3)表示順時針轉90度
rotated_image1 = np.rot90(img, k=-1)  # 順時針旋轉90度
rotated_image2 = np.rot90(img, k=1)   # 逆時針旋轉90度# 顯示原圖和旋轉后的圖像
cv2.imshow('yuantu', img)  # 原圖窗口
cv2.imshow('rotated_image1', rotated_image1)  # 順時針90度窗口
cv2.imshow('rotated_image2', rotated_image2)  # 逆時針90度窗口
cv2.waitKey(0)  # 等待按鍵
cv2.destroyAllWindows()  # 關閉所有窗口,釋放資源# 方法二:使用OpenCV的rotate函數旋轉(更直觀,支持固定角度)
rotated_image = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)  # 順時針90度
rotated_image1 = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)  # 逆時針90度
rotated_image2 = cv2.rotate(img, cv2.ROTATE_180)  # 旋轉180度# 顯示旋轉結果
cv2.imshow('shun90', rotated_image)    # 順時針90度窗口
cv2.imshow('ni90', rotated_image1)     # 逆時針90度窗口
cv2.imshow('180', rotated_image2)      # 180度窗口
cv2.waitKey(0)  # 等待按鍵

兩種方法對比

  • np.rot90:通過旋轉次數控制(k=1/2/3/-1),適合 90 度倍數的旋轉,但不夠直觀。
  • cv2.rotate:直接通過枚舉值指定旋轉方向(如ROTATE_90_CLOCKWISE),可讀性更強,推薦使用。

三、支持旋轉角度的模板匹配

結合多目標匹配與旋轉的知識,我們就可以結合一下實現對旋轉角度的模板匹配

import cv2
import numpy as np# 讀取原始圖像和模板
img_rgb = cv2.imread('beijing.jpg')  # 原始彩色圖像
template = cv2.imread('jiantou.jpg', 0)  # 模板圖像(以灰度模式讀取)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)  # 原始圖像轉灰度# 方法二(cv2.rotate)生成不同角度的模板(方法一被注釋,原理相同)
template_rot90_clockwise_cv = cv2.rotate(template, cv2.ROTATE_90_CLOCKWISE)  # 順時針90度
template_rot90_counterclockwise_cv = cv2.rotate(template, cv2.ROTATE_90_COUNTERCLOCKWISE)  # 逆時針90度
template_rot180_cv = cv2.rotate(template, cv2.ROTATE_180)  # 180度# 定義模板列表:包含原始模板和所有旋轉后的模板(需要檢測的角度)
templates = [template,  # 原始模板(0度)template_rot90_clockwise_cv,  # 順時針90度template_rot90_counterclockwise_cv,  # 逆時針90度template_rot180_cv  # 180度
]# 設定匹配閾值:從0.9降低到0.8
# 原因:旋轉后的模板與目標的匹配度可能略低(邊緣、細節可能有偏差),降低閾值避免漏檢
threshold = 0.8# 遍歷每個模板,分別進行匹配
for temp in templates:h, w = temp.shape[:2]  # 獲取當前模板的高和寬(不同旋轉角度的模板尺寸可能變化)# 對當前模板執行匹配res = cv2.matchTemplate(img_gray, temp, cv2.TM_CCOEFF_NORMED)# 獲取符合閾值的匹配點坐標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('Result', img_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()  # 關閉窗口,釋放資源

核心邏輯
通過生成模板的多個旋轉版本(0°、90° 順時針、90° 逆時針、180°),分別與原始圖像匹配,從而覆蓋目標可能的旋轉角度。這樣即使目標在圖像中旋轉了,也能被檢測到。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921792.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921792.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921792.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

封裝日期選擇器組件,帶有上周,下周按鈕

ui圖組件代碼如下&#xff1a; <template><div><el-date-pickerv-model"dateRange"type"daterange"align"right"size"mini":editable"false"unlink-panelsrange-separator"至"start-placeholder&q…

基于SpringBoot+MYSQL開發的AI智能大數據醫療診斷平臺

角色&#xff1a; 管理員、醫生、居民 技術&#xff1a; SpringBoot、MyBatis、MySQL、Shiro、Beetl、Swagger、jQuery、Bootstrap 核心功能&#xff1a; 這是一個基于SpringBoot的社區醫療管理平臺&#xff0c;旨在為管理員提供用戶、角色、部門、菜單、日志等系統管理功能&am…

【MFC 小白日記】對話框編輯器里“原型圖像”到底要不要勾?3 分鐘看懂!

摘要&#xff1a;本文解析了MFC中Picture Control的"原型圖像(Prototype Image)"屬性的真實作用。該屬性僅在設計時提供可視化的占位圖預覽&#xff0c;方便UI布局&#xff0c;運行時不會影響程序表現。文章通過對比實驗驗證&#xff0c;勾選后會在對話框編輯器中顯示…

微信開放平臺第三方平臺,可以管理多個微信小程序

大家好&#xff0c;我是小悟。 這個系統可以幫助服務商更好地管理多個商家小程序&#xff0c;無需管理多個商家小程序的賬號密碼或者appId和secret&#xff0c;大大提升效率。 不需要頻繁登錄小程序后臺就能完成上傳代碼、認證、備案、提交代碼審核、發布小程序等操作。 這里錄…

Java全棧學習筆記32

-- drop table t_stu;-- unique 唯一約束的列允許為null-- 如果在之后的操作中。需要某列必須為key&#xff0c;才能做一些操作的情況下。也可以使用唯一約束代替主鍵約束-- create table t_stu(-- studId int,-- tel varchar(11) unique,-- sex varchar(1),-- addr va…

linux升級系統,重啟出現Minimal BASH-like line editingis supported

文章目錄一.問題背景二.解決步驟2.1確認系統分區2.2手動引導2.3 重建grub引導2.4 還原軟件包 一.問題背景 閑來無事&#xff0c;把ubuntu25.04通過sudo do-release-upgrade命令升級到了ubuntu25.10.在升級的過程會出現以下問題 1.自動替換flatpak程序為snap2.請求是否清除舊依賴…

type(類型別名)和 interface的區別和最佳實踐

核心結論在大多數情況下&#xff0c;它們可以互換使用&#xff0c;都能描述對象的結構。它們的區別更多在于設計和擴展能力上。主要區別總結表特性interface (接口)type (類型別名)擴展方式使用 extends 繼承interface A extends B {}使用 & 交叉類型type A B & C合并…

vscode中使用git、githup的基操

一、git提交 配置賬戶密碼 查看用戶信息 git config --global user.name # 查看用戶名 git config --global user.email # 查看郵箱賬戶配置 # 設置全局用戶名和郵箱 git config --global user.name "你的用戶名" git config --global user.email "你的郵箱&q…

jsBridge接入流程

import deviceInfo from ./deviceInfo import { setRefreshToken } from ./token// 設備判斷 const u navigator.userAgent export const isAndroid u.indexOf(Android) > -1 || u.indexOf(Adr) > -1 export const isIOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/)…

【C++】19. 封裝紅?樹實現set和map

文章目錄一、源碼及框架分析二、模擬實現map和set1、insert的實現2、iterator的實現3、map?持[ ]4、模擬實現的完整源代碼1&#xff09;RBTree.h2&#xff09;Myset.h3&#xff09;Mymap.h4&#xff09;Test.cpp一、源碼及框架分析 SGI-STL30版本源代碼&#xff0c;map和set的…

面試不會問題

1. 什么是表鎖&#xff1f;什么是行鎖&#xff1f;什么情況下會使用表鎖&#xff1f;InnoDB引擎通過“索引”實現行鎖&#xff08;鎖定滿足條件的行&#xff09;&#xff0c;但如果操作無法通過索引定位行&#xff0c;會導致行鎖失效&#xff0c;進而升級為表鎖。常見的表現為&…

達夢數據庫-用戶,權限,角色

達夢數據庫-用戶,權限,角色 在達夢數據庫(DM8)中,用戶(User)、權限(Privilege)和角色(Role) 是數據庫安全體系的核心組成部分,用于控制誰可以訪問數據庫、能訪問哪些對象以及能執行哪些操作。 下面為你提供一份全面、詳細、結構化的說明,幫助你深入理解達夢數據…

uniapp原生插件 TCP Socket 使用文檔

uniapp原生插件 TCP Socket 使用文檔 試了插件市場幾個TCP Socket插件都不能實現監聽服務器主動斷開&#xff0c;于是閑來無事就開發了一款&#xff0c;本插件是一個基于 Netty 實現的 TCP 通信模塊&#xff0c;用于在 UniApp 插件中提供 TCP 連接、數據發送和連接管理功能。以…

VM中CentOS 7密碼重置

重啟虛擬機點擊e進入內核處理向下劃找到UTF-8在后面輸入rd.breakctrl X進入單用戶模式mount -o remount,rw/sysroot進行掛盤 chroot /sysroot訪問系統&#xff0c;并使用passwd修改root密碼 出現亂碼 輸入LANGen touch /.autorelabel 保存配置 exit exit退出等待系統重新打開&…

車規級MOS管AEC-Q101認證的關鍵參數解讀與失效模式-深圳阿賽姆

摘要本文拆解AEC-Q101認證的7大關鍵測試項&#xff08;UIS/溫度循環/THB等&#xff09;&#xff0c;結合M120N06JC等型號實測數據&#xff0c;解析雪崩失效/柵氧擊穿/綁定線脫落等故障機理&#xff0c;附選型核查表一、AEC-Q101認證核心測試項與參數解讀1.1 非鉗位電感開關測試…

嵌入式鐵頭山羊stm32-ADC實現軟件觸發的常規序列的單通道轉換-Day25

目錄 一、實驗目的 二、電路連接 三、實驗執行&#xff08;五步&#xff09; 1.初始化ADC的IO引腳 2.配置ADC的時鐘&#xff0c;注意要小于14MHz 3.根據ADC的編程接口 實現初始化ADC的基本參數 4.配置常規序列并閉合觸發輸入開關 5.閉合總開關、啟動并讀取轉換結果 四…

多模態模型出現“幻覺”,描述了表格中不存在的內容,如何修正?

在日常工作中&#xff0c;多模態模型的 “幻覺” 問題已成為影響效率的關鍵痛點 —— 當我們需要模型基于文檔生成建議性內容&#xff08;如行業報告分析、論文數據解讀等&#xff09;時&#xff0c;模型常因無法準確理解文檔信息&#xff0c;輸出包含 “虛構內容” 的結果&…

Java AI 智能問數:Function調用版如何重塑企業數據決策

Java AI 智能問數&#xff1a;Function調用版如何重塑企業數據決策 在數字化轉型浪潮中&#xff0c;企業一把手常面臨數據查詢的痛點&#xff1a;分析師需編寫復雜SQL&#xff0c;業務人員依賴IT支持&#xff0c;決策鏈條冗長。傳統方法效率低下&#xff0c;而自然語言處理&…

AI-調查研究-74-具身智能 機器人學習新突破:元學習與仿真到現實遷移的挑戰與機遇

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持續更新中&#xff01;&#xff08;長期更新&#xff09; AI煉丹日志-31- 千呼萬喚始出來 GPT-5 發布&#xff01;“快的…

勞務員的就業前景如何?

勞務員的就業前景整體較為樂觀&#xff0c;受到行業需求、政策支持等因素的積極影響&#xff0c;同時也面臨著一些挑戰。以下是具體分析&#xff1a;1.就業優勢行業需求穩定&#xff1a;建筑行業作為國民經濟的支柱產業&#xff0c;持續發展使得對勞務員的需求較為穩定。無論是…