最近有一批图片上的目标是用多边形近似的,由于想做分割的一些事,所以需要对其处理一下,把这个多边形包围的区域全部置为255,现在有labelme这个工具可以在用多边形近似目标后就会自动生成分割图,但我的却是有标注好的多边形,但没有分割图,找来找去也没有好的解决方法,最后想到多边形的已经知道了,我可以用opencv中的多边形填充函数fillpoly呀,于是就写了个小程序来处理得到分割图。
我的图片上的目标原始标记文本如下:
好了看了上面的数据结构,下面就来用程序把这些多边形(实际是多边形的顶点)取出来,然后再使用opencv多边形填充函数执行填充操作就可以了。所有执行程序如下:
def GetAnnotPolygonPoints(AnotPath):
tree = ET.ElementTree(file=AnotPath) # open xml
root = tree.getroot()
labesNode=root.find('labels')
labels=labesNode.findall('label')
Polygons=[]
for label in labels:
name=label.find('name').text
print(name)
pointsNode=label.find('points')
points=pointsNode.findall('point')
Polygon={}
Points=[]
for point in points:
x=float(point.find('x').text)
y=float(point.find('y').text)
Points.append([int(x),int(y)])
Polygon[name]=Points
Polygons.append(Polygon)
return Polygons
if __name__ == '__main__':
MainDir='/OriginalData'
AnnotDir =os.path.join(MainDir,'OriginalAnnotSet')
ImDir=os.path.join(MainDir,'OriginalImSet')
SegImDir=os.path.join(MainDir,'OriginalSegImSet')
AnnotNames = os.listdir(AnnotDir)
AnnotNames.sort()
for AnnotName in AnnotNames[:]:
ImName=AnnotName[:-4]+'.jpg'
AnnotPath=os.path.join(AnnotDir,AnnotName)
ImPath=os.path.join(ImDir,ImName)
Polygons=GetAnnotPolygonPoints(AnnotPath)
Im0=cv2.imread(ImPath)
print(Im0.shape)
Im=np.zeros(Im0.shape[:-1],np.uint8)
for Polygon in Polygons[:]:
Keys=Polygon.keys()
Points=np.array(Polygon.values())
try:
cv2.fillPoly(Im, Points, (255, 255, 255))#只使用这个函数可能会出错,不知道为啥
except:
try:
cv2.fillConvexPoly(Im,Points,(255, 255, 255))#上面出现错误时使用这个可以执行,不知道为啥
except:
continue
SegImPath=os.path.join(SegImDir,ImName)
cv2.imwrite(SegImPath,Im)
print('doing segment {}\n'.format(ImName))
#cv2.imshow('tst',Im)
#cv2.waitKey()
由于代码比较简单,没有太多注解