目錄
前言:
?一、函數(shù)講解:
圖像閾值處理:Cv2.Threshold()
查找輪廓 Cv2.FindContours()
最小外接矩形 Cv2.BoundingRect();
繪制輪廓 Cv2.DrawContours()
?計(jì)算輪廓相似度 Cv2.MatchShapes()
二、代碼(教學(xué)注釋詳細(xì),仔細(xì)閱讀)
三、代碼過(guò)程總結(jié):
前言:
輪廓匹配是一種計(jì)算機(jī)視覺(jué)技術(shù),用于在圖像中查找和比較目標(biāo)輪廓與待匹配輪廓之間的相似度
?一、函數(shù)講解:
圖像閾值處理:Cv2.Threshold()
用于將圖像中的像素值根據(jù)閾值分成兩個(gè)不同的區(qū)域,可以用來(lái)實(shí)現(xiàn)圖像的分割、邊緣檢測(cè)等任務(wù)。
Cv2.Threahold(Mat src, Mat dst ,double thresh, double maxval, ThresholdTypes type)
-
src
: 輸入的源圖像,通常是一個(gè)單通道灰度圖像。 -
dst
: 輸出的目標(biāo)圖像,與源圖像具有相同的尺寸和類(lèi)型。 -
thresh
: 閾值,用于將圖像中的像素值進(jìn)行分類(lèi)。 -
maxval
: 閾值之后的像素值要設(shè)置的新值。 -
type
: 閾值處理的類(lèi)型,有不同的處理方式,比如二進(jìn)制閾值、反二進(jìn)制閾值、截?cái)嚅撝档取?/li>
常見(jiàn)的閾值處理類(lèi)型包括:
-
ThresholdTypes.Binary
: 如果像素值大于等于閾值,則設(shè)置為maxval
,否則為 0。 -
ThresholdTypes.BinaryInv
: 如果像素值小于閾值,則設(shè)置為maxval
,否則為 0。 -
ThresholdTypes.Trunc
: 如果像素值大于等于閾值,則保持原值,否則截?cái)酁殚撝怠?/li> -
ThresholdTypes.ToZero
: 如果像素值大于等于閾值,則保持原值,否則設(shè)置為 0。 -
ThresholdTypes.ToZeroInv
: 如果像素值小于閾值,則保持原值,否則設(shè)置為 0。 -
ThresholdTypes.Otsu:
大津法,是一種自動(dòng)確定圖像二值化閾值的方法,它能夠?qū)D像的像素分成兩個(gè)類(lèi)別,使得類(lèi)別內(nèi)方差最小、類(lèi)別間方差最大。這個(gè)方法非常適用于背景與前景之間對(duì)比明顯的圖像。 -
ThresholdTypes.Triangle:三角法,
基于圖像直方圖的閾值選擇方法,通過(guò)尋找直方圖中的一條直線(xiàn),將直方圖分成兩個(gè)部分,使得兩個(gè)部分之間的面積最小,從而得到閾值。
Point[][] contours:二維數(shù)組表示多個(gè)輪廓,每個(gè)輪廓由一組點(diǎn)坐標(biāo)組成,因此 contours變量
存儲(chǔ)了多個(gè)輪廓。
HierarchyIndex[] hierarchy :用hierarchy變量存儲(chǔ)輪廓之間拓?fù)潢P(guān)系的數(shù)據(jù)結(jié)構(gòu)
查找輪廓 Cv2.FindContours()
返回一組輪廓數(shù)組 contours和輪廓的拓?fù)浣Y(jié)構(gòu)hierarchy
Point[][] contours; // 存儲(chǔ)輪廓的點(diǎn)坐標(biāo)數(shù)組
HierarchyIndex[] hierarchy; // 存儲(chǔ)輪廓之間的拓?fù)潢P(guān)系
Cv2.FindContours(
input: binaryImage, // 二值化圖像,白色像素表示物體,黑色像素表示背景
contours: out contours, // 存儲(chǔ)找到的輪廓點(diǎn)坐標(biāo)
hierarchy: out hierarchy, // 存儲(chǔ)輪廓之間的拓?fù)潢P(guān)系
mode: RetrievalModes.External, // 輪廓檢索模式,這里表示只檢索外部輪廓
method: ContourApproximationModes.ApproxNone // 輪廓逼近方法,這里表示不逼近輪廓
);
-
input
: 二值化圖像,即圖像中的物體被標(biāo)記為白色,背景被標(biāo)記為黑色。 -
contours
: 用于存儲(chǔ)找到的輪廓的點(diǎn)坐標(biāo)數(shù)組。每個(gè)輪廓由一組點(diǎn)構(gòu)成。 -
hierarchy
: 用于存儲(chǔ)輪廓之間的拓?fù)潢P(guān)系,例如父子關(guān)系、前后關(guān)系等。 -
mode
: 輪廓檢索模式,可以是RetrievalModes.List
(檢索所有輪廓)或RetrievalModes.External
(只檢索外部輪廓)等。 -
method
: 輪廓逼近方法,可以是ContourApproximationModes.ApproxNone
(不逼近輪廓)、ContourApproximationModes.ApproxSimple
(簡(jiǎn)化輪廓)等。
最小外接矩形 Cv2.BoundingRect();
Rect 變量名 = Cv2.BoundingRect(InputArray points);
?points
是輸入的輪廓點(diǎn)集,可以是一個(gè) Point[]
或 Mat
。
? 返回一個(gè) Rect
對(duì)象,表示計(jì)算得到的最小外接矩形。矩形由左上角坐標(biāo) (x, y)
和矩形的寬度和? 高度 (width, height)
組成。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-782775.html
繪制輪廓 Cv2.DrawContours()
void Cv2.DrawContours(Mat image, IEnumerable<IEnumerable<Point>> contours, int contourIdx, Scalar color, int thickness = 1, LineTypes lineType = LineTypes.Link8, Mat? hierarchy = null, int maxLevel = int.MaxValue, Point? offset = null);
-
image
:目標(biāo)圖像,輪廓將繪制在這個(gè)圖像上。 -
contours
:要繪制的輪廓列表,可以是一個(gè)包含Point
數(shù)組的集合。 -
contourIdx
:要繪制的輪廓的索引。
正數(shù)值(0、1、2..):表示你要繪制的具體輪廓的索引。如果有多個(gè)輪廓,你可以選擇其中一個(gè)來(lái)繪制;
負(fù)數(shù)(-1):表示繪制所有的輪廓。這時(shí)會(huì)繪制contours
列表中的所有輪廓。 -
color
:繪制輪廓的顏色。 -
thickness
:輪廓線(xiàn)的寬度,其余為默認(rèn)
: 繪制細(xì)線(xiàn),通常是輪廓的默認(rèn)值。這是最常見(jiàn)的用法。
?= 1?> 1
: 繪制較粗的線(xiàn)。增加線(xiàn)寬度可以使輪廓更加突出。?= -1
: 填充輪廓內(nèi)部。這樣可以創(chuàng)建一個(gè)實(shí)心的輪廓。
Cv2.MatchShapes()形狀匹配
double Cv2.MatchShapes(InputArray contour1, InputArray contour2, ContourMatchModes method, double parameter = 0);
-
contour1
:第一個(gè)輪廓的點(diǎn)集,可以是一個(gè)Point[]
或Mat
。 -
contour2
:第二個(gè)輪廓的點(diǎn)集,可以是一個(gè)Point[]
或Mat
。 -
method
:計(jì)算相似性的方法,可以是ContourMatchModes
枚舉中的一個(gè)選項(xiàng)。 -
parameter
:計(jì)算方法所需的參數(shù)。 - ?用于選擇形狀匹配的方法:
-
ShapeMatchModes.I1
:使用I1方法計(jì)算形狀相似性。 -
ShapeMatchModes.I2
:使用I2方法計(jì)算形狀相似性。 -
ShapeMatchModes.I3
:使用I3方法計(jì)算形狀相似性。
返回值:該方法返回一個(gè) double
類(lèi)型的相似性度量值,用于表示兩個(gè)輪廓之間的相似性。值越小,表示形狀越相似。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-782775.html
二、代碼(教學(xué)注釋詳細(xì),仔細(xì)閱讀)
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 輪廓匹配查找模板
{
class Program
{
static void Main(string[] args)
{
//讀取圖像
Mat template = Cv2.ImRead("C:/Users/CGW/source/repos/輪廓匹配查找模板_Color Space/輪廓匹配查找模板_Color Space/imgs/0.bmp"); //讀取模板圖像
Mat imgTest = Cv2.ImRead("C:/Users/CGW/source/repos/輪廓匹配查找模板_Color Space/輪廓匹配查找模板_Color Space/imgs/4.bmp"); //讀取測(cè)試圖像
Mat grayTemp = new Mat(); // 模板圖像
Mat grayTest = new Mat(); // 測(cè)試圖像
//轉(zhuǎn)換為灰度圖
Cv2.CvtColor(template, grayTemp, ColorConversionCodes.BGR2GRAY);
Cv2.CvtColor(imgTest, grayTest, ColorConversionCodes.BGR2GRAY);
//二值化--分割輪廓區(qū)域
Cv2.Threshold(grayTemp, grayTemp, 90, 255, ThresholdTypes.Binary);
Cv2.Threshold(grayTest, grayTest, 90, 255, ThresholdTypes.Binary);
Point[][] contours; // 存儲(chǔ)輪廓的變量
HierarchyIndex[] hierarchy; // 存儲(chǔ)輪廓拓?fù)浣Y(jié)構(gòu)的變量
// 使用 FindContours 函數(shù)查找圖像中的輪廓,返回一組輪廓數(shù)組 contours,同時(shí)還可以獲得輪廓的拓?fù)浣Y(jié)構(gòu)。
Cv2.FindContours(grayTemp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
int index = 0; // 模板中十字輪廓的輪廓序號(hào)
//遍歷每個(gè)輪廓
for (int i = 0; i < contours.Length; i++)
{
// 獲取輪廓的外接矩形
Rect rect = Cv2.BoundingRect(contours[i]);
// 判斷輪廓是否滿(mǎn)足條件,比如寬度和高度都大于80像素
if (rect.Width > 80 && rect.Height > 80)
{
index = i; // 記錄找到的目標(biāo)輪廓的索引
// 在模板圖像上繪制找到的目標(biāo)輪廓,標(biāo)記為紅色
Cv2.DrawContours(template, contours, i, new Scalar(0, 0, 255), -1);
break; // 找到目標(biāo)輪廓后跳出循環(huán)
}
}
Cv2.ImShow("template", template);
//遍歷測(cè)試圖像中的輪廓做輪廓匹配
Point[][] contours2; //輪廓查找結(jié)果變量
HierarchyIndex[] hierarchy2; //輪廓拓?fù)浣Y(jié)構(gòu)變量
Cv2.FindContours(grayTest, out contours2, out hierarchy2, RetrievalModes.External,
ContourApproximationModes.ApproxNone);
//Console.WriteLine("contour2_size = {0}", contours2.Length); //輸出輪廓個(gè)數(shù)
for (int i = 0; i < contours2.Length; i++)
{
Rect rect = Cv2.BoundingRect(contours2[i]);
//寬高與模板輪廓寬高相符的才做輪廓匹配,剔除干擾輪廓
if (rect.Width >= 80 && rect.Width <= 100 && rect.Height > 80 && rect.Height <= 100) //找到目標(biāo)輪廓,跳出循環(huán)
{
// 計(jì)算輪廓匹配值
double matchValue = Cv2.MatchShapes(contours[index], contours2[i], ShapeMatchModes.I3);
// 輸出匹配值
Console.WriteLine("matchRate = {0}", matchValue);
// 如果匹配值在一定閾值內(nèi),繪制匹配的輪廓
if (matchValue <= 2)
Cv2.DrawContours(imgTest, contours2, i, new Scalar(0, 255, 0), -1);
}
}
Cv2.ImShow("match-result", imgTest);
Cv2.WaitKey(0);
}
}
}
三、代碼過(guò)程總結(jié):
- 讀取模板圖像和測(cè)試圖像。
- 創(chuàng)建存儲(chǔ)灰度模板和測(cè)試圖像的變量
grayTemp
和grayTest
。 - 將圖像轉(zhuǎn)換為灰度圖像。
- 對(duì)模板圖像和測(cè)試圖像進(jìn)行二值化處理,將圖像中的輪廓區(qū)域分割出來(lái)。
- 定義存儲(chǔ)輪廓結(jié)果和拓?fù)浣Y(jié)構(gòu)的變量
contours
和hierarchy
。 - 使用
Cv2.FindContours
在模板圖像中查找輪廓,存儲(chǔ)在contours
中,同時(shí)也獲取輪廓的拓?fù)浣Y(jié)構(gòu)。 - 遍歷
contours
數(shù)組,找到滿(mǎn)足條件的目標(biāo)輪廓(這里是寬度和高度都大于80像素),在模板圖像上繪制目標(biāo)輪廓。 - 使用
Cv2.ImShow
顯示帶有標(biāo)記的模板圖像。
到了這里,關(guān)于OpenCvSharp-輪廓形狀匹配/模板查找1.0(附源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!