如何在 OpenCV Python 中匹配图像形状?
opencvpythonserver side programmingprogramming
我们使用 cv2.matchShapes() 函数来匹配两个图像形状。此函数返回一个度量,显示图像形状之间的相似性。此函数使用 Hu-Moments 来计算度量值。度量值越低,图像形状之间的相似度越高。
在下面的例子中,我们将匹配来自不同图像的形状以及来自单个图像的形状。
语法
我们使用以下语法来匹配两个图像形状 -
ret = cv2.matchShapes(cnt1,cnt1,1,0.0)
其中,
cnt1 - 第一个图像形状的轮廓点。
cnt2 - 第二个图像形状的轮廓点
步骤
您可以使用以下步骤匹配两个图像形状 -
导入所需的库。在以下所有 Python 示例中,所需的 Python 库是 OpenCV。确保您已经安装了它。
import cv2
使用 cv2.imread() 将输入图像读取为灰度图像。
img1 = cv2.imread('star.png',0) img2 = cv2.imread('star1.png',0)
对灰度图像应用阈值以创建二值图像。
ret,thresh1 = cv2.threshold(img1,150,255,0) ret,thresh2 = cv2.threshold(img1,150,255,0)
使用查找二值图像中形状的轮廓cv2.findContours() 函数。
contours1, _ = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours2, _ = cv2.findContours(thresh2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
从每幅图像中选择特定轮廓,并应用形状匹配函数 cv2.matchShapes() 传递所选轮廓。
cnt1=contours1[0] cnt2=contours2[0] ret12 = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
打印结果值,即图像形状匹配度量。值越低,匹配越好。
print("匹配图像 1 与图像 2:", ret12)
让我们看一些例子以便更好地理解。
示例 1
在此程序中,我们匹配两个图像形状。每个图像包含一个形状。我们还将每个图像中的形状与其自身进行匹配。
# 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(contours)) cnt1 = contours1[0] contours2,hierarchy = cv2.findContours(thresh2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of Shapes detected in Image 2:",len(contours)) 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)
将下面的图像视为上述程序中提到的"star.png"和"pentagon.png"的输入图像。
输出
执行时,上述代码将产生以下输出 −
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
示例 2
在此程序中,我们匹配图像中的形状。我们在图像中检测到三种形状。
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()
我们将在此程序中使用以下图像和输入文件 -
输出
执行时,上述代码将产生以下输出 -
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
我们得到以下窗口,显示输出 -
根据上述结果,我们得出结论,形状 1 与形状 2 的相似度高于形状 3。