有没有办法增加cv2.findContours返回的点数?
Is there a way to increase the amount of points returned by cv2.findContours?
对于我尝试匹配拼图的项目,我编写了一些代码来确定拼图每一面的缩进(向内和向外)。我添加了两个示例图像来显示结果。
Inward indentation
Outward indentation
所有缩进都被很好地检测到,但它的准确性并不总是像预期的那样。我认为这是由于 cv2.findContours() 仅提供有限数量的点数。我提供了 cv2.findContours().
的代码
imshape = l.getImageShape(image)
ret, thresh = cv2.threshold(imshape, 0, 254, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
我选择只使用带有 RETR_EXTERNAL 的外部线条,因为这些是唯一需要的轮廓。我还决定用 CHAIN_APPROX_NONE 保存每个点,即使我真的不需要侧面直线部分的很多信息。但是,CHAIN_APPROX_SIMPLE 也删除了关键(缩进)部分的一些点,进一步降低了准确性。
第一个函数 getImageShape 只是简单地以与 thresh 类似的方式获取形状,但我发现我提前使用它获得了更好的结果,而不是仅仅将源图像作为 [=43= 的输入参数] 前面代码中的函数。
def getImageShape(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, ksize=5)
thresh = cv2.threshold(gray, 0, 254, cv2.THRESH_BINARY)[1]
thresh = cv2.blur(thresh, ksize=(3, 3))
return thresh
由于准确性较差(拼图一侧 width/height 的误差约为 4%),仅根据缩进位置将两侧相互匹配会导致多个 'possible' 解决方案.我希望有一种方法可以 增加 cv2.getContours 返回的点数 但在 openCV 文档中没有找到任何关于它的信息。
如果这不可能,我将不得不添加一些图像连续性检测算法(但这会使它无法仅通过形状来匹配碎片)。
提前致谢!
如果我可以建议一个替代方案:
您可以尝试通过使用 Sobel
或 Prewitt
过滤器计算图像梯度来使轮廓可见,并在进行一些简单的后处理后使用 Canny
边缘检测。
这是我使用它的结果,请注意,我使用了你提供的带有轮廓标记的图片,所以请忽略那个小的不一致。
对于我尝试匹配拼图的项目,我编写了一些代码来确定拼图每一面的缩进(向内和向外)。我添加了两个示例图像来显示结果。
Inward indentation
Outward indentation
所有缩进都被很好地检测到,但它的准确性并不总是像预期的那样。我认为这是由于 cv2.findContours() 仅提供有限数量的点数。我提供了 cv2.findContours().
的代码imshape = l.getImageShape(image)
ret, thresh = cv2.threshold(imshape, 0, 254, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
我选择只使用带有 RETR_EXTERNAL 的外部线条,因为这些是唯一需要的轮廓。我还决定用 CHAIN_APPROX_NONE 保存每个点,即使我真的不需要侧面直线部分的很多信息。但是,CHAIN_APPROX_SIMPLE 也删除了关键(缩进)部分的一些点,进一步降低了准确性。
第一个函数 getImageShape 只是简单地以与 thresh 类似的方式获取形状,但我发现我提前使用它获得了更好的结果,而不是仅仅将源图像作为 [=43= 的输入参数] 前面代码中的函数。
def getImageShape(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, ksize=5)
thresh = cv2.threshold(gray, 0, 254, cv2.THRESH_BINARY)[1]
thresh = cv2.blur(thresh, ksize=(3, 3))
return thresh
由于准确性较差(拼图一侧 width/height 的误差约为 4%),仅根据缩进位置将两侧相互匹配会导致多个 'possible' 解决方案.我希望有一种方法可以 增加 cv2.getContours 返回的点数 但在 openCV 文档中没有找到任何关于它的信息。
如果这不可能,我将不得不添加一些图像连续性检测算法(但这会使它无法仅通过形状来匹配碎片)。
提前致谢!
如果我可以建议一个替代方案:
您可以尝试通过使用 Sobel
或 Prewitt
过滤器计算图像梯度来使轮廓可见,并在进行一些简单的后处理后使用 Canny
边缘检测。
这是我使用它的结果,请注意,我使用了你提供的带有轮廓标记的图片,所以请忽略那个小的不一致。