20-模板匹配matchTemplate()實現(EmguCV學習)

文章目錄

說明

1、模板匹配不支持放大縮小,圖像旋轉,不適用於縮放與旋轉情況;應保證模板圖像與搜尋的圖像具有相同的大小,方向;
2、模板匹配用來尋找一幅圖像中與模板最匹配的部分,模板圖像大小必須小於搜尋的原圖像,且類型必須相同;
在這裏插入圖片描述3、CvInvoke.MatchTemplate()函數:輸出比較映射圖像result類型爲:32位單通道圖像,尺寸大小爲 : (W-w+1)*(H-h+1);映射圖像結果中最佳匹配的地方最亮,圖像像素值最大;可先將映射圖像歸一化到0-1,再尋找maxLoc與maxValue,設定一個閾值,大於閾值的認爲是匹配圖像結果(實現多模板匹配);匹配方法常用:CcorrNormed(歸一化相關匹配法)
在這裏插入圖片描述
在這裏插入圖片描述
4、CvInvoke.MinMaxLoc() : 尋找圖像中最大最小像素值及其位置;

在這裏插入圖片描述

Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Util;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Drawing;

namespace lesson20
{
    class Program
    {
        static void Main(string[] args)
        {
            ///單模板匹配
            //Mat src = CvInvoke.Imread("src.png");
            //CvInvoke.Imshow("src", src);
            //Mat result = src.Clone();

            //Mat tempImg = CvInvoke.Imread("temp.png");
            //int rows_dst = src.Rows - tempImg.Rows + 1;
            //int cols_dst = src.Cols - tempImg.Cols + 1;
            //Mat dst = new Mat(rows_dst,cols_dst,DepthType.Cv32F,1);     //創建合適大小的32位浮點型單通道圖像
            //CvInvoke.MatchTemplate(src, tempImg, dst, TemplateMatchingType.CcoeffNormed);     //模板匹配
            //CvInvoke.Imshow("match", dst);          //輸出32位匹配圖(imshow()自動縮放)
            //CvInvoke.Normalize(dst, dst, 0, 1, NormType.MinMax, dst.Depth);//歸一化到0-1

            //double minValue = 1000, maxvalue = -1;
            //Point minLoc = new Point();
            //Point maxLoc = new Point();

            //CvInvoke.MinMaxLoc(dst, ref minValue, ref maxvalue, ref minLoc, ref maxLoc);    //尋找最大最小值位置
            //CvInvoke.Rectangle(result, new Rectangle(maxLoc.X, maxLoc.Y, tempImg.Width, tempImg.Height), 
            //                    new MCvScalar(0, 255, 0), 2);
            //CvInvoke.Imshow("result", result);
            //CvInvoke.WaitKey(0);

            ///視頻模板匹配
            //VideoCapture cap = new VideoCapture("1.mp4");
            //Mat tempImg = CvInvoke.Imread("green.jpg");
            //if(!cap.IsOpened)
            //{
            //    Console.WriteLine("could not open the video...");
            //    return;
            //}
            //Mat frame = new Mat();
            //while(true)
            //{
            //    cap.Read(frame);
            //    if(frame.IsEmpty)
            //    {
            //        continue;
            //    }
            //    int matchresult_rows = frame.Rows - tempImg.Rows + 1;
            //    int matchresult_cols = frame.Cols - tempImg.Cols + 1;
            //    Mat matchresult_img = new Mat(matchresult_rows, matchresult_cols, DepthType.Cv32F, 1);
            //    CvInvoke.MatchTemplate(frame, tempImg, matchresult_img, TemplateMatchingType.CcoeffNormed);
            //    CvInvoke.Imshow("match result", matchresult_img);
            //    CvInvoke.Normalize(matchresult_img, matchresult_img, 0, 1, 
            //                        NormType.MinMax, matchresult_img.Depth);  //歸一化
            //    double minValue = 0, maxValue = 0;
            //    Point minLoc = new Point(0, 0);
            //    Point maxLoc = new Point(0, 0);

            //    CvInvoke.MinMaxLoc(matchresult_img, ref minValue, ref maxValue, ref minLoc, ref maxLoc);
            //    CvInvoke.Rectangle(frame, new Rectangle(maxLoc.X, maxLoc.Y, tempImg.Width, tempImg.Height), new MCvScalar(0, 255, 0), 2);

            //    CvInvoke.Imshow("template trace", frame);
            //    if(CvInvoke.WaitKey(30) == 27)
            //    {
            //        break;
            //    }
            //}

            ///多模板匹配方法
            Mat src = CvInvoke.Imread("src.png");
            CvInvoke.Imshow("src", src);
            Mat result = src.Clone();

            Mat tempImg = CvInvoke.Imread("temp.png");
            int matchImg_rows = src.Rows - tempImg.Rows + 1;
            int matchImg_cols = src.Cols - tempImg.Cols + 1;
            Mat matchImg = new Mat(matchImg_rows, matchImg_rows, DepthType.Cv32F,1); //存儲匹配結果
            CvInvoke.MatchTemplate(src, tempImg, matchImg, TemplateMatchingType.CcoeffNormed);
            CvInvoke.Imshow("match", matchImg);
            CvInvoke.Normalize(matchImg, matchImg, 0, 1, NormType.MinMax, matchImg.Depth); //歸一化
            double minValue = 0.0, maxValue = 0.0;
            Point minLoc = new Point();
            Point maxLoc = new Point();
            CvInvoke.MinMaxLoc(matchImg,ref minValue,ref maxValue,ref minLoc,ref maxLoc);

            Image<Gray, Single> imgMatch = matchImg.ToImage<Gray, Single>();

            int count = 0;
            int tempH = 0, tempW = 0;
            for(int i =0; i < imgMatch.Rows;i++)
            {
                for(int j = 0; j < imgMatch.Cols;j++)
                {
                    float matchValue = imgMatch.Data[i,j,0];
                    if((matchValue > 0.7) && (Math.Abs(j - tempW) > 10) && (Math.Abs(i - tempH)> 10))  //只繪製處於最大範圍內的點
                    {
                        count++;
                        CvInvoke.Rectangle(result, new Rectangle(j, i, tempImg.Width, tempImg.Height), new MCvScalar(255, 0, 0), 2);
                        tempH = i;
                        tempW = j;
                    }
                }
            }
            CvInvoke.Imshow("result", result);
            CvInvoke.WaitKey(0);
        }
    }
}

效果

1、單模板匹配:(只尋找最佳匹配的一幅圖像)
在這裏插入圖片描述

2、視頻模板匹配:
在這裏插入圖片描述

3、多模板匹配:
在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章