How to match image shapes in OpenCV Python?

We use cv2.matchShapes() function to match two image shapes in OpenCV. This function returns a metric showing the similarity between the image shapes using Hu-Moments to calculate the metric value. Lower the metric value, higher the similarity between the image shapes.

In the following examples, we will match the shapes from different images and also shapes from a single image.

Syntax

We use the following syntax to match two image shapes ?

ret = cv2.matchShapes(cnt1, cnt2, method, parameter)

Where,

  • cnt1 ? The contour points of the first image shape.

  • cnt2 ? The contour points of the second image shape.

  • method ? Comparison method (1, 2, or 3 for different Hu-moment variants).

  • parameter ? Method-specific parameter (typically 0.0).

Steps

You can use the following steps to match two image shapes ?

Step 1: Import the required library. In all the following Python examples, the required Python library is OpenCV. Make sure you have already installed it.

import cv2

Step 2: Read the input images as grayscale images using cv2.imread().

img1 = cv2.imread('star.png', 0)
img2 = cv2.imread('star1.png', 0)

Step 3: Apply thresholding on the grayscale images to create binary images.

ret, thresh1 = cv2.threshold(img1, 150, 255, 0)
ret, thresh2 = cv2.threshold(img2, 150, 255, 0)

Step 4: Find the contours of the shapes in the binary images using cv2.findContours() function.

contours1, _ = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours2, _ = cv2.findContours(thresh2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Step 5: Select the particular contour from each image and apply the shape match function cv2.matchShapes() passing the selected contours.

cnt1 = contours1[0]
cnt2 = contours2[0]
ret12 = cv2.matchShapes(cnt1, cnt2, 1, 0.0)

Step 6: Print the result value, the image shape matching metric. The lower the value, the better matching it is.

print("Matching Image 1 with Image 2:", ret12)

Let's have a look at some examples for a better understanding.

Example 1: Matching Shapes from Different Images

In this program, we match two image shapes. Each image contains a single shape. We also match the shape with itself from each image ?

# import required libraries
import cv2

# Read two images as grayscale images
img1 = cv2.imread('star.png', 0)
img2 = cv2.imread('star1.png', 0)

# Apply thresholding on the images to convert to binary images
ret, thresh1 = cv2.threshold(img1, 127, 255, 0)
ret, thresh2 = cv2.threshold(img2, 127, 255, 0)

# find the contours in the binary image
contours1, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print("Number of Shapes detected in Image 1:", len(contours1))
cnt1 = contours1[0]

contours2, hierarchy = cv2.findContours(thresh2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print("Number of Shapes detected in Image 2:", len(contours2))
cnt2 = contours2[0]

# Compute the match scores
ret11 = cv2.matchShapes(cnt1, cnt1, 1, 0.0)
ret22 = cv2.matchShapes(cnt2, cnt2, 1, 0.0)
ret12 = cv2.matchShapes(cnt1, cnt2, 1, 0.0)

# print the matching scores
print("Matching Image 1 with itself:", ret11)
print("Matching Image 2 with itself:", ret22)
print("Matching Image 1 with Image 2:", ret12)

Consider the below images as the input images mentioned as 'star.png' and 'pentagon.png' in the above program.

Output

On execution, the above code will produce the following output ?

Number of Shapes detected in Image 1: 1 
Number of Shapes detected in Image 2: 1 
Matching Image 1 with itself: 0.0 
Matching Image 2 with itself: 0.0 
Matching Image 1 with Image 2: 0.6015851094057714

Example 2: Matching Multiple Shapes in Single Image

In this program, we match the shapes in a single image. We detect three shapes in the image and compare their similarities ?

import cv2
import numpy as np

img = cv2.imread('convexhull.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 100, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print("Number of Shapes detected:", len(contours))

# draw contour and shape number
for i, cnt in enumerate(contours):
   M = cv2.moments(cnt)
   x1, y1 = cnt[0, 0]
   img1 = cv2.drawContours(img, [cnt], -1, (0, 255, 255), 3)
   cv2.putText(img1, f'Shape:{i+1}', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

cnt1 = contours[0]
cnt2 = contours[1]
cnt3 = contours[2]

ret11 = cv2.matchShapes(cnt1, cnt1, 1, 0.0)
ret12 = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
ret23 = cv2.matchShapes(cnt2, cnt3, 1, 0.0)
ret31 = cv2.matchShapes(cnt3, cnt1, 1, 0.0)

print("Matching Shape 1 with itself:", ret11)
print("Matching Shape 1 with Shape 2:", ret12)
print("Matching Shape 2 with Shape 3:", ret23)
print("Matching Shape 3 with Shape 1:", ret31)

cv2.imshow("Shapes", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output

On execution, the above code will produce the following output ?

Number of Shapes detected: 3 
Matching Shape 1 with itself: 0.0 
Matching Shape 1 with Shape 2: 0.15261042892128207 
Matching Shape 2 with Shape 3: 0.9192709496955178 
Matching Shape 3 with Shape 1: 0.7521097407160106

On the basis of the above result, we conclude that Shape 1 is more similar to Shape 2 than Shape 3, as indicated by the lower matching score of 0.152 compared to 0.752.

Key Points

  • A score of 0.0 indicates perfect match (identical shapes)

  • Lower scores indicate higher similarity between shapes

  • The function uses Hu-Moments which are invariant to translation, rotation, and scaling

  • Method parameter 1, 2, or 3 corresponds to different Hu-moment comparison techniques

Conclusion

The cv2.matchShapes() function provides an effective way to compare shape similarities using Hu-Moments. Lower metric values indicate higher similarity, with 0.0 representing identical shapes.

Updated on: 2026-03-26T22:01:55+05:30

8K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements