我需要在图像中绘制轮廓,因此我使用了函数cv2.polylines
在点之间绘制线,但是我不知道为什么会出现错误,例如未定义d
(d
是包含点(x, y)
集的列表。
import xml.dom.minidom
import cv2
import numpy as np
import matplotlib.pyplot as plt
def main(file):
doc = xml.dom.minidom.parse(file)
values = doc.getElementsByTagName("coordinateIndex")
coordX = doc.getElementsByTagName("x")
coordY = doc.getElementsByTagName("y")
d = {}
for atr_value, atr_x, atr_y in zip(values, coordX, coordY):
value = atr_value.getAttribute('value')
x = atr_x.getAttribute('value')
y = atr_y.getAttribute('value')
d[value] = [x, y]
return d
image = cv2.imread('1.631791322.58809740.14.834982.40440.3641459051.955.6373933.1920.jpeg')
point=d
cv2.polylines(image,
point,
isClosed = False,
color = (0,255,0),
thickness = 3,
linetype = cv2.LINE_AA)
imshow("image",image)
result = main('1.631791322.58809740.14.834982.40440.3641459051.955.6373933.1920.xml')
print(result)
这是一个示例XML文件:
<?xml version="1.0" ?>
<TwoDimensionSpatialCoordinate>
<coordinateIndex value="0"/>
<x value="302.6215607602997"/>
<y value="166.6285651861381"/>
<coordinateIndex value="1"/>
<x value="3.6215607602997"/>
<y value="1.6285651861381"/>
</TwoDimensionSpatialCoordinate>
这里有几个问题。
首先,通过d
创建字典d = {}
。 d[value] = [x, y]
,即d
是not列表。
第二,“ d
未定义”,因为d
是您的main
方法中的局部变量。当您调用result = main(...)
时,result
将反映d
的值。
第三,cv2.polylines
需要一个NumPy整数对数组。您具有以字符串形式存储在XML中的浮点值。
因此,现在让我们找到一种解决这些问题的方法:首先,我们将坐标转换为float
(并重命名您的方法,因为main
对于此类函数是错误的选择):
import xml.dom.minidom
import cv2
import numpy as np
def extract(file):
doc = xml.dom.minidom.parse(file)
values = doc.getElementsByTagName("coordinateIndex")
coordX = doc.getElementsByTagName("x")
coordY = doc.getElementsByTagName("y")
d = {} # <-- That's a dictionary!
for atr_value, atr_x, atr_y in zip(values, coordX, coordY):
value = atr_value.getAttribute('value')
x = float(atr_x.getAttribute('value')) # <-- to float
y = float(atr_y.getAttribute('value')) # <-- to float
d[value] = [x, y]
return d
然后,我们重新安排图像加载,并在脚本中进行坐标提取:
# Read image; extract coordinates from XML
image = cv2.imread('path/to/your/image.png')
dd = extract('path/to/your/file.xml') # <-- That's a dictionary!
最后,我们将您的字典转换为某些NumPy数组,将float值转换为某些int类型,并正确调用cv2.polylines
:
# Convert dictionary values to int NumPy array (needed for cv2.polylines)
pts = np.array(list(dd.values())).astype(np.int32) # <-- to int
# Draw polygon lines
image = cv2.polylines(image,
[pts],
isClosed=False,
color=(0, 255, 0),
thickness=3,
lineType=cv2.LINE_AA)
# Show result
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
我在您的示例XML中又添加了两个点,并使用了我的默认测试图像-这是输出:
希望有帮助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.2.0
----------------------------------------