🔥 Programming/OpenCV

[OpenCV4] C# OpenCV4 Template Matching

스쳐가는비 2022. 10. 19. 20:55

Template Matching

Template Matching은 더 큰 이미지에서 찾고자 하는 이미지를 찾는 기능이다.

OpenCV에서 없어서는 안될 기능이며, 자세한 사항은 아래 OpenCV URL에서 확인할 수 있다.

 

https://docs.opencv.org/4.x/d4/dc6/tutorial_py_template_matching.html

 

OpenCV: Template Matching

Goals In this chapter, you will learn Theory Template Matching is a method for searching and finding the location of a template image in a larger image. OpenCV comes with a function cv.matchTemplate() for this purpose. It simply slides the template image o

docs.opencv.org

 

배경 이미지

ppt에다가 한글을 써놓고, 찾고자하는 이미지를 잘라 낸 후, Template Matching으로 잘 찾아내는지

확인한다.

 

우선 찾고자 하는 이미지를 마우스 드래그로 잘라낸다.

그리고 Find를 누르면 아래 이미지와 같이 Template matching을 이용하여 이미지를 찾아낸다.

Code

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Point = OpenCvSharp.Point;

namespace TemplateMatching
{
    public partial class Form1 : Form
    {
        private OpenCvSharp.Point ClickPoint        = new OpenCvSharp.Point();
        private OpenCvSharp.Point CurrentTopLeft    = new OpenCvSharp.Point();
        private OpenCvSharp.Point CurrentBottomRight = new OpenCvSharp.Point();
        private Pen MyPen;
        private Graphics g;

        Mat _orgMat = new Mat();
        Mat _roiMat = new Mat();

        public Form1()
        {
            InitializeComponent();

            g = this.pictureBox1.CreateGraphics();
            MyPen = new Pen(Color.Red, 2);
            MyPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Bitmap convert = new Bitmap(Properties.Resources.test1);
            pictureBox1.Image = Properties.Resources.test1;
            _orgMat = BitmapConverter.ToMat(convert);
        }


        bool _isDraw = false;

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _isDraw = true;
                ClickPoint = new Point(e.X, e.Y);
                pictureBox1.Refresh();
            }

        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isDraw)
            {
                if(e.X < ClickPoint.X)
                {
                    CurrentTopLeft.X = e.X;
                    CurrentBottomRight.X = ClickPoint.X;
                }
                else
                {
                    CurrentTopLeft.X = ClickPoint.X;
                    CurrentBottomRight.X = e.X;
                }

                if (e.Y < ClickPoint.Y)
                {
                    CurrentTopLeft.Y = e.Y;
                    CurrentBottomRight.Y = ClickPoint.Y;
                }
                else
                {
                    CurrentTopLeft.Y = ClickPoint.Y;
                    CurrentBottomRight.Y = e.Y;
                }

                pictureBox1.Refresh();
                g.DrawRectangle(MyPen, CurrentTopLeft.X, CurrentTopLeft.Y, CurrentBottomRight.X - CurrentTopLeft.X,
               CurrentBottomRight.Y - CurrentTopLeft.Y);
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            _isDraw = false;

            SetNewRoiTemplate();
        }


        private void btn_StartFind_Click(object sender, EventArgs e)
        {
            using (Mat resultMat = new Mat())
            {
                Cv2.MatchTemplate(_orgMat, _roiMat, resultMat, TemplateMatchModes.CCoeffNormed);
                Cv2.Threshold(resultMat, resultMat, 0.6, 1.0, ThresholdTypes.Tozero);

                OpenCvSharp.Point minloc, maxloc;
                double minval, maxval;
                Cv2.MinMaxLoc(resultMat, out minval, out maxval, out minloc, out maxloc);

                Rect rect = new Rect(maxloc.X, maxloc.Y, _roiMat.Width, _roiMat.Height);
                Cv2.Rectangle(_orgMat, rect, new OpenCvSharp.Scalar(0, 0, 255), 2);

                pictureBox1.Image = BitmapConverter.ToBitmap(_orgMat);

                lbl_Result.Text = $"{maxval * 100:F2}%";

                pictureBox1.Refresh();
            }
        }

        private void SetNewRoiTemplate()
        {
            Rect rect = new Rect(CurrentTopLeft.X, CurrentTopLeft.Y, CurrentBottomRight.X - CurrentTopLeft.X, CurrentBottomRight.Y - CurrentTopLeft.Y);
            _roiMat = _orgMat.SubMat(rect);

            pictureBox1.Image = Properties.Resources.test1;
        }
       
    }

}