cv2.fitEllipse 创建一个与应有的完全不同的椭圆

cv2.fitEllipse creates an ellipse totally different from what it should be

我想在不同的集群周围设置椭圆。到目前为止,我使用 cv2.fit Ellipse 并且效果很好。但是我发现一个椭圆有问题(超过 100 个)。 这是重现意外行为的代码示例。

import numpy as np
import cv2
import itertools
import matplotlib.pyplot as mpl

test=np.zeros((40,40))
test[27,12]=1
test[28,11:13]=1
test[29,11:14]=1
test[30,10:14]=1
test[31,11:14]=1
test[32,12:14]=1
test[33,13]=1

def getContours(clusters):
        map_contour=np.ones(clusters.shape).astype(np.uint8)
        int_cnts=[]
        for label in np.unique(clusters):
                # if the label is zero, we are examining the 'background'
                if label == 0:
                        continue
                mask = np.zeros(test.shape, dtype="uint8")
                mask[clusters == label] = 255
                cnts, hierarchy = \
                        cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
                int_cnts.append(cnts)
                c = max(cnts, key=cv2.contourArea)
                cv2.drawContours(map_contour, cnts, 0, (0, 255, 0), 1)
        list_contours=list(itertools.chain.from_iterable(int_cnts))
        return list_contours, map_contour

list_test,map_test=getContours(test)

info=np.zeros((len(list_test),5))
map_ellipse=np.ones(test.shape).astype(np.uint8)
for index,cnt in enumerate(list_test):
        ellipse=cv2.fitEllipse(cnt)
        info[index,0:2],info[index,2:4],info[index,4] = ellipse
        cv2.ellipse(map_ellipse,ellipse,(255,0,0))

print cnt
print ellipse

mpl.contourf(map_ellipse)
mpl.contour(test)
mpl.show()

cnt 给出:

array([[[12,  27]],

       [[11,  28]],

       [[11,  29]],

       [[10, 30]],

       [[13, 33]],

       [[13,  29]],

       [[12,  28]]], dtype=int32)

椭圆是:

((23.71430015563965, -20.397018432617188),
 (8.957982063293457, 98.63383483886719),
 0.0)

如您所见,如果您 copy/paste 和 运行 上面的代码,椭圆的顶部(切成两半)似乎与它应该代表的区域完全断开(左上方)。 我不知道代码有什么问题,特别是因为它适用于同一图片中的其他形式。 因此,我们将不胜感激!

如果您认为这是一个有趣的问题而您无法回答它,请点赞它以便它获得更多的知名度并且我可能有机会得到答案。非常感谢!

编辑:如果有帮助,出于某种原因,当我设置 test[30,9:14]=1 而不是 test[30,10:14]=1 时,椭圆的位置和大小要好得多(尽管不够好)。但是当我改用 test[30,9:14]=1 时,椭圆现在又变大了并且位于左上角。这种对一个像素的敏感度并没有真正改变表格的形状是非常出色的。

我终于知道是怎么回事了。由于近似cv2.CHAIN_APPROX_SIMPLE,计算椭圆的点数太少

如果我使用cv2.CHAIN_APPROX_NONE,问题就解决了,它考虑到了轮廓的所有点。