在Python中尝试使用OpenCV的cv2.matchShapes()函数

6
我在白板上画了一幅随机图案,NAO机器人拍摄了照片并试图重新绘制同样的图案。
我的绘画: enter image description here NAO的绘画: enter image description here 此时,我想写一些关于它的结论,具体来说,我想从两张图片中提取轮廓,并使用OpenCV函数cv2.matchShapes()匹配这些轮廓。
然而,我为此编写了一个小的Python代码脚本,但它给了我一些错误。以下是代码:
import numpy as np
import cv2

#get the pictures from the forlder
original = cv2.imread('eightgon.jpg')
drawn = cv2.imread('eightgon1.jpg')

#make them gray    
originalGray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
drawnGray = cv2.cvtColor(drawn, cv2.COLOR_BGR2GRAY)

#apply erosion
kernel = np.ones((2, 2),np.uint8)
originalErosion = cv2.erode(originalGray, kernel, iterations = 1)
drawnErosion = cv2.erode(drawnGray, kernel, iterations = 1)

#retrieve edges with Canny
thresh = 175
originalEdges = cv2.Canny(originalErosion, thresh, thresh*2)
drawnEdges = cv2.Canny(drawnErosion, thresh, thresh*2)

#extract contours
originalContours, Orighierarchy = cv2.findContours(originalEdges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
drawnContours, Drawnhierarchy = cv2.findContours(drawnEdges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

print cv2.matchShapes(drawnContours,originalContours,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

当我运行这段简单的代码时,它返回了以下错误:
File "C:/Python27/getResults.py", line 32, in <module>
    ret = cv2.matchShapes(drawnContours,originalContours,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)
TypeError: contour1 is not a numpy array, neither a scalar

由于错误提示我轮廓应该是数组..所以我对代码进行了轻微的更改,像这样:

cnt1 = np.asarray(drawnContours, np.int0)
cnt2 = np.asarray(originalContours, np.int0)
print cv2.matchShapes(cnt1,cnt2,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

在这种情况下,它返回给我这个错误:ValueError: setting an array element with a sequence. 我做错了什么? 任何帮助都将不胜感激!

顺便提一下,你正在尝试“使用”matchShapes(),而不是“实现”它(这已经完成了)。 - berak
抱歉,我的英语不太好。 - Francesco Sgaramella
3个回答

4

我曾经遇到过类似的问题。match shapes函数只接受一个轮廓对,而不是整个轮廓容器对。

cv2.matchShapes(drawnContours[i], originalContours[i], cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

希望这可以帮到您。

文档声称matchShapes还需要一对图像。您如何将任意数量的轮廓信息组合起来? - jtlz2
@jtlz2 - 一对图像可以工作,但不支持图像/轮廓数组。 - Divyanshu Grover

2
在这里,drawnContoursoriginalContours 是包含在图像中的轮廓列表。 使用 drawnContours[i]originalContours[i] 来表示特定的轮廓,其中 i = 0,1,2...n-1,n 是图像中轮廓的总数。

例如,

print cv2.matchShapes(
    drawnContours[0], originalContours[0], 
    cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

要获取图像中轮廓的总数,请使用以下命令:
n = len(drawnContours)  # n is the number of contours
print n

-3

检查opencv版本,旧版本可能具有不同的matchShapes或findContours API。

很遗憾,一些NAO软件发布包含了相当古老的opencv版本。

考虑更新您的NAO软件,或尝试获取一些beta版本...


matchShapes 调用中实际上存在问题,他提供了所有轮廓的完整列表。 - EpixyCoder101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接