资讯详情

资讯详情

国产CAD图纸AI识图实战:从DXF解析到图标符号智能识别

1. 国产CAD的AI识图需求到底从哪来1.1 一个真实场景为什么“识别图标与图元”成了刚需我在制造业信息化这行干了十来年最近两年被问得最多的问题从“怎么把DWG转成PDF”变成了“怎么让机器看懂图纸里的东西”。这个转变背后是国产化替代的大背景——大量企业把设计工具从国外CAD切换到中望、浩辰、CAXA这些国产平台之后发现一个很尴尬的事图纸能打开、能画但以前积累的自动化脚本、二次开发插件、甚至一些基于对象模型的批量处理流程全都得重写。重写的核心难点在哪就在“识别”两个字上。国外CAD有一套成熟的DXF组码体系和ActiveX自动化接口你写个脚本遍历模型空间拿到每个实体的类型、图层、颜色、句柄这是基本操作。但国产CAD的底层数据组织方式不完全一样有些平台对自定义图元、代理对象的支持策略不同导致你直接照搬老代码经常拿到空值或者类型错乱。更麻烦的是图标识别。这里说的“图标”不是指软件界面上的按钮图标而是图纸里那些用块参照、属性块、甚至多条线段拼出来的“符号化表达”——比如电气图里的断路器符号、暖通图里的风阀符号、机械图里的粗糙度标注。这些符号在图纸里没有统一的语义标签人眼一看就懂机器却只能看到一堆线和圆。国产化迁移过程中如果不能让AI把这些符号自动认出来那所谓的“智能审图”“自动算量”“批量改图”全是空中楼阁。所以这个项目的核心目标很明确在国产CAD环境下构建一套能自动识别常见图标符号和基础图元直线、圆弧、多段线、文字、标注的AI能力并且这套能力要能落地到实际的设计、审查、归档流程里。适合谁看CAD二次开发工程师、制造业IT负责人、设计院数字化专员以及任何正在做国产化迁移、被图纸数据清洗折磨过的同行。1.2 国产CAD平台的数据特点与识别难点先泼一盆冷水国产CAD不是简单换个壳它的内核在几何引擎、数据存储、扩展接口上都有自己的设计。我实测过几个主流平台发现几个共性问题。第一块参照的嵌套深度和属性提取方式差异大。国外CAD里用BlockReference拿属性一行代码的事。国产平台有的把属性存在扩展数据里有的用自定义字典你得先搞清楚它的对象模型文档。更坑的是有些平台对匿名块比如标注箭头、填充图案生成的临时块的处理策略不同你遍历的时候会混进来大量无意义的块需要先做过滤。第二图元坐标系的转换逻辑不统一。图纸空间和模型空间的变换矩阵不同平台实现有细微差别。我遇到过在A平台算出来正确的包围盒到B平台就偏了半个图框。后来发现是UCS用户坐标系的处理方式不同有的平台默认把UCS矩阵乘进去了有的没有。这个坑不踩一次根本想不到。第三文字识别是老大难。国产CAD对SHX字体的支持各有千秋有些平台把文字转成曲线后你就拿不到原始字符串了。而图标识别里文字往往是关键上下文——比如一个符号旁边写着“DN100”那它大概率是管道附件。所以AI识别不能只做图形匹配必须图文联合分析。基于这些特点我的整体思路是不依赖单一平台的私有接口而是走“导出中间格式AI推理结果回写”的路线。中间格式优先选DXF因为它是事实上的交换标准国产CAD基本都支持导出。AI推理部分用Python生态模型选轻量级的保证在普通办公机上也能跑。结果回写则通过各平台提供的脚本接口或者直接操作DXF实现。2. 核心思路拆解为什么这么设计2.1 整体架构从“硬编码规则”转向“规则学习”混合模式早些年做图元识别大家习惯写规则圆就是圆直线就是直线块参照就查块名。这套方法在标准化程度高的图纸里能跑但一到实际项目就崩。为什么因为设计院出图风格千差万别同一个风阀符号张三画成矩形加斜线李四画成两个三角形对接王五直接用了自定义实体。你规则写到死也覆盖不全。所以这次我采用混合模式基础几何图元用规则引擎快速过滤复杂图标符号用AI模型做分类和检测。规则引擎负责把图纸“切碎”成候选区域比如通过连通域分析把相邻的线段、圆弧聚成一个簇然后把这个簇的几何特征包围盒长宽比、线段数量、圆弧数量、闭合性喂给一个轻量级分类器。分类器输出这个簇属于哪类符号的概率。为什么不用端到端的深度学习检测模型比如YOLO那种。原因很现实标注数据太少。你不可能让设计院给你标几万张图纸。而且CAD图纸是矢量数据直接转成像素图会丢失精度放大缩小后线宽变化会影响检测。所以我的策略是在矢量层面做特征工程用传统机器学习随机森林、SVM做分类这样只需要几百个标注样本就能达到可用精度而且推理速度极快一张A1图纸几秒钟跑完。2.2 为什么选择FastOCR做文字辅助热词里提到了FastOCR智能表格识别我一开始没太在意后来发现它在图纸文字提取上意外地好用。国产CAD导出的PDF或者打印成图片后图纸里的文字往往和图形混在一起传统OCR容易把尺寸标注的数字和符号混淆。FastOCR的表格识别能力在这里派上了用场——它能把图纸里的标题栏、明细表、材料表结构化提取出来这些结构化文字信息反过来可以辅助图标识别。举个例子明细表里写着“截止阀 J41H-16C DN50”而图纸某个区域检测到一个阀门符号两者通过位置关系明细表引线指向关联起来就能确认这个符号是截止阀而不是其他阀类。这种图文互证的思路比单纯看图准确率高出一大截。2.3 局部聚焦算法在密集图纸里的应用热词里还有个“局部聚焦算法辅助标记的高分遥感影像农田地块智能识别”虽然领域不同但思路可以借鉴。CAD图纸里图元分布极不均匀有的区域密密麻麻全是线有的区域大片空白。如果对整张图统一处理密集区域容易漏检空白区域浪费算力。我借鉴了局部聚焦的思路先用一个低分辨率的网格把图纸划分成若干区块计算每个区块的图元密度。密度高的区块提高采样精度用更细的网格再切分密度低的区块直接跳过或者粗粒度处理。这样整体推理时间能压缩40%以上而且密集区域的识别率明显提升。3. 核心细节解析与实操要点3.1 图元提取从DXF里拿到干净的数据第一步是把国产CAD图纸导出成DXF。这里有个细节不同平台导出的DXF版本不一样有的默认R12有的默认2018。R12格式简单但丢失很多信息比如多段线的凸度、样条曲线2018格式全但解析复杂。我的建议是统一导出为AC10152000版兼容性和信息完整度平衡得最好。拿到DXF后用Python的ezdxf库解析。这个库成熟稳定文档齐全。核心代码逻辑如下import ezdxf doc ezdxf.readfile(drawing.dxf) msp doc.modelspace() entities [] for e in msp: entity_type e.dxftype() if entity_type in [LINE, ARC, CIRCLE, LWPOLYLINE, TEXT, MTEXT, INSERT]: entities.append({ type: entity_type, layer: e.dxf.layer, handle: e.dxf.handle, geometry: extract_geometry(e) })extract_geometry函数需要根据实体类型分别处理。直线拿起点终点圆弧拿圆心半径起止角多段线拿顶点列表和凸度文字拿插入点和内容块参照拿插入点和旋转缩放。注意国产CAD导出的DXF里块参照的INSERT实体可能包含多个属性ATTRIB这些属性在ezdxf里需要通过e.attribs访问而不是直接读e.dxf。我一开始漏了这一步导致属性块的信息全丢了。3.2 连通域聚类把散落的图元拼成符号拿到图元列表后下一步是把属于同一个符号的图元聚在一起。比如一个阀门符号可能由两条短线、一个圆、一条中线组成它们在空间上相邻但DXF里是四个独立实体。聚类算法我用的是基于距离阈值的层次聚类。具体做法计算每两个图元之间的最小距离如果小于阈值比如图纸单位下的2mm就认为它们属于同一簇。阈值怎么定我的经验是取图纸典型线宽的3到5倍。太大会把相邻的不同符号合并太小会把一个符号拆散。from scipy.cluster.hierarchy import linkage, fcluster import numpy as np # 计算距离矩阵 dist_matrix compute_pairwise_distances(entities) Z linkage(dist_matrix, methodsingle) clusters fcluster(Z, tthreshold, criteriondistance)这里有个坑singlelinkage容易产生链式效应把一串本不相干的图元连成一个大簇。我后来改用completelinkage虽然计算慢一点但簇的边界更清晰。实测下来对于典型机械图纸complete的准确率比single高15%左右。3.3 特征工程让分类器看懂几何形状每个簇提取出来后需要转成特征向量。我设计了以下几类特征统计特征图元总数、各类型图元数量线、弧、圆、多段线、图层分布熵。几何特征包围盒的宽高比、面积、周长、凸包面积比、最小外接矩形旋转角。拓扑特征端点连接数、闭合环数量、悬挂边数量。文字特征簇内文字内容、文字高度、文字与图形的相对位置。这些特征加起来大概30维对于随机森林来说足够了。特征计算里最耗时的是凸包和最小外接矩形我用shapely库实现速度可以接受。实操心得图层信息非常重要。很多设计院有固定的图层规范比如“阀门”图层、“设备”图层。如果簇内图元集中在某个图层那分类置信度直接拉满。我通常把图层名称做one-hot编码作为强特征输入。3.4 模型训练小样本下的调参经验标注数据我攒了大概500个符号样本覆盖阀门、法兰、弯头、三通、仪表、电气元件等常见类别。训练集和验证集按8:2划分。模型选随机森林因为它在小样本下表现稳定而且特征重要性可解释。from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score clf RandomForestClassifier( n_estimators200, max_depth12, min_samples_leaf3, class_weightbalanced, random_state42 ) scores cross_val_score(clf, X, y, cv5) print(f交叉验证准确率: {scores.mean():.3f})调参过程中发现几个关键点max_depth超过15就过拟合验证集准确率反而下降min_samples_leaf设为3比默认的1更稳因为符号样本里有些噪声点class_weightbalanced必须开否则样本多的类别会压制样本少的类别。最终模型在验证集上的准确率是87.3%召回率84.1%。对于辅助人工审图来说这个指标够用了——它能把可疑区域标出来让人去确认而不是完全替代人。4. 实操过程与核心环节实现4.1 环境搭建与依赖安装整个流程跑在Python 3.9以上核心依赖如下pip install ezdxf1.0.3 pip install shapely2.0.1 pip install scikit-learn1.3.0 pip install numpy1.24.3 pip install scipy1.11.1 pip install opencv-python4.8.0.74 pip install fastocr0.2.1fastocr这个包安装时注意它依赖的底层OCR引擎需要单独下载模型文件大概200MB。第一次运行会自动下载如果网络环境不好可以手动放到缓存目录。注意国产CAD导出的DXF里有些自定义实体比如中望的ZWM实体ezdxf不认识会报错。解决办法是在导出时选择“标准DXF”而不是“原生格式”或者在解析时用try-except跳过未知实体。4.2 完整识别流程的代码实现我把整个流程封装成一个类核心方法recognize接收DXF路径返回识别结果列表。class CADSymbolRecognizer: def __init__(self, model_path): self.clf joblib.load(model_path) self.threshold 2.0 # 聚类距离阈值单位mm def recognize(self, dxf_path): doc ezdxf.readfile(dxf_path) msp doc.modelspace() # 1. 提取图元 entities self._extract_entities(msp) # 2. 连通域聚类 clusters self._cluster_entities(entities) # 3. 特征提取 features [self._extract_features(c) for c in clusters] # 4. 分类预测 X np.array(features) probs self.clf.predict_proba(X) labels self.clf.predict(X) # 5. 组装结果 results [] for cluster, label, prob in zip(clusters, labels, probs): results.append({ bbox: cluster[bbox], label: label, confidence: max(prob), entities: cluster[entities] }) return results_extract_entities里有个细节对于INSERT实体我不仅提取插入点还会递归展开它的块定义把块内的图元也提取出来。这样做的原因是有些符号是用块做的但块内图元才是真正的几何信息。递归深度限制为3层防止循环引用。_cluster_entities里距离计算用shapely的distance方法比手写欧氏距离快很多。对于多段线先转成LineString再算距离。4.3 文字辅助识别的集成FastOCR的集成相对独立因为它处理的是图像而不是矢量。流程是先把DXF用国产CAD的打印功能输出成高分辨率PNG建议600dpi然后跑FastOCR提取文字和表格。from fastocr import FastOCR ocr FastOCR() result ocr.recognize(drawing.png, tableTrue) text_blocks result[text_blocks] tables result[tables]拿到文字块后需要和矢量图元做空间关联。我的做法是对于每个识别出的符号簇查找距离它最近且距离小于5mm的文字块把文字内容作为附加特征。如果文字里包含“DN”“PN”“Φ”等关键词直接提升对应类别的置信度。实操心得FastOCR对旋转文字的处理一般如果图纸里有大量竖排文字建议先做图像旋转校正。我用OpenCV的minAreaRect检测文字方向然后旋转到水平再送OCR准确率能提升20%以上。4.4 结果回写与可视化识别结果最终要回到国产CAD里让设计师能看到。两种方式一是生成一个带标记的DXF用不同颜色高亮识别出的符号二是通过国产CAD的脚本接口直接在当前图纸上画标记。我选第一种因为通用性强。用ezdxf新建一个图层“AI_RECOGNITION”把每个识别结果的包围盒画成矩形旁边标注类别和置信度。def write_results(dxf_path, results, output_path): doc ezdxf.readfile(dxf_path) msp doc.modelspace() doc.layers.add(AI_RECOGNITION, color1) # 红色 for r in results: bbox r[bbox] msp.add_lwpolyline( [(bbox[0], bbox[1]), (bbox[2], bbox[1]), (bbox[2], bbox[3]), (bbox[0], bbox[3])], closeTrue, dxfattribs{layer: AI_RECOGNITION} ) msp.add_text( f{r[label]} {r[confidence]:.2f}, dxfattribs{layer: AI_RECOGNITION, height: 2.5} ).set_placement((bbox[0], bbox[3] 1)) doc.saveas(output_path)这样设计师打开输出文件一眼就能看到AI认出了什么、在哪里、有多确信。对于置信度低于0.6的结果我建议用黄色标记提示需要人工复核。5. 常见问题与排查技巧实录5.1 识别率突然下降怎么查这是最常被问到的问题。昨天跑得好好的今天换了一张图纸识别率从85%掉到40%。排查思路按以下顺序来第一步检查DXF导出设置。不同图纸可能来自不同设计院导出设置不一样。重点看三个参数是否包含块定义、是否展开属性、是否使用真实线宽。我遇到过一张图导出时勾了“仅导出可见图层”结果大量符号在冻结图层里根本没导出来。第二步检查单位。国产CAD图纸的单位有毫米、厘米、英寸、无单位。如果聚类阈值是按毫米设的2.0但图纸单位是英寸那阈值实际只有0.08mm所有图元都聚不到一起。解决办法是读DXF的$INSUNITS变量自动换算阈值。第三步检查图层命名。有些图纸的图层名是乱码或者纯数字导致one-hot编码失效。这时候需要降级处理忽略图层特征只用几何特征。第四步检查文字干扰。如果图纸里文字特别多FastOCR可能把图形误认成文字或者把文字块错误关联到符号上。这时候需要调整文字关联的距离阈值或者暂时关闭文字辅助。5.2 常见问题速查表问题现象可能原因排查方法解决方案识别结果为空DXF导出时未包含模型空间实体用文本编辑器打开DXF搜索ENTITIES段重新导出勾选“包含模型空间”符号被拆成多个簇聚类阈值太小打印图元间距离分布直方图增大阈值到线宽的5倍不同符号被合并聚类阈值太大或链式效应检查簇内图元数量超过20个需警惕改用complete linkage减小阈值文字识别乱码SHX字体不支持或OCR模型缺失查看FastOCR日志安装对应语言模型或转成TrueType字体再导出推理速度极慢图元数量超过10万统计图元总数启用局部聚焦跳过空白区域置信度普遍偏低模型训练样本与当前图纸风格差异大对比训练集和当前图纸的图层分布补充标注样本重新训练5.3 几个只有踩过才知道的坑坑一国产CAD的块参照有“多重引用”问题。热词里提到了“cad多重引用插入解除工具”我一开始没理解什么意思后来遇到了一个块被多次插入但每次插入的缩放比例不同有的甚至是负缩放镜像。ezdxf解析时负缩放的块内图元坐标需要做镜像变换否则位置全错。解决办法是读INSERT的xscale和yscale如果为负对块内图元做相应变换。坑二样条曲线和多段线的凸度。国产CAD里多段线的圆弧段用凸度bulge表示凸度值等于圆弧圆心角四分之一的正切。ezdxf的LWPOLYLINE实体有bulge属性但如果你直接拿顶点坐标当直线处理圆弧就变成了弦符号形状完全变了。必须根据凸度重建圆弧。坑三标注的关联性。尺寸标注在DXF里是DIMENSION实体它关联到被标注的图元。如果你只提取DIMENSION本身拿不到它标注的是哪条线。需要读它的defpoint和defpoint2等属性反查关联图元。这个在识别“带尺寸的符号”时特别重要。坑四颜色和线型的语义。有些设计院用颜色区分专业比如红色是电气、蓝色是给排水。识别时如果把颜色作为特征能大幅提升准确率。但国产CAD的颜色索引和国外不完全一样需要做映射表。6. 后续扩展与个人体会这套方案目前跑在几个实际项目里最典型的是一家做环保设备的设计院他们有大量工艺流程图需要从旧平台迁移。以前人工整理一张图要半天现在AI预识别加人工复核压缩到20分钟。当然AI不是万能的它更像一个“超级过滤器”把明显的东西标出来让人专注于疑难杂症。后续我打算往两个方向扩展。一是引入主动学习让设计师在复核时顺手修正AI的错误这些修正结果自动回流到训练集模型每周更新一次。二是支持更多国产CAD平台的原生接口现在走DXF中转虽然通用但毕竟多了一步导出如果直接对接各平台的API实时性会更好。最后分享一个小技巧如果你也在做类似的事建议先从单一符号类型开始比如只识别阀门把准确率做到95%以上再逐步扩展。一上来就搞全类别标注数据不够调参调到怀疑人生。我当初就是贪多结果返工了两次。另外图纸的图层规范比什么都重要如果你们院里的图层是乱的先花时间整理图层这比优化模型见效快得多。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →