【问题标题】:The contour detected using opencv to dxf使用opencv到dxf检测到的轮廓
【发布时间】:2021-09-27 14:17:07
【问题描述】:

我使用 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文件中绘制的线不一样。另外,每次运行时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

【问题讨论】:

    标签: python-3.x opencv-contour ezdxf


    【解决方案1】:

    设置

    >>> 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)
    从 a 中删除长度为 1 的轴。


    关键部分

    您使用了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")
    

    【讨论】:

    • 哦,我完全了解 Squeeze。我不知道为什么使用ctr=contour[1],但是这里最大的问题。谢谢你,我学会了。感谢您的友好回答。
    • 旁注:try-except 块可防止在以某种方式存在的 0 大小数组上出现索引错误。
    • 非常感谢
    • 哦,stackoverflow 模组可能会删除评论,只是说谢谢!有空的时候看看stackoverflow的规则吧~
    • 对于使用opencv绘制的轮廓,dxf线在x轴上对称绘制。你碰巧知道如何补充这个吗?
    猜你喜欢
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 2016-03-27
    相关资源
    最近更新 更多