首页 / 资讯中心 / 文章详情

基于YOLOv10的字母数字识别检测系统:从数据标注到UI部署全流程

基于YOLOv10的字母数字识别检测系统:从数据标注到UI部署全流程 ★ FEATURED ARTICLE
这套基于YOLOv10的字母数字识别检测系统是我最近完整走通的一个项目。它做的事很直接用YOLOv10深度学习模型在图像里框出每一个字母和数字并给出对应的类别标签再配一个Python写的UI界面把整个流程串起来既能传图识别也能打开摄像头做实时检测。项目交付物里包含训练好的模型权重、自定义标注的YOLO数据集、完整的Python工程代码拿到手基本改改路径就能跑起来。这类需求在工业现场、物流分拣、设备巡检里非常常见。比如机柜上的资产编号、包装箱上的批次号、实验器皿的标签都需要从图片里准确读出字母和数字。以前大家习惯直接上OCR但实际做下来你会发现普通OCR在这种场景下往往水土不服字符排列不整齐、背景复杂、字体多样、光照变化大识别率很难保证。用目标检测的思路去做反而更稳因为YOLO本质上是在“定位分类”它不要求文字水平排列也不依赖字符切割对角度、遮挡、光照变化的鲁棒性好很多。这篇文章就把这个项目的完整实操过程拆开讲从数据集怎么做、为什么选YOLOv10、训练参数怎么调到UI界面如何串联整个识别流程。适合正在做字符识别、工业视觉检测或者刚接触YOLO想找个完整项目练手的朋友参考。1. 字母数字识别这事到底是在解决什么问题1.1 先搞清楚这明明是“检测”而不是“识别”拿到这个项目我第一个想提醒的就是概念问题。标题里写的是“字母数字识别检测”实际上YOLO模型做的是目标检测也就是把每个字符当作一个独立目标输出它的边界框位置和类别。比如图片里有一串“A1B2C3”模型会输出6个框分别对应A、1、B、2、C、3这6个字符。这和传统OCR的流程有本质区别。OCR是先做文字行检测再做字符切割最后逐个分类识别这个pipeline对整齐排版的印刷体很有效但对自然场景下的字符就很吃力。YOLOv10走的是“一锅端”路线每个字符都当作目标来检测不需要先找文字行也不用切割。这个区别对工程落地的意义很大。像工业场景里字符可能印在曲面、圆柱表面甚至是有褶皱的包装袋上文字方向不固定OCR很难处理。但用YOLO做检测只要样本足够模型就能学出“字符长什么样”在哪个位置出现方向是什么都能框出来。真正做到了“所见即所得”。1.2 分类有多少种36类的边界情况字母数字识别的类别定义一般是0到9十个数字加上A到Z二十六个大写字母总共36类。看起来不多但里面有几个经典的坑。最典型的是相似字符混淆。O和0、I和1、Z和2、S和5这四组是重灾区。尤其是O和0字体稍微特殊一点人都容易看走眼模型更是经常翻车。我在标注数据的时候专门把这些容易混淆的字符单独拉出来做了统计确保它们在整个数据集里数量均衡不能偏科。还有一类是长尾问题。如果样本里某些字母出现得特别少比如Q、Z、X这种在工业编号里不常出现的字母模型就很容易漏检。解决办法是合成数据时主动提高这些稀有字符的采样概率或者做类别加权。这个我在后面数据章节会具体说。1.3 典型应用场景有哪些这类系统的应用面其实很宽我自己接触到和帮朋友调试过的就不下五种。工业产线字符追溯产品外壳上喷印的序列号、批号用于质量追溯和防伪验证。电力设备巡检电表箱、配电柜上的设备编号识读巡检机器人拍照后自动归档。仓储物流快递面单、周转箱上的标签信息读取辅助自动化分拣。实验室管理试管、培养皿上的标签识别避免人工抄录错误。车牌与集装箱号虽然车牌有专用算法但集装箱号、车架号这种长串字母数字组合用这套思路一样能做。这些场景有一个共同点环境可控性差、拍摄角度不固定、字符排列不规整但企业对识别准确率的要求又都很苛刻。用YOLOv10做算是目前性价比很高的一种解法。2. 为什么选YOLOv10而不是YOLOv5/v8或者OCR2.1 YOLOv10在架构上做了什么改变我在选型的时候其实先在YOLOv5和YOLOv8之间犹豫了一阵后来出了YOLOv10才最终敲定。它有几个关键改进大家要明白这些改动意味着什么。第一个重点是去掉了NMS。传统的YOLO系列模型会预测一堆冗余框训练完需要靠非极大值抑制把重复的框合并掉。YOLOv10引入了双标签分配策略训练时用一对多分支提供监督推理时切换成一对一分支直接从模型输出的框中拿到唯一目标框不需要后处理NMS。这对工程来说是个加分项代码逻辑简化了推理延迟也降了。第二个是C2fU模块在C2f结构里融入了类似SE attention的机制用轻量的方式增强特征表达能力。在小目标检测上表现不错而字符恰好是小目标这一点很关键。第三个是PSA注意力模块用在模型更深层的特征提取上能够在全局范围内建模特征之间的关联。对字符检测来说这意味着模型能更好地利用上下文信息比如根据周边的字符特征来区分O和0。2.2 同尺寸模型参数对比我整理过一组YOLOv10不同规格模型的参数对比当时选型就靠这张表。模型尺寸参数量速度表现场景建议YOLOv10n约270万很快适合CPU或边缘设备实时性要求高、算力受限的场景YOLOv10s约720万快GPU实时无压力通用场景我的首选YOLOv10m约1560万中等精度优先、算力充裕的服务器环境YOLOv10l约1970万偏慢追求极致精度的离线识别字母数字字符比较小环境又复杂我最终用的是YOLOv10s精度和速度比较平衡。如果后续要部署到Jetson Nano这种小设备就换n版本重训一版数据不用动只是改一下配置。2.3 为什么不直接用OCR/文本识别方案这个项目刚启动时也有人建议直接用PaddleOCR之类现成的OCR库理由是什么都不用做装上就能用。但我测下来的结果不太理想。OCR方案在整行印刷体、字库统一、长句文本场景下表现确实强可它走的是“检测文本框 - 识别文本序列”的路子对单个字符的边界框定位能力天生偏弱。你要的是“图片里每个字母数字在哪、是什么”不一定是一段完整字符串。比如包装袋上的编号只有6到8个字符且字符之间可能比较散OCR检测模块会把整行文字当成一个目标框你想要单个字符框就无从谈起。另外自定义字体和特殊字符的情况下OCR需要对识别分支重新训练工程复杂度并不比YOLO方案低。综合算下来YOLOv10这套方案训练更直接、部署更轻、单字符框也更稳定。3. 数据集制作项目里最容易翻车的环节3.1 数据从哪来合成真实场景双轨制训练数据永远是这个项目的核心瓶颈模型能不能达到实用级别八成取决于数据。我一开始就两条腿走路。第一条腿是合成数据用代码在背景图上随机生成字母数字字符串加上字体变换、缩放、旋转、透视变形、噪声、模糊、亮度扰动。这里我踩过一个坑就是合成数据虽然量大管饱但背景和字体太“干净”模型在真实图片上会明显掉点。第二条腿是真实场景拍摄数据手机拍摄的标签、工厂流水线上的铭牌、包装箱喷码甚至从公开数据集里筛选符合需求的图片。这部分数据量不大但极其宝贵它决定了模型在真实环境下的泛化能力。我的经验配比是合成数据占七成真实数据占三成。每大类字体至少准备5种以上合成时随机选择。背景图也刻意选用不同材质金属、塑料、纸箱、木纹都包含让模型不要依靠“背景特征”去做检测而是真正关注字符纹理。3.2 标注规范单字符框才是核心决策数据集标注方式决定了模型学的是什么这个必须一开始就定清楚。我采用的是单字符级别标注也就是每个字母或数字单独一个框。拿“AB123”这串字符来说标成五个框类别分别是A、B、1、2、3。而不是把整串字符框成一个目标。很多初学者会纠结这一点总觉得按整串标注工作量小但这样模型学的是“字符序列”的整体特征后面碰到位置变化或者字符间距不同的样本几乎必然漏检误检。标注工具我用的是LabelImg界面简单快捷键熟练了效率还行。需要注意导出格式要和YOLO格式对齐也就是每个标注文件是一个txt每一行是类别ID 中心点x 中心点y 宽度 高度所有坐标都归一化到0到1之间。比如一张640x640的图片左上角有个字符框中心点在(160, 200)框宽80高80类别ID是0那这一行就是0 0.25 0.3125 0.125 0.125标注的时候坐标系别搞混YOLO是像素坐标归一化不是像COCO那样左上角宽高的形式。3.3 数据增强策略把小字符这个难点打透字符检测最大的痛点是“小”。一张640x640的图人眼看到的字符可能只有三四十个像素高。模型能不能抓住这些小目标的特征数据增强很关键。YOLOv10自带的数据增强管线里Mosaic和MixUp是默认开启的对提升小目标泛化能力很有帮助。四张图拼成一张相当于变相增加了小目标的数量。但Mosaic在字符检测里会带来一个问题字符之间可能互相覆盖造成标注框重叠和遮挡。我的做法是把mosaic的力度调低设置mosaic0.5只在一半的迭代里启用它。另外我额外加了几个针对字符场景的增强锐化与反锐化掩蔽模拟不同摄像头对焦状态。高斯噪声和椒盐噪声模拟低光照、高ISO的拍摄效果。随机局部模糊模拟运动模糊。随机色相偏移模拟不同材质对颜色的影响。这些增强不是越多越好关键是模拟你的实际部署环境。如果实际场景就是室内固定光源没必要把训练数据搞得像灾难现场否则模型在真实数据上反而会糊。3.4 data.yaml的配置细节训练前要准备好数据集配置文件这是YOLO系列的标配内容大概是这样# data.yaml path: D:/yolo_ocr/dataset train: images/train val: images/val nc: 36 names: 0: 0 1: 1 2: 2 # 一路到9 10: A 11: B # ... 35: Z这里有个细节值得提醒类别ID从0开始连续编号一旦确定就不要中途改动。我吃过亏一开始把A排在前面后面发现数字的标注量更大又调整了类别顺序结果之前的标注文件全部要重来。所以建议从一开始就按“数字0-9字母A-Z”的固定顺序排好。还有目录结构YOLO的train和val路径既可以写绝对路径也可以用相对路径写法。考虑到项目要交付给别人用路径写死容易出问题。建议用相对于data.yaml文件所在目录的方式这样别人把整个项目文件夹拷到任何机器都能直接跑。4. 模型训练与调参从环境到出模型的全过程4.1 环境准备与版本兼容训练环境我用的Python 3.10、PyTorch 2.x、CUDA 11.8的组合。官方代码库对Python版本有一个最低要求低于这个版本会有兼容问题但太新的Python版本有时又依赖不上torch所以建议用3.10到3.12之间的版本。创建虚拟环境是必须的不要直接在系统Python里装多个项目之间依赖包冲突会让人崩溃。conda create -n yolo10 python3.10 conda activate yolo10 pip install ultralyticsultralytics这个包本身就带训练、验证、导出、推理的全套功能对新手很友好。显卡驱动和CUDA版本对不上是新手最常见的翻车点。建议用nvidia-smi看支持的最高CUDA版本然后安装PyTorch官方对应版本的轮子。4.2 训练脚本怎么写的关键参数逐一说明训练命令看似简单参数调优的门道都在细节里。我贴一下我实际用的训练命令yolo train \ datadata.yaml \ modelyolov10s.yaml \ epochs200 \ batch16 \ imgsz640 \ device0 \ optimizerAdamW \ lr00.01 \ patience30 \ seed42这里几个参数我解释一下为什么这么定。imgsz640是考虑到部署设备的分辨率和字符尺寸的折中。如果字符特别小可以提高到1024但训练时间和显存占用会明显上涨。batch16要看显卡显存batch不是越大越好太大容易收敛不稳太小batchnorm统计量不准。epochs200不是一味追求多配合patience30做早停当验证集mAP连续30轮没有提升就自动停止节省时间。优化器和学习率这里想多说一句。YOLO家族传统上用SGD但我在字符检测这种小目标场景里实测AdamW收敛更快最终精度也略高。学习率lr00.01配合AdamW是合理的起步值如果loss出现剧烈震荡就降一个数量级到0.001。权重衰减参数weight_decay默认0.0005对普通场景够用。如果跑出来的模型在高分辨率测试图上过拟合严重可以适当增加到0.001。但这些基于我自己的数据集情况大家在自己数据上调参一定要记录每个组合的实验结果别凭感觉乱调。4.3 训练过程的观察指标训练开始后别光盯着控制台发呆有几个指标要关注。终端里会输出训练loss和验证loss还有mAP50、mAP50-95这些指标。mAP50IoU阈值0.5下的平均精度通俗说就是框大概框对就算对这个指标高说明“能不能检测到目标”的基础能力好。mAP50-95IoU阈值从0.5到0.95取平均这个指标高说明“框得准不准”更严格。precision和recall字符检测场景我更关注recall。漏检一个字符意味着整个序列号读错比误检一个背景区域严重得多。训练结束后的验证也很有讲究。我建议在val模式里单独跑一遍看每一类的AP值。尤其观察O和0、I和1这两组的AP差距。如果0的AP是0.95O的AP只有0.82说明模型对O的数据不够或特征没有学好要回去补O的样本。4.4 模型导出与验证训练完事的best.pt不能拿起来就用先做一轮推理自检挑十张训练时没见过的真实图片看框的准不准、类别对不对。然后才导出成需要的部署格式。yolo export modelbest.pt formatonnx导出ONNX是标准操作后续无论是用ONNX Runtime跑CPU还是转成NCNN/TensorRT跑嵌入式平台都比较方便。YOLOv10在导出时有一个要注意的地方因为它本身去掉了NMS导出的ONNX输出是一个大的预测张量需要自己在代码里解析。如果后续接的是OpenCV的DNN模块要适配一下输出层的reshape逻辑。5. 核心代码解读从加载模型到输出字符串5.1 推理流程的骨架整套系统最核心的推理逻辑其实就几件事读图、预处理、模型推理、解析输出、可视化。我用ultralytics的API演示的话代码可以很简洁from ultralytics import YOLO # 加载训练好的模型 model YOLO(runs/detect/train/weights/best.pt) # 推理单张图片 results model(test_img.jpg) # 拿到检测结果 boxes results[0].boxes.xyxy.cpu().numpy() # 框坐标 cls results[0].boxes.cls.cpu().numpy().astype(int) # 类别ID conf results[0].boxes.conf.cpu().numpy() # 置信度这里results[0].boxes就是检测到的所有目标。需要提一下YOLOv10的boxes返回的框坐标是原始图像分辨率下的像素坐标不是归一化的做可视化直接画就行。5.2 从无序框到有序字符串一个常被忽视的步骤这是项目里最“实现级”的坑模型输出了一堆框但你最终要的是一串顺序正确的字符串比如“A1B2C3”而不是随机排列的框集合。我在代码里实现了这样一个排序函数先对检测到的所有框按中心点y坐标做一次粗略排序分成“行”同一行内再按x坐标排序。原因是工业场景下字符序列不总是水平排列的可能有一点倾斜。如果只是简单按x排序倾斜角度较大的序列会被打乱。import numpy as np def sort_boxes_by_reading_order(boxes, cls_ids): 按阅读顺序对检测框排序先分行再从左到右 if len(boxes) 0: return [] # 取每个框的中心点 cx (boxes[:, 0] boxes[:, 2]) / 2 cy (boxes[:, 1] boxes[:, 3]) / 2 # 按y坐标从高到低排把每一行分开 idx np.argsort(cy) rows [] current_row [idx[0]] for i in idx[1:]: if abs(cy[i] - cy[current_row[-1]]) 10: current_row.append(i) else: rows.append(current_row) current_row [i] rows.append(current_row) # 每一行内按x坐标从左到右排 sorted_indices [] for row in rows: row_sorted sorted(row, keylambda i: cx[i]) sorted_indices.extend(row_sorted) # 生成最终字符串 id_to_char {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: A, 11: B, 12: C, 13: D, 14: E, 15: F, 16: G, 17: H, 18: I, 19: J, 20: K, 21: L, 22: M, 23: N, 24: O, 25: P, 26: Q, 27: R, 28: S, 29: T, 30: U, 31: V, 32: W, 33: X, 34: Y, 35: Z} result [id_to_char[cls_ids[i]] for i in sorted_indices] return .join(result)行分组的阈值10像素是我根据实际图像尺度调出来的如果你的图像分辨率不同需要改成相对值比如字符高度的1/3左右这样泛化能力更强。这段代码虽然不复杂但直接决定了识别结果的正确性值得用心磨。5.3 置信度过滤与疑难字符策略置信度阈值设置的逻辑和常规检测任务不太一样。对于字母数字识别一般要求宁可漏检也不误检的场景会把conf_thres调高到0.5甚至0.6。比如产线上的字符一旦识别错会导致追溯系统把A读成4产生错乱危害比读不出来更大。而有些场景是宁可误检也不漏检比如执法取证要保证每个字符都尽可能被框出来哪怕框错几个背景事后人工复核反而更好。我UI界面里把置信度滑块做成可调的下界0.1上界0.9默认0.25就是让使用方根据现场情况灵活调整。还有一个细节混淆字符的二次校验。我在系统里加了这样一个策略——当模型输出的字符是O、0、I、1、Z、2这六个高危字符时如果置信度低于阈值但差距不大就额外用一个小分类器或者模板匹配做二次确认。这个小功能在实测中把混淆字符的误识率降了不少。6. UI界面开发把模型包装成能用起来的工具6.1 技术选型为什么要用PySide6UI界面实现我用的PySide6也就是Qt for Python的当前版本。选择它有几个原因一是Qt的布局系统成熟做图像显示、参数调整、日志展示这种工具型界面比Gradio这种纯Web方案更接近本地原生应用的体验。二是PySide6的官方许可对开源和个人使用友好不用担心商业授权问题。三是和OpenCV、Pillow的配合顺畅图像数据可以直接转成QImage显示不需要中间转换格式。如果你从来没写过PySide6也不用担心这个界面本身逻辑不复杂核心就是文件选择、按钮、标签控件再加上一个多线程处理。6.2 界面布局设计和核心功能UI我分了三个区域左侧是图片显示区右侧是检测结果区和参数设置区底部是日志输出区。具体控件如下图片显示控件左边一个大的QLabel用来显示原始图检测后的标注图也画在这个区域。检测模式切换单张图片识别、文件夹批量识别、摄像头实时检测三个Tab。参数设置置信度滑块、IoU滑块还有字体大小选择。结果展示一个表格控件每一行列出序号、检测到的字符、置信度、位置坐标。日志输出一个文本框记录模型加载时间、每张图的处理耗时方便排查问题。实际操作体验上图片加载和推理不能卡住主线程否则界面会假死。Qt的解决方案是用QThread把耗时任务丢到子线程主线程只负责刷新界面。class InferenceThread(QThread): result_ready Signal(object) def __init__(self, model_path, image_path): super().__init__() self.model_path model_path self.image_path image_path self.model None def run(self): # 在子线程里加载模型和推理 if self.model is None: from ultralytics import YOLO self.model YOLO(self.model_path) results self.model(self.image_path) self.result_ready.emit(results)算力不够的机器上模型加载可能要好几秒如果放在主线程用户体验会很差。另外摄像头实时检测场景子线程里必须做帧缓存用最新的帧去推理不要阻塞摄像头采集。6.3 摄像头实时检测的实现细节实时检测比单图检测多一个环节视频流的获取和显示。我是用OpenCV的VideoCapture读摄像头帧每帧缩放到合适尺寸后喂给模型推理完后画框再显示。帧率控制在10到15帧就够用不要追求太高因为YOLO推理本身就占用较多计算资源摄像头采集线程和推理线程如果抢CPU会导致界面卡顿。关键参数摄像头的分辨率设置成1280x720就够不需要太高分辨率越高推理越慢而且小字符在低分辨率下反而不容易漏检因为模型训练时就是在640分辨率下跑的输入太大会改变目标的相对尺寸分布。摄像头实时检测时人眼对框的“稳定性”很敏感同一帧里的字符框如果前后帧抖动太厉害观感很差。我给检测框加了简单的平滑方法保留前一帧的框坐标和当前帧取加权平均。代码就三五行效果立竿见影。7. 常见问题与排查技巧实录7.1 训练阶段频繁踩坑的几个点显存不足报错怎么办这个最常见。减小batch到4或2图片尺寸从640降到512把AMP自动混合精度打开。还不行就检查是不是后台有别的程序占显存。用nvidia-smi看一下进程把占用的进程干掉。loss值巨大而且不下降先检查数据集的路径和标注文件对不对。一个典型的错误是数据路径写错导致训练集为空模型一直在验证集上评估loss当然不正常。打开训练日志看每轮的box_loss如果第一轮就异常大十有八九是标注坐标没归一化或者类别ID越界了。训练精度很高但测试时漏检严重这是过拟合了。合成数据太多、真实数据太少会这样。解决方法是加入更强的数据增强或者干脆增加真实场景数据量。我之前有一个阶段合成数据占九成训练集mAP95拿到真实测试图只有六成多补充了一百多张真实照片之后马上回到八成以上。7.2 推理阶段字符漏检与误检排查字符漏检在推理阶段很让人头大我这里整理了一个排查思路。先拿漏检的图去看模型输出的原始置信度分布。用上面提到的推理代码跑一遍把每个框的置信度打印出来。如果发现漏检的字符其实有对应的检测结果只是置信度低于阈值那说明模型本身学到了只是阈值设太高调低阈值即可。反过来如果完全没有对应的框那说明模型真的没检测到就得回训练阶段补数据了。误检背景区域也常遇到。我遇到最多的情况是模型把图形Logo当成字母尤其是一些圆形、环形Logo轮廓很像O。改进思路是收集这类误检图加到训练集里当负样本但YOLO数据集格式本身没有背景类需要在标注文件里把这些区域标成某个不存在的类别吗不对正确做法是导入图片时不标任何框模型会自动学习“这个区域没有目标”相当于隐式负样本。我在训练目录里放了一个专门的negatives文件夹里面就是这些容易引发误检的背景图片。7.3 部署到新机器时的环境迁移开发机器上跑得好好的换台机器就各种报错这是工程化交付最常见的问题。我的做法是冻结环境依赖生成requirements.txt并且锁定所有主要包的版本号。常见报错之一是CUDA版本和PyTorch不匹配装的时候先查显卡驱动支持的最高CUDA版本再配合PyTorch官网的安装矩阵来装。CPU机器上直接换成CPU版本的PyTorch推理速度会慢一些但功能完全正常Ultralytics会自动检测。7.4 实时检测速度优化的几个方向如果你追求更高的推理帧率有几个方向可以试。第一个是降低输入分辨率。从640降到416速度能提升将近一倍代价是mAP下降几个点。对字符检测来说字符本来就小降分辨率容易漏检我建议优先试试前两个方案。第二个是使用TensorRT加速在NVIDIA显卡上能把ONNX模型转成TensorRT引擎速度提升非常明显我实测在同等硬件上能快3到5倍。第三是把模型从s换成nYOLOv10n参数量只有s的一半多一点速度更快精度在充足数据下不会差太多。如果你部署的是CPU环境还可以试试把ONNX Runtime的线程数调大或者开启intra_op_num_threads参数。这个优化对CPU推理效果立竿见影。8. 实测效果与一些后续扩展最后聊一下这个系统实际跑出来的效果。我自己的测试集是大概600张真实环境图片和300张仿真图片的混合字符总数约13000个。用YOLOv10s模型在单张NVIDIA GPU上640分辨率下的平均推理时间约12毫秒整条流程包括画框和排序单张图约20毫秒。mAP50在0.96左右mAP50-95在0.82左右按完整字符串完全识别正确的比例来算测试集上有差不多93%的整串准确率。那些没完全识别对的串大部分问题出在遮挡严重的场景或者模糊到人眼都难分辨的图。混在这里面O和0、I和1这类相似字符的歧义占了一部分。上面提到的二次校验策略帮了不少但还没有彻底解决想完全消除歧义最终还得靠业务规则来兜底比如校验位验证。再分享一个小技巧是我调这个项目时悟到的训练数据里的标注框别贴着字符边缘卡太死。你标注的时候把四边多留出两三个像素模型判断框的位置就会更从容。我一开始追求“完美标注”框和字符严丝合缝结果验证集上框的位置偏差反而偏大。后来换成稍微宽松的标注mAP50-95直接涨了零点几。后续扩展方向其实很多。一个是加上播放视频文件的检测模式可以直接处理工厂监控录像。另一个是把识别结果通过串口或Socket发出去对接PLC或者上位机系统这样才算真正进了产线闭环。还有就是可以把UI界面打包成exe用PyInstaller拖进去就行但注意模型文件和代码路径要保持相对路径结构否则打包出来的程序换个目录就找不到模型了。这个项目的完整源码和数据集的制作方式都是可以复用的。核心步骤就那些采集数据、标注、训练、调参数、包界面、部署每一步做好字母数字识别这个需求其实没有想象中那么难。
阅读完成 · 觉得有帮助?
咨询建站