9:OpenCV—模板匹配

模版匹配

1、模板匹配概念

  模板匹配是一項在一副圖像中尋找與另一幅模板圖像最匹配(相似)部分的技術。模板匹配不是基于直方圖的,而是通過在輸入圖像上滑動圖像塊(模板)同時對比相似度,來對模板和輸入圖像進行匹配的一種方法。

應用:

  (1)目標查找定位

  (2)運動物體跟蹤

2、模板匹配 — matchTemplate()

1 CV_EXPORTS_W void matchTemplate(InputArray image, InputArray temp1, OutputArray result, int method);

  image:待搜索圖像(大圖)

  temp1:搜索模板,需和原圖一樣數據類型且尺寸大小不能大于源圖像

  reuslt:比較結果的映射圖像,其必須為單通道的,32位浮點型圖像,如果原圖(待搜索圖像)尺寸為W*H,二temp1的尺寸為w*h,則result的尺寸一定是(W-w+1)*(H-h+1)

  method:指定的匹配方法,有如下六種:


CV_TM_SQDIFF --- 平方差匹配法(最好匹配0)
CV_TM_SQDIFF_NORMED --- 歸一化平方差匹配法(最好匹配0)
CV_TM_CCORR --- 相關匹配法(最壞匹配0)
CV_TM_CCORR_NORMED ---歸一化相關匹配法(最壞匹配0)
CV_TM_CCOEFF --- 系數匹配法(最好匹配1)
CV_TM_CCOEFF_NORMED --- 歸一化系數匹配法(最好匹配1)

2、矩陣歸一化 — normalize()


void normalize(InputArray src,OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )

  src:輸入源圖像,Mat類型

  dst:輸出結果圖像,需要和原圖一樣的尺寸和類型

  alpha:歸一化后的最小值,默認為1

  beta:歸一化后的最大值,默認為0

  norm_type:歸一化類型,可選:NORM_INF, NORM_L1, NORM_L2(默認)等

  dtype:默認值為-1,此參數為負值時,輸出矩陣和src有同樣的類型

  mask:可選的掩碼操作

normallize()函數的作用是進行矩陣歸一化。

3、尋找最值 — minMaxLoc()


1void minMaxLoc(InputArray src, CV_OUT double* minVal, CV_OUT double* maxVal = 0, CV_OUT Point* minLoc=0, CV_OUT Point* maxLoc=0, InputArray mask=noArray());

  src:輸入源圖像,單通道圖像

  minVal:返回最小值的指針,若無需返回,則置為0

  maxVal:返回最大值的指針,若無需返回,則置為0

  minLoc:返回最小位置的指針,若無需返回,則置為0

  maxLoc:返回最大位置的指針,若無需返回,則置為0

  mask:可選的掩碼操作

minMaxLoc()函數的作用是在數組中找到全局最小值和最大值

4、單模板案例


//模板匹配
#include "opencv2/opencv.hpp"
#include <iostream>using namespace std;
using namespace cv;int main()
{Mat temp=imread("mu.jpg");Mat src=imread("1.jpg");Mat dst=src.clone();imshow("temp",temp);int width=src.cols-temp.cols+1;//result寬度int height=src.rows-temp.rows+1;//result高度Mat result(height,width,CV_32FC1);//創建結果映射圖像//matchTemplate(srcImg, templateImg, resultImg, CV_TM_SQDIFF); //平方差匹配法(最好匹配0)//matchTemplate(srcImg, templateImg, resultImg, CV_TM_SQDIFF_NORMED); //歸一化平方差匹配法(最好匹配0)//matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCORR); //相關匹配法(最壞匹配0)//matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCORR_NORMED); //歸一化相關匹配法(最壞匹配0)//matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCOEFF); //系數匹配法(最好匹配1)matchTemplate(src,temp,result,CV_TM_CCOEFF_NORMED);//化相關系數匹配,最佳值1imshow("result",result);normalize(result,result,0,1,NORM_MINMAX,-1);//歸一化到0-1范圍double minValue,maxValue;Point minLoc,maxLoc;minMaxLoc(result,&minValue,&maxValue,&minLoc,&maxLoc);cout<<"minValue="<<minValue<<endl;cout<<"maxValue="<<maxValue<<endl;rectangle(dst,maxLoc,Point(maxLoc.x+temp.cols,maxLoc.y+temp.rows),Scalar(0,255,0),2,8);imshow("dst",dst);waitKey(0);return 0;
}

注意:result的長寬正好是(原圖-模板圖)的長寬,result圖中白亮程度表示匹配程度

5、視頻模板匹配


//視頻模板匹配
#include "opencv2/opencv.hpp"
#include <iostream>using namespace std;
using namespace cv;int main()
{Mat frame,resultImg;Mat templateImg = imread("green.jpg");VideoCapture cap("1.mp4");if(!cap.isOpened())return;int resultImg_cols,resultImg_rows;while(1){cap>>frame;if(frame.empty())    break;Mat showImg = frame.clone();resultImg_cols = frame.cols -  templateImg.cols + 1;resultImg_rows = frame.rows -  templateImg.rows + 1;resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1);matchTemplate(frame, templateImg, resultImg, CV_TM_CCOEFF_NORMED); //歸一化相關系數匹配法(最好匹配1)normalize(resultImg, resultImg, 0, 1, NORM_MINMAX);double minValue, maxValue;Point minLoc, maxLoc;Point matchLoc;minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc);cout<<"max_value= "<<maxValue<<endl;//cout<<"min_value= "<<minValue<<endl;if(maxValue>=0.7)rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2);imshow("frame", frame);imshow("result", showImg);if(27 == waitKey(10))break;}destroyAllWindows();waitKey(0);return 0;
}

6、多模板匹配


//多模板匹配
#include "opencv2/opencv.hpp"
#include <iostream>
#include <stdio.h>using namespace std;
using namespace cv;int main()
{Mat srcImg = imread("E://src.png");Mat templateImg = imread("E://temp.png");Mat resultImg;Mat showImg = srcImg.clone();int resultImg_cols = srcImg.cols -  templateImg.cols + 1;int resultImg_rows = srcImg.rows -  templateImg.rows + 1;resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1);matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCOEFF_NORMED); //化相關系數匹配法(最好匹配1)normalize(resultImg, resultImg, 0, 1, NORM_MINMAX);Mat midImg = resultImg.clone();//多目標模板匹配---方法一/*double matchValue;int count0=0;int tempW=0, tempH=0;char matchRate[10];for(int i=0; i<resultImg_rows; i++){for(int j=0; j<resultImg_cols; j++){matchValue = resultImg.at<float>(i, j);sprintf(matchRate, "%0.2f", matchValue);if(matchValue>=0.85 && (abs(j - tempW)>5) && (abs(i - tempH)>5) ){count0++;putText(showImg, matchRate, Point(j-5, i-5), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);rectangle(showImg, Point(j, i), Point(j + templateImg.cols, i + templateImg.rows), Scalar(0, 255, 0), 2);tempW = j;tempH = i;}}}cout<<"count="<<count0<<endl;imshow("resultImg", resultImg);imshow("dst", showImg);*///多目標模板匹配---方法二double minValue, maxValue;Point minLoc, maxLoc;Point matchLoc;char matchRate[10];for(int i=0; i<100; i++){int startX = maxLoc.x - 4;int startY = maxLoc.y - 4;int endX = maxLoc.x + 4;int endY = maxLoc.y + 4;if(startX<0 || startY<0){startX = 0;startY = 0;}if(endX > resultImg.cols - 1 || endY > resultImg.rows - 1){endX = resultImg.cols - 1;endY = resultImg.rows- 1;}Mat temp = Mat::zeros(endX - startX, endY - startY, CV_32FC1);//Mat ROI = resultImg(Rect(Point(startX, startY), temp.cols, temp.rows));temp.copyTo(resultImg(Rect(startX, startY, temp.cols, temp.rows)));minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc);if(maxValue<0.8)    break;cout<<"max_value= "<<maxValue<<endl;sprintf(matchRate, "%0.2f", maxValue);putText(showImg, matchRate, Point(maxLoc.x - 5, maxLoc.y - 5), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2);}imshow("midImg", midImg);imshow("resultImg", resultImg);imshow("dst", showImg);waitKey(0);return 0;
}

輪廓查找與繪制

1、輪廓的相關概念

1)什么是輪廓

  輪廓可以簡單認為成將連續的點(連著邊界)連在一起的曲線,具有相同的顏色或者灰度,提取輪廓就是提取這些具有相同顏色或者灰度的曲線,或者說是連通域,輪廓在形狀分析和物體的檢測和識別中非常有用。

2)注意事項:

  ①為了更加準確,要使用二值化圖像。在尋找輪廓之前,要進行閾值化處理 或者 Canny 邊界檢測

  ②查找輪廓的函數會修改原始圖像。如果你在找到輪廓之后還想使用原始圖像的話,你應該將原始圖像存儲到其他變量中(clone(), copyTo())

  ③在OpenCV 中,查找輪廓就像在黑色背景中找白色物體。你應該記住,要找的物體應該是白色而背景應該是黑色。

3)常用函數:

  findContours()—–查找輪廓

   drawContours()—–繪制輪廓

2、查找輪廓


void findContours(InputArray image, OutputArrayofArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point());

  image: 輸入圖像, Mat類型8位單通道圖像(一般為二值圖)

  contours: 檢測到的輪廓, 每個輪廓存儲為一個點向量, 即Point類型的vector表示

  hierarchy: 可選的輸出向量, 包含圖像的拓撲信息。其作為輪廓數量的表示, 包含了許多元素, 每個輪廓contours[i]對應4個hierarchy元素hierarchy[i][0]~hierarchy[i][3], 分別表示后一輪廓、前一輪廓、父輪廓、內嵌輪廓的索引編號, 如果沒有對應項, 設置為負數

  mode: 輪廓檢索模式, 取值如下:


CV_RETR_EXTERNAL=0-----表示只檢測最外層輪廓   
CV_RETR_LIST=1------提取所有輪廓并放置在list中, 輪廓不建立等級關系
CV_RETR_CCOMP=2------提取所有輪廓并組織為雙層結構   
CV_RETR_TREE=3------提取所有輪廓并重新建立網狀輪廓結構 

  method: 輪廓的近似方法, 取值如下:


CV_CHAIN_APPROX_NONE ---連續存儲所有的輪廓點,任何兩個相鄰的點都是水平、垂直或者相鄰的。也就是說max(abs(x1-x2), abs(y2-y1)) == 1
CV_CHAIN_APPROX_SIMPLE --- 壓縮存儲,對于水平、垂直或者斜向的線段,比如一個四邊形,只會存儲四個頂點
CV_CHAIN_APPROX_TC89_L1/CV_CHAIN_APPROX_TC89_KCOS        

  offset: 每個輪廓的可選偏移量, 默認值Point()

3、繪制輪廓


1 CV_EXPORTS_W void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point());

  image: 目標圖像, Mat類型對象即可

  contours: 所有的輸入輪廓, 每個輪廓存儲為一個點向量

  contourIdx: 輪廓繪制指示變量(索引), 若為負值, 則表示繪制所有輪廓

  color: 繪制輪廓的顏色

  thickness: 輪廓線條的粗細, 默認值1, 如果為負值, 則繪制輪廓內部, 可選宏 CV_FILLED

  lineType: 線條類型, 默認值8

  hierarcy: 可選的層次結構信息, 默認值noArray()

  maxLevel: 表示用于繪制輪廓的最大等級, 默認值INT_MAX

  offset: 可選的輪廓偏移參數, 默認值Point()


//輪廓查找  輪廓繪制
#include"opencv2/opencv.hpp"
#include<iostream>using namespace std;
using namespace cv;int main()
{Mat srcImg = imread("2.png");Mat tempImg = srcImg.clone();//Mat draw(srcImg.rows, srcImg.cols, CV_8UC3);cvtColor(srcImg, srcImg, CV_BGR2GRAY); //轉為灰度圖threshold(srcImg, srcImg,100, 255, CV_THRESH_BINARY);//圖像二值化,value>threshold(即100)?255:0imshow("srcImg", srcImg);  //輪廓查找前vector<vector<Point>> contours;vector<Vec4i> hierarchy;//findContours(srcImg, contours, hierarchy,RETR_EXTERNAL, CHAIN_APPROX_SIMPLE ); //查找外輪廓,壓縮存儲輪廓點findContours(srcImg, contours, hierarchy,RETR_LIST, CHAIN_APPROX_SIMPLE ); //查找所有輪廓//findContours(srcImg, contours, hierarchy,CV_RETR_CCOMP, CHAIN_APPROX_SIMPLE ); //查找所有輪廓//findContours(srcImg, contours, hierarchy,RETR_TREE, CHAIN_APPROX_NONE ); //查找所有輪廓,存儲所有輪廓點imshow("cont", srcImg);  //輪廓查找后drawContours(tempImg, contours,-1, Scalar(0, 255, 0),2);  //繪制輪廓:-1代表繪制所有輪廓cout<<"num="<<contours.size()<<endl; //輸出輪廓個數imshow("contours", tempImg);waitKey(0);return 0;
}

附錄:

QT集合OpenCV庫


# 添加我們包含路徑
INCLUDEPATH += D:\Application\opencvdev\opencv3.4.6\rebuild_for_qt\install\include
# 添加對應類庫文件
LIBS += D:\Application\opencvdev\opencv3.4.6\rebuild_for_qt\lib\libopencv_*.a
上面配置的磁盤路徑是你電腦編譯OpenCV的路徑

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

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

相關文章

Composer 常規操作說明與問題處理

目錄 一、 Composer 簡介&#xff0c;安裝二、全局配置三、項目配置&#xff08;composer.json&#xff09;3.1 composer.json 文件1. 基礎字段信息2. **require&#xff08;生產環境依賴&#xff09;**3. **require-dev&#xff08;開發環境依賴&#xff09;** 3.2 composer.l…

Spring Boot 3.0與Java 17:企業級應用開發的新范式

引言 隨著Spring Boot 3.0和Java 17的正式發布&#xff0c;企業級應用開發迎來了新的技術范式。這兩項技術的結合不僅帶來了性能提升&#xff0c;還引入了眾多現代化的編程特性&#xff0c;為開發者提供了更強大、更高效的開發體驗。本文將深入探討Spring Boot 3.0與Java 17的…

Vue 組件 - 指令

Vue 漸進式JavaScript 框架 基于Vue2的學習筆記 - Vue指令 目錄 指令寫法 自定義指令 簡單封裝指令 指令傳遞字符串 update事件 指令應用 指令實現輪播 指令函數簡寫 指令函數列表 bind inserted update componentUpdated unbind Vue3指令輪播 nextick 總結 指…

5.28 后端面經

為什么golang在并發環境下更有優勢 Go語言&#xff08;Golang&#xff09;在并發環境下的優勢主要源自其設計哲學和內置的并發機制&#xff0c;這些機制在語言層面提供了高效、簡潔且安全的并發編程工具。以下是其核心優勢的詳細分析&#xff1a; 1. Goroutine&#xff1a;輕量…

Linux線程入門

目錄 Linux線程概念 什么是線程 重新理解進程 線程的優點 線程的缺點 線程的異常 線程用途 Linux線程概念 什么是線程 在一個程序里的一個執行路線就叫做線程&#xff08;thread&#xff09;。更準確的定義是&#xff1a;線程是“一個進程內部的控制序列”。一切進程至…

通信應用高速模數轉換器ADC

在5G通信、醫療成像、航空航天及工業自動化等關鍵領域&#xff0c;高速ADC模數轉換器作為信號鏈的“心臟”&#xff0c;其性能直接決定了系統的精度與效率。然而&#xff0c;如何精確測試高速ADC的動態參數、優化設計驗證流程、應對復雜應用場景的挑戰&#xff0c;始終是工程師…

PostgreSQL 中 JSONB 數據類型的深度解析以及如何使用

一、JSONB 核心特性解析 1. 存儲結構與優勢 ??二進制存儲??&#xff1a;將 JSON 數據解析為二進制格式&#xff08;分解鍵值對&#xff0c;去除空格和重復鍵&#xff09;??高效查詢??&#xff1a;支持 GIN/GiST 索引&#xff0c;查詢速度比 JSON 類型快 10 倍??數據…

C++_核心編程_ 左移運算符重載 “<<” 左移運算符

作用&#xff1a;可以輸出自定義數據類型 */ //目標 調用p1,輸出Person 中的屬性 m_A ,m_B &#xff1a; /* #### 4.5.2 左移運算符重載 “<<” 左移運算符 作用&#xff1a;可以輸出自定義數據類型 *///目標 調用p1,輸出Person 中的屬性 m_A ,m_B &#xff1a; class…

thinkphp 5.1 部分知識記錄<一>

1、配置基礎 慣例配置->應用配置->模塊配置->動態配置 慣例配置:核心框架內置的配置文件,無需更改。應用配置:每個應用的全局配置文件(框架安裝后會生成初始的應用配置文件),有部分配置參數僅能在應用配置文件中設置。模塊配置:每個模塊的配置文件(相同的配置…

數據結構 -- 樹相關面試題

二、樹相關的填空題 1.對于一個具有 n 個結點的二叉樹&#xff0c;當它為一棵 ________ 二叉樹時&#xff0c;具有最小高度&#xff0c;即為 ________&#xff1b;當它為一棵單支樹時具有最大高度&#xff0c;即為 ________。 2.對于一個具有 n 個結點的二叉樹&#xff0c;當它…

2025河北CCPC 題解(部分)

簽到題&#xff1a;AC代碼如下 &#xff1a; // Problem: H - What is all you need? // Contest: Virtual Judge - sdccpc20250526 // URL: https://vjudge.net/contest/718568#problem/H // Memory Limit: 1024 MB // Time Limit: 1000 ms // // Powered by CP Editor (ht…

計算機視覺---YOLOv4

YOLOv4&#xff08;You Only Look Once v4&#xff09;于2020年由Alexey Bochkovskiy等人提出&#xff0c;是YOLO系列的重要里程碑。它在YOLOv3的基礎上整合了當時最先進的計算機視覺技術&#xff0c;實現了檢測速度與精度的顯著提升。以下從主干網絡、頸部網絡、頭部檢測、訓練…

OpenCV 第7課 圖像處理之平滑(一)

1. 圖像噪聲 在采集、處理和傳輸過程中,數字圖像可能會受到不同噪聲的干擾,從而導致圖像質量降低、圖像變得模糊、圖像特征被淹沒,而圖像平滑處理就是通過除去噪聲來達到圖像增強的目的。常見的圖像噪聲有椒鹽噪聲、高斯噪聲等。 1.1 椒鹽噪聲 椒鹽噪聲(Salt-and-pepper N…

Spring AI 系列3: Promt提示詞

一、Promt提示詞 Promt提示是引導 AI 模型生成特定輸出的輸入&#xff0c; 提示的設計和措辭會顯著影響模型的響應。 在 Spring AI 中與 AI 模型交互的最低層級&#xff0c;處理提示有點類似于在 Spring MVC 中管理”視圖”。 這涉及創建帶有動態內容占位符的大段文本。 這些占…

隨叫隨到的電力補給:移動充電服務如何重塑用戶體驗?

在快節奏的現代生活中&#xff0c;電力已成為維系日常運轉的隱形血脈。智能手機、電動汽車、便攜設備的普及&#xff0c;讓“電量焦慮”逐漸演變為一種時代癥候。而移動充電服務的興起&#xff0c;正悄然改變這一局面。它像一位隱形的能源管家&#xff0c;隨時響應需求&#xf…

LeetCode 75. 顏色分類 - 雙指針法高效解決(Java實現)

文章目錄 問題描述算法思路&#xff1a;三指針分區法核心思想指針定義 Java實現算法執行流程關鍵問題解析&#xff1a;為什么交換0后不需要重新檢查&#xff1f;交換0時的兩種情況分析詳細解釋&#xff1a; 復雜度分析示例演示&#xff08;輸入&#xff1a;[2,0,2,1,1,0]&#…

【MySQL】C語言連接

要使用C語言連接mysql&#xff0c;需要使用mysql官網提供的庫&#xff0c;大家可以去官網下載 我們使用C接口庫來進行連接 要正確使用&#xff0c;我們需要做一些準備工作: 保證mysql服務有效在官網上下載合適自己平臺的mysql connect庫&#xff0c;以備后用 下載開發庫 s…

NFS 掛載配置與優化最佳實踐指南

文章目錄 NFS 掛載配置與優化最佳實踐指南1. 服務器端配置1.1 安裝 NFS 服務1.2 配置共享目錄常用配置選項說明 1.3 啟動與檢查服務 2. 客戶端掛載2.1 安裝 NFS 客戶端2.2 掛載 NFS 共享2.3 自動掛載 3. 客戶端掛載選項4. 性能優化與故障排查4.1 性能優化建議4.2 常見問題排查 …

3D PDF如何制作?SOLIDWORKS MBD模板定制技巧

SOLIDWORKS制作3D PDF模版 SOLIDWORKS MBD能夠幫助工程師以清晰直觀的方式描述產品尺寸信息。在3D PDF文件中&#xff0c;用戶可以自由旋轉和移動視圖&#xff0c;方便查看模型的各個尺寸細節。 本文將帶您一步步學習如何使用SOLIDWORKS MBD制作專業的3D PDF模板&#xff0c;…

Unity-QFramework框架學習-MVC、Command、Event、Utility、System、BindableProperty

QFramework QFramework簡介 QFramework是一套漸進式、快速開發框架&#xff0c;適用于任何類型的游戲及應用項目&#xff0c;它包含一套開發架構和大量的工具集 QFramework的特性 簡潔性&#xff1a;QFramework 強調代碼的簡潔性和易用性&#xff0c;讓開發者能夠快速上手&a…