OpenCvSharp-contour matching/template search 1.0 (with source code)

Table of contents

Foreword:

 1. Function explanation:

Image threshold processing: Cv2.Threshold()

Find contours Cv2.FindContours()

Minimum circumscribed rectangle Cv2.BoundingRect();

Draw Contours Cv2.DrawContours()

 Calculate silhouette similarity Cv2.MatchShapes()

2. Code (detailed teaching notes, read carefully)

3. Summary of the coding process:


Foreword:

Contour matching is a computer vision technique used to find and compare the similarity between target contours and the contours to be matched in images

 1. Function explanation:

Image threshold processing: Cv2.Threshold()

It is used to divide the pixel values ​​in the image into two different areas according to the threshold, and can be used to achieve tasks such as image segmentation and edge detection.

Cv2.Threahold(Mat src, Mat dst ,double thresh, double maxval, ThresholdTypes type)
  • src: The input source image, usually a single-channel grayscale image.
  • dst: The output destination image has the same size and type as the source image.
  • thresh: Threshold used to classify pixel values ​​in an image.
  • maxval: The new value to be set for pixel values ​​after the threshold.
  • type: Type of threshold processing, there are different processing methods, such as binary threshold, inverse binary threshold, truncation threshold, etc.

Common types of thresholding include:

  • ThresholdTypes.Binary: Set to 0 if the pixel value is greater than or equal to the threshold, maxvalotherwise 0.
  • ThresholdTypes.BinaryInv: Set to if the pixel value is less than the threshold, maxvalotherwise 0.
  • ThresholdTypes.Trunc: If the pixel value is greater than or equal to the threshold, keep the original value, otherwise truncate to the threshold.
  • ThresholdTypes.ToZero: If the pixel value is greater than or equal to the threshold, keep the original value, otherwise set to 0.
  • ThresholdTypes.ToZeroInv: If the pixel value is less than the threshold, keep the original value, otherwise set to 0.
  • ThresholdTypes.OtsuThe Otsu method is a method for automatically determining the binarization threshold of an image. It can divide the pixels of the image into two categories, so that the variance within the category is minimized and the variance between categories is maximized. This method is ideal for images with significant contrast between the background and foreground.
  • ThresholdTypes.Triangle:三角法,The threshold selection method based on the image histogram divides the histogram into two parts by finding a straight line in the histogram to minimize the area between the two parts, thereby obtaining the threshold.

Point[][] contours: A two-dimensional array represents multiple contours. Each contour consists of a set of point coordinates, so contours变量multiple contours are stored.

HierarchyIndex[] hierarchy: a data structure that uses hierarchy variables to store topological relationships between contours

Find contours Cv2.FindContours()

Returns a set of contour array contours and the topology hierarchy of the contours

Point[][] contours; // 存储轮廓的点坐标数组
HierarchyIndex[] hierarchy; // 存储轮廓之间的拓扑关系

Cv2.FindContours(
    input: binaryImage, // 二值化图像,白色像素表示物体,黑色像素表示背景
    contours: out contours, // 存储找到的轮廓点坐标
    hierarchy: out hierarchy, // 存储轮廓之间的拓扑关系
    mode: RetrievalModes.External, // 轮廓检索模式,这里表示只检索外部轮廓
    method: ContourApproximationModes.ApproxNone // 轮廓逼近方法,这里表示不逼近轮廓
);
  • input: Binarized image, that is, the objects in the image are marked as white and the background is marked as black.
  • contours: Array of point coordinates used to store the found contour. Each contour consists of a set of points.
  • hierarchy: Used to store topological relationships between contours, such as parent-child relationships, front-to-back relationships, etc.
  • mode: Contour retrieval mode, which can be RetrievalModes.List(retrieve all contours) or RetrievalModes.External(retrieve only external contours), etc.
  • method: Contour approximation method, which can be ContourApproximationModes.ApproxNone(not approximating the contour), ContourApproximationModes.ApproxSimple(simplifying the contour), etc.

Minimum circumscribed rectangle Cv2.BoundingRect();

Rect 变量名 = Cv2.BoundingRect(InputArray points);

 pointsis the input contour point set, which can be a Point[]or Mat.

  Returns an Rectobject representing the calculated minimum enclosing rectangle. The rectangle consists of the coordinates of the upper left corner (x, y)and the width and height of the rectangle (width, height).

Draw Contours 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: Target image, the outline will be drawn on this image.
  • contours: A list of contours to be drawn, which can be a Pointcollection containing an array.
  • contourIdx: Index of the contour to draw. If negative, all contours are drawn.
  • color: The color to draw the outline.
  • thickness: The width of the contour line. The rest of the parameters are default

 Calculate contour similarity Cv2.MatchShapes()

double Cv2.MatchShapes(InputArray contour1, InputArray contour2, ContourMatchModes method, double parameter = 0);
  • contour1: The point set of the first contour, which can be a Point[]or Mat.
  • contour2: The point set of the second contour, which can be a Point[]or Mat.
  • method: The method for calculating similarity, which can be ContourMatchModesan option in the enumeration.
  • parameter: Arguments required by the compute method.

Return value: This method returns doublea similarity measure value of type, used to represent the similarity between two contours. Smaller values ​​indicate more similar shapes.

2. Code (detailed teaching notes, read carefully)

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"); //读取测试图像

            Mat grayTemp = new Mat(); // 模板图像
            Mat grayTest = new Mat(); // 测试图像

            //转换为灰度图
            Cv2.CvtColor(template, grayTemp, ColorConversionCodes.BGR2GRAY);
            Cv2.CvtColor(imgTest, grayTest, ColorConversionCodes.BGR2GRAY);

            //二值化--分割轮廓区域
            Cv2.Threshold(grayTemp, grayTemp, 90, 255, ThresholdTypes.Binary);
            Cv2.Threshold(grayTest, grayTest, 90, 255, ThresholdTypes.Binary);

            Point[][] contours; // 存储轮廓的变量
            HierarchyIndex[] hierarchy; // 存储轮廓拓扑结构的变量

            // 使用 FindContours 函数查找图像中的轮廓,返回一组轮廓数组 contours,同时还可以获得轮廓的拓扑结构。
            Cv2.FindContours(grayTemp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);

            int index = 0; // 模板中十字轮廓的轮廓序号
            //遍历每个轮廓
            for (int i = 0; i < contours.Length; i++)
            {
                // 获取轮廓的外接矩形
                Rect rect = Cv2.BoundingRect(contours[i]);

                // 判断轮廓是否满足条件,比如宽度和高度都大于80像素
                if (rect.Width > 80 && rect.Height > 80)
                {
                    index = i; // 记录找到的目标轮廓的索引
                    // 在模板图像上绘制找到的目标轮廓,标记为红色
                    Cv2.DrawContours(template, contours, i, new Scalar(0, 0, 255), -1);
                    break; // 找到目标轮廓后跳出循环
                }
            }
            Cv2.ImShow("template", template);

            //遍历测试图像中的轮廓做轮廓匹配
            Point[][] contours2; //轮廓查找结果变量
            HierarchyIndex[] hierarchy2; //轮廓拓扑结构变量

            Cv2.FindContours(grayTest, out contours2, out hierarchy2, RetrievalModes.External,
                                            ContourApproximationModes.ApproxNone);

            //Console.WriteLine("contour2_size = {0}", contours2.Length); //输出轮廓个数
            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) //找到目标轮廓,跳出循环
                {
                    // 计算轮廓匹配值
                    double matchValue = Cv2.MatchShapes(contours[index], contours2[i], ShapeMatchModes.I3);
                    // 输出匹配值
                    Console.WriteLine("matchRate = {0}", matchValue);
                    // 如果匹配值在一定阈值内,绘制匹配的轮廓
                    if (matchValue <= 2)
                        Cv2.DrawContours(imgTest, contours2, i, new Scalar(0, 255, 0), -1);
                }
            }
            Cv2.ImShow("match-result", imgTest);
            Cv2.WaitKey(0);
        }
    }
}

3. Summary of the coding process:

  • Read template image and test image.
  • Create variables that store the grayscale template and test images grayTempand grayTest.
  • Convert the image to a grayscale image.
  • Binarize the template image and test image to segment the contour areas in the image.
  • contoursDefine the variables and to store the contour results and topology hierarchy.
  • Use to Cv2.FindContoursfind the contour in the template image, store it in contours, and also get the topology of the contour.
  • Traverse contoursthe array, find the target outline that meets the conditions (here, the width and height are both greater than 80 pixels), and draw the target outline on the template image.
  • Use to Cv2.ImShowdisplay the template image with the markup.

Guess you like

Origin blog.csdn.net/m0_55074196/article/details/132492555