使用opencv检测到的轮廓转dxf
The contour detected using opencv to dxf
我使用 opencv 来检测 Python 中的轮廓。我通过搜索编写了将此轮廓保存为 dxf 文件的代码,如下所示。
cap = EasyPySpin.VideoCapture(0)
_, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
frame = cv2.resize(frame, dsize=(0,0), fx=0.26, fy=0.26, interpolation=cv2.INTER_AREA)
frame_blr = cv2.GaussianBlur(frame, (3, 3), 0)
canny = cv2.Canny(frame_blr, 255, 0)
contours, hierarchy=cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours_draw = cv2.drawContours(frame, contours, -1, (0, 255, 0), 1)
cv2.imshow('contour', contours_draw)
contours = [np.squeeze (cnt, axis = 1) for cnt in contours]
ctr = contours[1]
dwg = ezdxf.new ('R2010') # create a new DXF R2010 drawing, official DXF version name: 'AC1024'
msp = dwg.modelspace () # add new entities to the model space
dwg.layers.new (name = 'MyLines', dxfattribs = {'color': 3}) # 3 = Green
for i in range (len (ctr)):
n = i + 1
if n>= len (ctr):
n = 0
msp.add_line (ctr [i], ctr [n], dxfattribs = {'layer': 'MyLines'}) # add a LINE entity
print (ctr [i], '->', ctr [n])
dwg.saveas ('line.dxf')
但是检测到的轮廓和dxf文件中画的线不一样。此外,每次 runs.I 不知道为什么,dxf 文件中都会绘制一条略有不同的线。
轮廓图像 > enter image description here
DXF 文件 > enter image description here
而且我不知道这段代码是什么意思。
contours = [np.squeeze (cnt, axis = 1) for cnt in contours]
ctr = contours[1]
如果我删除此代码并将 crt 编辑为等高线,则会出现以下错误。
Traceback (most recent call last):
File "c:/Users/MyPc/KHS/p40.contour detection, (x,y).py", line 38, in <module>
msp.add_line (contours [i], contours [n], dxfattribs = {'layer': 'MyLines'}) # add a LINE entity
File "C:\Users\MyPc\AppData\Local\Programs\Python\Python38\lib\site-packages\ezdxf\graphicsfactory.py", line 121, in add_line
dxfattribs["start"] = Vec3(start)
File "src\ezdxf\acc\vector.pyx", line 417, in ezdxf.acc.vector.Vec3.__cinit__
TypeError: invalid argument count
设置
>>> import cv2
... import numpy as np
... frame = cv2.imread("cyan quick_3_MAD.png")
>>> canny = cv2.Canny(frame, 255, 0)
>>> contours, hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
>>> contours_draw = cv2.drawContours(frame, contours, -1, (0, 255, 0), 1)
>>> cv2.imwrite("out.png", contours_draw)
输出:
什么是 np.squeeze
?
对于这个例子,等高线看起来像这样:
>>> print(str(contours)[:400])
[array([[[629, 568]],
[[629, 569]],
[[629, 570]],
...
>>> len(contours)
188
>>> contours[0].shape
(59, 1, 2)
使用np.squeeze
后,删除了不必要的1尺寸轴。
squeezed = [np.squeeze(cnt, axis=1) for cnt in contours]
>>> len(squeezed)
188
>>> squeezed[0].shape
(59, 2)
引用文档np.squeeze
numpy.squeeze(a, axis=None)
Remove axes of length one from a.
关键部分
您使用了ctr = contours[1]
,这意味着您仅在多个轮廓中绘制列表中的第一个轮廓。
相反,您需要遍历轮廓并绘制它具有的每个轮廓。
>>> import ezdxf
... dwg = ezdxf.new("R2010")
... msp = dwg.modelspace()
... dwg.layers.new(name="greeny green lines", dxfattribs={"color": 3})
>>> for ctr in squeezed:
... for n in range(len(ctr)):
... if n >= len(ctr) - 1:
... n = 0
... try:
... msp.add_line(ctr[n], ctr[n + 1], dxfattribs={"layer": "greeny green lines", "lineweight": 20})
... except IndexError:
... pass
>>> dwg.saveas("output.dxf")
输出:
更新
要翻转图像,我们只需反转 y 值即可。
由于 squeezed
是包含计数的 np 数组列表,我们可以简单地将向量 [1, -1]
乘以它以翻转 y 轴上的值。
>>> inverted_squeezed = [arr * [1, -1] for arr in squeezed]
>>> for ctr in inverted_squeezed:
... for n in range(len(ctr)):
... if n >= len(ctr) - 1:
... n = 0
... try:
... msp.add_line(ctr[n], ctr[n + 1], dxfattribs={"layer": "greeny green lines", "lineweight": 20})
... except IndexError:
... pass
>>> dwg.saveas("output.dxf")
我使用 opencv 来检测 Python 中的轮廓。我通过搜索编写了将此轮廓保存为 dxf 文件的代码,如下所示。
cap = EasyPySpin.VideoCapture(0)
_, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
frame = cv2.resize(frame, dsize=(0,0), fx=0.26, fy=0.26, interpolation=cv2.INTER_AREA)
frame_blr = cv2.GaussianBlur(frame, (3, 3), 0)
canny = cv2.Canny(frame_blr, 255, 0)
contours, hierarchy=cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours_draw = cv2.drawContours(frame, contours, -1, (0, 255, 0), 1)
cv2.imshow('contour', contours_draw)
contours = [np.squeeze (cnt, axis = 1) for cnt in contours]
ctr = contours[1]
dwg = ezdxf.new ('R2010') # create a new DXF R2010 drawing, official DXF version name: 'AC1024'
msp = dwg.modelspace () # add new entities to the model space
dwg.layers.new (name = 'MyLines', dxfattribs = {'color': 3}) # 3 = Green
for i in range (len (ctr)):
n = i + 1
if n>= len (ctr):
n = 0
msp.add_line (ctr [i], ctr [n], dxfattribs = {'layer': 'MyLines'}) # add a LINE entity
print (ctr [i], '->', ctr [n])
dwg.saveas ('line.dxf')
但是检测到的轮廓和dxf文件中画的线不一样。此外,每次 runs.I 不知道为什么,dxf 文件中都会绘制一条略有不同的线。
轮廓图像 > enter image description here DXF 文件 > enter image description here
而且我不知道这段代码是什么意思。
contours = [np.squeeze (cnt, axis = 1) for cnt in contours]
ctr = contours[1]
如果我删除此代码并将 crt 编辑为等高线,则会出现以下错误。
Traceback (most recent call last):
File "c:/Users/MyPc/KHS/p40.contour detection, (x,y).py", line 38, in <module>
msp.add_line (contours [i], contours [n], dxfattribs = {'layer': 'MyLines'}) # add a LINE entity
File "C:\Users\MyPc\AppData\Local\Programs\Python\Python38\lib\site-packages\ezdxf\graphicsfactory.py", line 121, in add_line
dxfattribs["start"] = Vec3(start)
File "src\ezdxf\acc\vector.pyx", line 417, in ezdxf.acc.vector.Vec3.__cinit__
TypeError: invalid argument count
设置
>>> import cv2
... import numpy as np
... frame = cv2.imread("cyan quick_3_MAD.png")
>>> canny = cv2.Canny(frame, 255, 0)
>>> contours, hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
>>> contours_draw = cv2.drawContours(frame, contours, -1, (0, 255, 0), 1)
>>> cv2.imwrite("out.png", contours_draw)
输出:
什么是 np.squeeze
?
对于这个例子,等高线看起来像这样:
>>> print(str(contours)[:400])
[array([[[629, 568]],
[[629, 569]],
[[629, 570]],
...
>>> len(contours)
188
>>> contours[0].shape
(59, 1, 2)
使用np.squeeze
后,删除了不必要的1尺寸轴。
squeezed = [np.squeeze(cnt, axis=1) for cnt in contours]
>>> len(squeezed)
188
>>> squeezed[0].shape
(59, 2)
引用文档np.squeeze
numpy.squeeze(a, axis=None)
Remove axes of length one from a.
关键部分
您使用了ctr = contours[1]
,这意味着您仅在多个轮廓中绘制列表中的第一个轮廓。
相反,您需要遍历轮廓并绘制它具有的每个轮廓。
>>> import ezdxf
... dwg = ezdxf.new("R2010")
... msp = dwg.modelspace()
... dwg.layers.new(name="greeny green lines", dxfattribs={"color": 3})
>>> for ctr in squeezed:
... for n in range(len(ctr)):
... if n >= len(ctr) - 1:
... n = 0
... try:
... msp.add_line(ctr[n], ctr[n + 1], dxfattribs={"layer": "greeny green lines", "lineweight": 20})
... except IndexError:
... pass
>>> dwg.saveas("output.dxf")
输出:
更新
要翻转图像,我们只需反转 y 值即可。
由于 squeezed
是包含计数的 np 数组列表,我们可以简单地将向量 [1, -1]
乘以它以翻转 y 轴上的值。
>>> inverted_squeezed = [arr * [1, -1] for arr in squeezed]
>>> for ctr in inverted_squeezed:
... for n in range(len(ctr)):
... if n >= len(ctr) - 1:
... n = 0
... try:
... msp.add_line(ctr[n], ctr[n + 1], dxfattribs={"layer": "greeny green lines", "lineweight": 20})
... except IndexError:
... pass
>>> dwg.saveas("output.dxf")