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、多模板匹配:
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值