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 bounding 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 the image.
  • maxval: The new value to be set for the pixel value after the threshold.
  • type: The type of threshold processing, there are different processing methods, such as binary threshold, anti-binary threshold, truncation threshold, etc.

Common types of thresholding include:

  • ThresholdTypes.Binary: Set to maxval if the pixel value is greater than or equal to the threshold, otherwise 0.
  • ThresholdTypes.BinaryInv: Set to maxval if the pixel value is less than the threshold, 0 otherwise.
  • 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.Otsu:The Otsu method is a method for automatically determining image binarization thresholds. 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: Triangulation method,A threshold selection method based on the image histogram. By finding a straight line in the histogram, the histogram is divided into two parts to minimize the area between the two parts. Thus the threshold is obtained.

Point[][] contours: A two-dimensional array represents multiple contours. Each contour consists of a set of point coordinates, so the contours variable stores multiple contours.

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

Find Contours Cv2.FindContours()

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

Point[][] contours; // Array of point coordinates to store contours
HierarchyIndex[] hierarchy; //Storage topological relationships between contours

Cv2.FindContours(
    input: binaryImage, // Binary image, white pixels represent objects, black pixels represent background
    contours: out contours, // store the coordinates of the found contour points
    hierarchy: out hierarchy, // stores topological relationships between contours
    mode: RetrievalModes.External, //Contour retrieval mode, here means only retrieving external contours
    method: ContourApproximationModes.ApproxNone // Contour approximation method, here means not approximating the contour
);
  • 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 found contours. 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 bounding rectangle Cv2.BoundingRect();

Rect variable name = Cv2.BoundingRect(InputArray points);

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

Returns a Rect object 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 collection containing an array of Point.
  • contourIdx: Index of the contour to be drawn. If negative, all contours are drawn.
  • color: The color of the outline.
  • thickness: The width of the outline. The remaining 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 an option in the ContourMatchModes enumeration.
  • parameter: Parameters required by the calculation method.

Return value: This method returns a double type of similarity measure value, used to represent the similarity between two contours. The smaller the value, the more similar the shapes are.

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 outline matching lookup template
{
    class Program
    {
        static void Main(string[] args)
        {
            //Read image
            Mat template = Cv2.ImRead("C:/Users/CGW/source/repos/contour matching search template_Color Space/contour matching search template_Color Space/imgs/0.bmp"); //Read template image
            Mat imgTest = Cv2.ImRead("C:/Users/CGW/source/repos/contour matching search template_Color Space/contour matching search template_Color Space/imgs/4.bmp"); //Read the test image

            Mat grayTemp = new Mat(); // Template image
            Mat grayTest = new Mat(); // test image

            //Convert to grayscale image
            Cv2.CvtColor(template, grayTemp, ColorConversionCodes.BGR2GRAY);
            Cv2.CvtColor(imgTest, grayTest, ColorConversionCodes.BGR2GRAY);

            //Binarization--segment the contour area
            Cv2.Threshold(grayTemp, grayTemp, 90, 255, ThresholdTypes.Binary);
            Cv2.Threshold(grayTest, grayTest, 90, 255, ThresholdTypes.Binary);

            Point[][] contours; // Variable to store contours
            HierarchyIndex[] hierarchy; // Variable to store outline topology

            // Use the FindContours function to find contours in the image, return a set of contour arrays contours, and also obtain the topological structure of the contours.
            Cv2.FindContours(grayTemp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);

            int index = 0; //Contour number of the cross contour in the template
            //Iterate through each contour
            for (int i = 0; i < contours.Length; i + + )
            {
                // Get the bounding rectangle of the outline
                Rect rect = Cv2.BoundingRect(contours[i]);

                // Determine whether the outline meets the conditions, such as both width and height are greater than 80 pixels
                if (rect.Width > 80 & amp; & rect.Height > 80)
                {
                    index = i; // Record the index of the found target contour
                    // Draw the found target contour on the template image, marked in red
                    Cv2.DrawContours(template, contours, i, new Scalar(0, 0, 255), -1);
                    break; // Break out of the loop after finding the target contour
                }
            }
            Cv2.ImShow("template", template);

            //Traverse the contours in the test image to perform contour matching
            Point[][] contours2; //Contour search result variable
            HierarchyIndex[] hierarchy2; //Contour topology variable

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

            //Console.WriteLine("contour2_size = {0}", contours2.Length); //Output the number of contours
            for (int i = 0; i < contours2.Length; i + + )
            {
                Rect rect = Cv2.BoundingRect(contours2[i]);

                //Only those whose width and height match the width and height of the template outline will be matched, and interference outlines will be eliminated.
                if (rect.Width >= 80 & amp; & amp; rect.Width <= 100 & amp; & amp; rect.Height > 80 & amp; & amp; rect.Height <= 100) //Find the target contour, Break out of loop
                {
                    // Calculate contour matching value
                    double matchValue = Cv2.MatchShapes(contours[index], contours2[i], ShapeMatchModes.I3);
                    // Output matching value
                    Console.WriteLine("matchRate = {0}", matchValue);
                    // If the matching value is within a certain threshold, draw the matching outline
                    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 code process:

  • Read template images and test images.
  • Create variables grayTemp and grayTest that store the grayscale template and test images.
  • Convert the image to grayscale.
  • Binarize the template image and test image to segment the contour areas in the image.
  • Define variables contours and hierarchy that store contour results and topology.
  • Use Cv2.FindContours to find contours in the template image, stored in contours, and also get the topology of the contour.
  • Traverse the contours array, find the target contour that meets the conditions (here, the width and height are both greater than 80 pixels), and draw the target contour on the template image.
  • Use Cv2.ImShow to display a tagged template image.