我想在不同的簇周围放置椭圆。到现在为止,我使用了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)
正如您所看到的,如果您复制/粘贴并运行上面的代码,椭圆的顶部(切成两半)似乎与它应该代表的区域完全断开(左上角)。 我不知道代码有什么问题,特别是因为它适用于同一图片中的其他表单。 因此,非常感谢任何帮助!
如果您认为这是一个有趣的问题并且您无法回答它,请进行投票,以便获得更多可见性,我可能有机会得到答案。非常感谢你!
编辑:如果它可以提供帮助,由于某种原因,当我设置test[30,9:14]=1
而不是test[30,10:14]=1
时,椭圆的位置和大小(虽然不够好)会更好。但是当我使用test[30,9:14]=1
代替时,椭圆现在再次变大并位于左上角。这种对一个像素的敏感度并没有真正改变形状的形状。
答案 0 :(得分:0)
我终于找到了发生的事情。由于近似cv2.CHAIN_APPROX_SIMPLE,用于计算椭圆的点数太小。
如果我使用cv2.CHAIN_APPROX_NONE来解决问题,它会考虑轮廓的所有点。