网站首页 > 技术文章 正文
00、背景
设计院提供2D的电气图,如何快速进行二次修改?
如果直接提供CAD矢量图,那就很方便。但设计院为了知识版权,一般只会提供pdf或图片文件。
那有没好的办法,进行一键转换为CAD图纸?
正好最近看OpenCV相关的书籍,有些思路。
01、实现原理
使用本文的代码会一键将 2D 图像转换为 DXF 文件。
主要利用了 OpenCV 进行图像处理并使用 Potrace 进行矢量化,简化了转换过程,使其成为 CAD 应用程序的理想选择,轻松高效地简化从图像到 DXF 的工作流程。
生成的 DXF 文件与各种 CAD 软件兼容,可以进一步编辑或查看。
重点步骤分解
- 输入:用户提供双电源接线图文件的路径。
- 图像处理:包括灰度转换、边缘检测和使用形态学操作进行细化。
- 矢量化:使用 Potrace 将处理后的 BMP 图像转换为 SVG。
- DXF 转换:将 SVG 路径转换为 DXF 格式。
- 输出:将最终的 DXF 文件保存为 final.dxf 。
02、执行效果
输入图片:test.jpg:
中间输出svg文件:
最终输出CAD图纸:final.dxf
运行前置条件
Python Libraries Python 库
- NumPy:与 OpenCV 结合使用进行数值运算。
- ezdxf:创建和操作 DXF 文件。
- svgpathtools:用于解析 SVG 文件。
- 子进程:用于运行外部命令,本文用到了 Potrace。下载地址:https://potrace.sourceforge.net/#downloading
安装所需的软件包
使用 pip 安装所需的软件包:
pip install opencv-python-headless
pip install numpy
pip install ezdxf
pip install svgpathtools
03、主要库和函数介绍
OpenCV (cv2)
用于图像处理任务的强大库。
- cv2.imread :从文件中读取图像。
- cv2.cvtColor :将图像转换为不同的颜色空间;这里用于灰度转换。
- cv2.Canny :执行边缘检测。
- cv2.GaussianBlur :减少图像中的噪点。
- cv2.threshold :对图像应用固定级别的阈值。
- cv2.erode 、 cv2.dilate :执行形态学操作。
Subprocess 子流程
用于在 Python 中运行外部命令。
- subprocess.run :执行 Potrace 命令以对图像进行矢量化。
ezdxf
用于创建和修改 DXF 绘图的 Python 包。
- ezdxf.new :初始化一个新的DXF文档。
- doc.modelspace() :访问图形实体的绘图空间。
svgpathtools
操作和分析 SVG 路径。
04、完整代码
代码简单,注释完整。
import cv2
import numpy as np
import os
import subprocess
import ezdxf
from svgpathtools import svg2paths
# 提示用户输入图像的路径
input_image_path = input("输入您要转换图片的文件路径: ")
# 检查提供的路径是否有效
if not os.path.exists(input_image_path):
print("指定的文件不存在。 请检查路径并重试。")
else:
# 读取图片
image = cv2.imread(input_image_path)
# 将图像转换为灰度
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用边缘检测
edges = cv2.Canny(gray_image, threshold1=50, threshold2=150)
# 应用高斯模糊来降噪
blurred = cv2.GaussianBlur(edges, (5, 5), 0)
# 对图像设置阈值以确保其是二进制的
_, binary_image = cv2.threshold(blurred, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 使用形态学运算来减少线条的粗细
eroded = cv2.erode(binary_image, np.ones((2,2), np.uint8), iterations=1)
dilated = cv2.dilate(eroded, np.ones((3,3), np.uint8), iterations=1)
# 通过用 .bmp 替换原始扩展名来构造输出文件名
output_bmp_path = os.path.splitext(input_image_path)[0] + '_refined_edges.bmp'
# 将精化边缘图像保存为 .bmp 文件
cv2.imwrite(output_bmp_path, dilated)
# 定义输出 SVG 的路径
output_svg_path = os.path.splitext(input_image_path)[0] + '_vectorized.svg'
# 运行 Potrace,将位图转换为 SVG
subprocess.run(['potrace', '-s', output_bmp_path, '-o', output_svg_path])
# 检查SVG是否创建成功
if os.path.exists(output_svg_path):
print(f"SVG 文件已成功创建于: {output_svg_path}")
# 将 SVG 转换为 DXF
paths, attributes = svg2paths(output_svg_path)
# 创建新的 DXF 文档
doc = ezdxf.new(dxfversion='R2010')
msp = doc.modelspace()
for path in paths:
for line in path:
start_point = (line.start.real, line.start.imag)
end_point = (line.end.real, line.end.imag)
msp.add_line(start_point, end_point)
# 保存文档
output_dxf_path = os.path.join(os.path.dirname(input_image_path),'final.dxf')
doc.saveas(output_dxf_path)
print(f"DXF 文件已成功创建于:{output_dxf_path}")
else:
print("SVG 文件创建失败。")
05、小结
- 以上代码适用于简单的 2D 图像。输入图像的质量会影响输出。
- 对于复杂或详细的图像,还需要在 CAD 程序中进行额外的手动编辑。
猜你喜欢
- 2024-09-11 给3D Slicer添加Python第三方插件库
- 2024-09-11 使用Python创建自己的Instagram滤镜
- 2024-09-11 薅羊毛我愿称Python为最强,Python 自动化带你轻松赚钱
- 2024-09-11 史上最全的OpenCV入门教程!这篇够你学习半个月了!万字长文入门
- 2024-09-11 使用python实现简易的人脸检测(python人脸检测106关键点)
- 2024-09-11 机器视觉技术(一)边缘提取(机器视觉边缘检测)
- 2024-09-11 Python-OpenCV 16. 图像特征检测与描述算法
- 2024-09-11 Flask—远程查看行空板USB摄像头视频
- 2024-09-11 OpenCV+Python识别车牌和字符分割的实现
- 2024-09-11 在Fedora中安装OpenCV-Python | 二
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)