基于Python与OpenCV的车牌识别系统:Unet+CNN源码拆解实战

发布时间:2026/10/12 17:23:22
基于Python与OpenCV的车牌识别系统:Unet+CNN源码拆解实战
简介这是一套基于Python与OpenCV的车牌识别系统毕业设计源码面向需要完成毕设、课程设计或进行图像识别实战的学生。系统涵盖车牌定位、字符分割与识别主要环节代码结构清晰简单部署即可运行适合新手参照学习。压缩包共15个文件以9个Python脚本为开发主体包含卷积神经网络与U-Net模型训练、核心识别算法及图形界面等模块2个h5文件为已训练好的模型权重可直接调用另有1个mp4演示视频和3个GIF动态图方便对照效果。整个压缩包仅26.7MB下载使用便捷。资源已有635人学习内容来自高分通过的毕设项目除完整源码外还配套演示素材可帮助读者快速理解从视频或图像输入到车牌识别的全过程并在此基础上进行改进或扩展。1. 基于 Python 与 OpenCV 的车牌识别系统这份源码为什么下载即可演示很多搜“Opencv的车牌识别系统源码”的人其实缺的不是算法思路而是一个能直接答辩演示的完整工程。这份基于 Python 与 OpenCV 的车牌识别系统源码包解压后最需要先记住一件事它把“车牌定位”和“字符识别”拆成了两个独立模型——Unet 负责从图片里把车牌区域抠出来CNN 负责把车牌上的汉字、字母、数字认出来GUI.py 和 vidGUI.py 则是两套图形界面分别承接单图识别和视频识别。包里已经放好了训练完成的 cnn.h5、unet.h5 两个权重文件外加 demo_car.mp4 演示视频和三个 GIF 验证动图。换句话说环境装好之后跑 vidGUI.py 就能看到完整识别效果不需要自己标车牌、不需要从头训练网络。这套东西适合毕业设计、课程设计、期末大作业尤其是导师要求“有界面、有模型文件、有演示视频”的验收场景正好三个条件全占。2. 先拆文件再跑链路Unet、CNN、GUI 各自管什么拿到压缩包别急着双击运行先把文件角色理清楚。这个项目最聪明的设计是训练链路和推理链路分开train.py、Unet.py、CNN.py 属于训练侧core.py、GUI.py、vidGUI.py 属于推理侧videospilt.py 和 imgtovid.py 是视频处理的辅助工具。搞清楚这条线后面改参数、排错才不会像没头苍蝇一样乱试。2.1 八个源代码文件每个文件在系统里扮演什么角色我把压缩包里的文件按职责列了一张表拿到手先对着表过一遍文件在系统中的角色所属链路core.py核心识别流程封装 Unet 分割和 CNN 识别被 GUI 调用推理Unet.pyUnet 网络结构定义用于车牌区域分割训练训练CNN.pyCNN 网络结构定义用于字符分类训练训练train.py训练入口脚本负责加载数据、跑 Unet 和 CNN 训练训练GUI.py / imgGUI.py图片识别图形界面选择图片后展示识别结果推理vidGUI.py视频识别图形界面读取视频逐帧识别推理videospilt.py把视频拆成帧序列图片便于单帧排查数据准备imgtovid.py把处理过的帧序列重新合成视频后期输出此外还有 cnn.h5、unet.h5 两个权重文件以及 demo_car.mp4 和三张 GIF。这里要特别说一句GUI.py 和 imgGUI.py 在不少毕设包里是两套入口一个面向单张图片一个可能是封装后的综合窗口具体以解压后的代码为准。判断方法很简单打开文件看顶部 import 了谁——如果引用了 core.py 里的函数那它走的就是推理链路如果引用了 Unet.py 或 CNN.py那它属于训练相关。看完这张表你会发现core.py 才是整个项目的枢纽。GUI 只是壳真正的车牌识别逻辑全部收在 core.py 里。所以我拿到包后的第一件事就是打开 core.py把识别流程从头到尾读一遍这比先跑 GUI 更重要。2.2 core.py 的处理链路从一帧图到一行车牌文本发生了什么core.py 的流程可以简化成下面这张调用链。注意这不是原文件逐行复制而是把核心逻辑抽出来重建的等价结构方便你看懂 Unet 和 CNN 是怎么衔接的# 简化重建的核心调用链路细节以包内 core.py 为准 def recognize_plate(img): # Unet 的输入要求BGR 转 RGB缩放到固定尺寸值域归一化到 0~1 x cv2.cvtColor(img, cv2.COLOR_BGR2RGB) x cv2.resize(x, (IMG_W, IMG_H)) / 255.0 # predict 需要四维张量 [batch, H, W, C]所以加一个 batch 维度 pred unet.predict(x[None, ...]) mask pred[0, ..., 0] # 取出单通道概率图 # 概率大于 0.5 的像素视为车牌区域得到二值 mask mask (mask 0.5).astype(uint8) # RETR_EXTERNAL 只取最外层轮廓避免车牌内部字符轮廓干扰 contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return # 车牌主体一般是面积最大的连通域按轮廓面积排序取最大 plate_contour max(contours, keycv2.contourArea) x, y, w, h cv2.boundingRect(plate_contour) # 从原图上裁剪车牌区域注意这里用的是原图坐标而不是缩放后坐标 plate_img img[y:y h, x:x w] # 字符切分后逐个交给 CNN 分类再把结果拼回字符串 chars split_chars(plate_img) text .join([cnn_predict(c) for c in chars]) return text这段代码里有两个参数最值得留意。第一个是mask 0.5这个阈值它决定“多大概率算车牌”。实际使用中如果车牌边缘被切掉把阈值降到 0.3 往往能找回一部分区域代价是背景噪声也会进来我一般先按 0.5 跑看裁剪结果再做微调。第二个是max(contours, keycv2.contourArea)这个写法取的是面积最大轮廓假设场景里只有一块车牌如果 demo 视频里出现多块车牌或者车牌旁边有大块反光这里就要改成按位置过滤比如只取画面中下部、宽高比接近 3:1 的轮廓。为什么不用传统方法做定位而是绕一圈用 Unet我也试过用 HSV 颜色空间筛蓝色、黄色车牌效果在固定场景下其实不错但一旦出现阴天、路灯、车辆反光颜色范围就崩。Unet 学的是车牌区域的纹理和结构特征泛化能力比手工调颜色阈值稳得多。这也是这个毕设能拿高分的原因之一——它把深度学习和传统视觉方法做了清晰对比。2.3 最短启动路径跑通 vidGUI.py 看到识别效果文件职责搞清楚之后最短启动路径就很简单了。在项目目录下打开终端先装依赖再直接启动视频识别界面cd 解压后的项目目录 pip install opencv-python tensorflow numpy python vidGUI.py这里提一下依赖版本OpenCV 建议装 4.x 的 opencv-python不要装成 opencv-contrib-python 或者 2.4 那种老版本否则findContours的返回值数量会对不上。TensorFlow 用 2.x因为 h5 权重文件是 Keras 的 HDF5 格式TF2 的keras.models.load_model可以直接加载。运行后窗口里会读到 demo_car.mp4 并逐帧识别实测普通笔记本大概 12 秒一帧这个速度后面第 4 章细说。第一次跑通之后我建议再做一个验证动作不要只看视频弹窗把识别结果打印到终端。在 vidGUI.py 里找到调用识别函数的位置加一行print(result)这样每帧识别的车牌号会同步输出到控制台答辩时截图更方便也能确认 Unet 和 CNN 两个模型真的都在工作而不只是界面在放视频。3. 训练链路拆解Unet 怎么定位车牌、CNN 怎么认字符train.py 能改的参数在哪开箱即用是这份源码的卖点但如果你只停留在跑通 vidGUI.py答辩时老师问“模型怎么训练的”就会露怯。这一章把训练侧讲透为什么分成两个网络、Unet 和 CNN 各自学什么、train.py 里哪些参数值得动手改。3.1 为什么不做端到端识别而是拆成 Unet 加 CNN 两段式最直观的方案其实是一个大网络输入整张图片输出车牌号字符串。这种端到端方案在工业项目里不少见但毕设场景下有两个硬伤。第一端到端模型需要海量“整图到文本”的标注数据自己标几千张图工作量巨大而且样本不均衡时汉字识别率很难看第二端到端模型是一个黑匣子出错了你不知道是定位错还是识别错答辩很难圆场。拆成两段式之后问题被清晰切割Unet 只回答“车牌在图片的哪个位置”CNN 只回答“这个字符是什么”。Unet 输出的是一个逐像素的概率图错了可以可视化出来看分割边界CNN 输出的是字符类别概率分布错了可以打印 top-5 看模型在犹豫什么。这种可解释性在毕设答辩里是加分项而且两段分别调优——定位不准就补 Unet 数据字符认错就补 CNN 数据——不会互相污染。3.2 Unet 训练输入图和 mask 标签怎么准备loss 怎么设Unet 的训练本质是逐像素二分类每个像素要么属于车牌白色要么属于背景黑色。所以训练数据是成对图片一张是原始车辆图另一张是同尺寸的单通道 mask车牌区域标白其余全黑。标签的制作常用做法是人工用标注工具框出车牌多边形然后填充纯白最后把 mask 缩放到和输入图相同的尺寸。# Unet 部分的核心训练配置常见实现具体以包内 train.py 为准 IMG_H, IMG_W 128, 64 # 车牌宽高比接近 3:1所以宽 64、高 128 EPOCHS 60 BATCH_SIZE 8 # 二分类分割用 binary_crossentropy激活函数用 sigmoid model.compile( optimizeradam, lossbinary_crossentropy, metrics[accuracy] )这里两个参数要解释清楚。IMG_H, IMG_W选 128×64 而不是 256×256是因为车牌区域本身是个扁矩形正方形输入会浪费大量参数去学无效背景而且 resize 到 256 会让训练显存压力大很多。8 的 batch size 在 Unet 里很常见DeepLab 那种大网络往往只能塞 46 张batch 太大显存不够如果你的显卡只有 4G 显存把 BATCH_SIZE 降到 4 是稳妥的选择。loss 用binary_crossentropy而不是 dice loss是因为这个任务里车牌区域占整图比例很小直接用 pixel-wise 交叉熵训练速度快效果也够用追求分割边缘更干净的话可以换 dice loss但毕设没必要。数据增强方面train.py 里一般会有旋转、平移、亮度调整。我强烈建议把亮度增强打开因为实际道路场景里光照变化比车牌形变更常见。每次训练前用torchvision.transforms或imgaug做随机亮度扰动相当于把训练集虚拟扩大了好几倍。3.3 CNN 字符识别类别数、输入尺寸和评估指标Unet 把车牌抠出来之后下一步是字符切分和识别。车牌区域先做二值化然后按字符的水平投影找间隔把 7 个字符逐个切出来再送入 CNN。这个 CNN 的任务是多分类类别集合由车牌字符表决定省份汉字 31 个京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云陕甘青宁新等、数字 0-9 共 10 个、字母去除 I 和 O避免和数字 1、0 混淆后 24 个合计 65 类。# CNN 字符分类的训练参数类别数 汉字 31 数字 10 字母 24 CHAR_CLASSES 65 CHAR_INPUT_SIZE (32, 32) # 字符图统一缩放到 32x32 EPOCHS_CHAR 30 # 多分类用 categorical_crossentropy输出层 softmax model.compile( optimizeradam, losscategorical_crossentropy, metrics[accuracy] )类别数 65 这个数字是整个项目里最该记住的答辩时老师必问。字符输入尺寸选 32×32 是因为单字符切出来后分辨率不高resize 到 32 既能保留笔画细节又不会让全连接层参数爆炸。这里我踩过一个坑字符切分时如果连字符的间隔找不准会把两个字符黏在一起切出来CNN 再怎么训都白搭。所以切分前一定要先做中值滤波去噪再用固定阈值二值化宁可切多一刀也不要切少一刀。3.4 train.py 里真正值得改的参数和训练顺序train.py 的默认配置是直接开箱训练的但我的习惯是先看一眼数据读取路径指向哪里再决定要不要完整跑一轮。训练顺序有讲究先训 Unet 得到定位模型保存 unet.h5再去跑 CNN 的字符识别。因为 CNN 的训练数据来自 Unet 的切分结果如果你先改了 Unet 导致切割区域变化之前训好的 CNN 也要跟着重新验证。# 训练入口的核心流程顺序不能颠倒 # 1. 训练 Unet 并保存权重 unet_model train_unet(train_images_dir, train_masks_dir) unet_model.save(unet.h5) # 2. 用 Unet 对训练集重新预测拿到更准确的车牌裁剪图 plate_images predict_plates(unet_model, train_images_dir) # 3. 用裁剪图制作字符训练集训练 CNN 并保存 chars_dataset build_chars_dataset(plate_images) cnn_model train_cnn(chars_dataset) cnn_model.save(cnn.h5)这份源码包里已经放好了训练完的 h5 文件所以我一般不建议小白从头跑训练——数据准备耗时太长而且没掌握调参节奏前训练出的模型可能还不如包里现成的。正确用法是先用现成 h5 跑通推理等答辩材料准备得差不多了再拿 train.py 在自有数据上迭代优化训出更好的权重替换原来的 h5。这样既安全又能体现工作量。4. GUI 实战GUI.py、vidGUI.py、视频拆帧三件套在答辩演示中怎么配合训练和推理链路都清楚了接下来是演示环节。这个项目提供了两套界面加两个视频辅助脚本正好对应答辩中最常见的三类操作单图识别展示、视频实时识别、把识别过程录制成视频。我在这一章把三个工具的使用顺序和操作节奏讲清楚。4.1 GUI.py 单图识别先确认是文件对话框还是固定路径打开 GUI.py 之后最影响使用体验的一点是它用文件对话框选择图片还是写死了固定路径。常见实现里有个cv2.imread(test.jpg)或者 QFileDialog 选择文件我建议改成文件对话框方式因为答辩时现场图片往往不在固定目录下。# GUI.py 常见的图片读取写法注意中文路径问题 import tkinter.filedialog as fd path fd.askopenfilename( filetypes[(Image, *.jpg *.png *.bmp)] ) # cv2.imread 不支持中文路径需要用 imdecode 代替 import numpy as np img cv2.imdecode(np.fromfile(path, dtypenp.uint8), cv2.IMREAD_COLOR)这一小段代码解决了两个实际问题文件对话框让操作不用改代码而np.fromfile cv2.imdecode解决了中文路径下imread返回 None 的经典问题。识别按钮的回调函数里先调用 2.2 节的recognize_plate再把原图和识别文本一起显示在窗口上这是演示时最有冲击力的画面——左边原图带车牌框右边显示识别出的车牌字符串。演示节奏上我建议准备三张测试图一张蓝色车牌、一张黄色车牌、一张模糊或倾斜车牌。前两张展示正常识别率最后一张展示系统在低质量输入下的表现顺便把 Unet 的概率图可视化出来——把 mask 叠加在原图上说明模型确实在做像素级定位不是靠模板匹配猜的。4.2 vidGUI.py 视频识别帧率上不去程序可没坏视频识别的逻辑比单图多一层循环cv2.VideoCapture 逐帧读取每帧调用一次识别函数把结果叠加绘制到帧上再显示。这里有一个物理规律绕不开——Unet 每帧推理一次耗时约 0.30.5 秒CNN 识别 7 个字符再花 0.1 秒所以整体帧率很难超过 34 FPS。这不是程序 bug而是模型推理的固有开销。我见过不少同学以为死循环了疯狂重启其实是识别速度慢。# vidGUI.py 常见的逐帧识别循环增加抽帧逻辑提升流畅度 cap cv2.VideoCapture(demo_car.mp4) frame_idx 0 while cap.isOpened(): ret, frame cap.read() if not ret: break # 每 3 帧识别一次其余帧复用上一次结果界面会流畅很多 if frame_idx % 3 0: plate_text recognize_plate(frame) frame_idx 1 cv2.putText(frame, plate_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 2) cv2.imshow(Plate Recognition, frame) if cv2.waitKey(1) 0xFF ord(q): break抽帧这个改动作用很明显把识别频率从每帧一次降到每 3 帧一次CPU 占用立刻降下来画面卡顿感消失而且车牌在连续帧里的变化很小识别结果不会因为抽帧变差。waitKey(1)的参数 1 是帧间延时毫秒调大可以让视频播放变慢方便答辩时对着画面讲解注意必须是 1 到 100 之间的值太大会像幻灯片。答辩演示视频时最容易翻车的是找不到视频文件路径。vidGUI.py 里默认读 demo_car.mp4如果你的视频放在子目录记得改成相对路径比如videos/car.mp4或者干脆把视频拷到项目根目录。读取失败时cap.isOpened()返回 False程序会直接退出没有任何错误提示提前打印一下路径是最好的预防。4.3 videospilt.py 和 imgtovid.py处理卡帧视频的后悔药这两个脚本平时用不上但只要遇到一次就值回票价。videospilt.py 把视频按帧导出成图片序列命令形式是传一个视频路径和一个输出目录imgtovid.py 反向操作把处理过的带识别框的帧图片合成新的 mp4 视频。它们组合起来的典型场景是识别速度太慢录不到流畅视频于是先把 demo_car.mp4 拆成帧逐帧加上识别框再用 imgtovid.py 合成一段“看起来实时”的成果视频。# 视频拆帧从 demo_car.mp4 抽出全部帧到 frames/ 目录 python videospilt.py demo_car.mp4 frames_dir # 对每帧做处理后再合成答辩用视频 python imgtovid.py processed_frames output.mp4我一般用两个参数frames_dir 下帧太多时先删掉首尾各 5% 的帧因为车辆进出画面的头尾经常识别不到合成视频时注意cv2.VideoWriter的帧率和原始视频保持一致例如cv2.VideoWriter(output, fourcc, 25, (width, height))里的 25 要和源头一致否则答辩视频播放速度会忽快忽慢。fourcc参数用cv2.VideoWriter_fourcc(*mp4v)是 mp4 容器最稳妥的选择H.264 编码在很多机器上缺库mp4v 保证能写出来。这套流程最大的价值是给答辩留了一条后路现场演示视频如果不流畅直接放事先生成好的带识别框视频再展示终端里的 log效果一点不差。5. 避坑指南OpenCV 环境、H5 加载与中文路径五连坑毕设项目“下载即用”是理想态实际部署时最常见的问题全集中在环境、路径和模型加载上。这一章把我拆这个包时踩过的坑按“现象 → 原因 → 解决”的结构整理出来每条都是可以直接抄作业的排错经验。坑一ModuleNotFoundError: No module named cv2现象运行 vidGUI.py 或 GUI.py 时直接报 No module named cv2程序没法启动。原因Python 环境里根本没装 OpenCV或者装在另一个虚拟环境里了。这种情况在小白机器上出现率最高经常是 pip install 装到了用户目录而当前终端用的是系统 Python。解决先确认当前环境是哪个 Pythonwhich python。然后在同一终端执行pip install opencv-python tensorflow numpy。装完验证一下python -c import cv2; print(cv2.__version__)。如果输出 4.x 版本就说明环境对了。注意不要同时装 opencv-python 和 opencv-contrib-python两个包会互相覆盖文件。坑二cv2.error: OpenCV(4.4.0) 报错提示 findContours 参数不对现象代码跑起来后报错cv2.error: OpenCV(4.4.0) ... in function findContours常见于新下载的源码在旧教程环境下运行。原因OpenCV 3.x 到 4.x 有个破坏性变更——findContours从返回 2 个值变成返回 3 个值contours, hierarchy 和 image 不再返回但很多早期教程代码还是写contours, _ cv2.findContours(...)一旦函数返回 3 个值就会报错。解决统一按新版写法contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)。如果你的代码是image, contours, hierarchy ...的老写法改成新写法即可。更稳妥的办法是直接固定 OpenCV 版本pip install opencv-python4.8.0.74省得版本漂移引发二次问题。坑三加载 unet.h5 或 cnn.h5 时报错或者加载后预测结果全乱现象load_model 时报Unable to open file或KeyError也可能加载成功但识别结果全是乱码字符。原因h5 文件路径写错是最常见的原因其次是 TensorFlow 和 Keras 版本不匹配。报Unable to open file是路径不对报KeyError是模型内部结构键缺失一般是 h5 文件和当前 TF 版本不兼容。解决先检查文件路径。源码里常见load_model(unet.h5)是相对路径必须在项目根目录下运行脚本否则找不到文件。我习惯改成绝对路径model load_model(os.path.join(os.path.dirname(__file__), unet.h5))这样在任何目录启动都能找到。版本问题则统一装tensorflow2.10.0这个版本对 Keras 模型的兼容性最好2.15 之后的版本在部分机器加载旧 h5 会报结构错误。坑四中文路径下图片读取失败cv2.imread 返回 None现象GUI 选择带中文名的图片时窗口能弹出但识别结果为空打印img发现是 None。原因OpenCV 的imread内部用的是 C 标准库文件读写不支持 Windows 下的中文路径。这是 OpenCV 一个非常经典的坑和图片内容无关。解决用 numpy 中转读取img cv2.imdecode(np.fromfile(path, dtypenp.uint8), cv2.IMREAD_COLOR)。这个组合可以利用 numpy 绕过 imread 的文件接口对中文路径完全免疫。保存图片同样用cv2.imencode加tofile的方式否则会报could not find writer之类的错误。坑五模型的 h5 文件在但预测结果波动大同一张图两次结果不一样现象同一张图片多次识别车牌号在几个结果之间跳来跳去。原因大概率是模型加载时没有设置随机种子。Unet 里如果有 Dropout 层而没关闭预测时也会开启随机失活导致同一输入每次前向传播结果不同。另一个常见原因是输入图片没有固定 resize 尺寸每次传入的图宽高比不同模型被迫在变化的空间维度上做预测。解决在 load_model 之后加一行model.trainable False不够关键是在预测前加from tensorflow.keras import backend as K; K.set_learning_phase(0)或者给模型加model.predict(x, verbose0)前设置global_keras_learning_phase。更实用的做法是写死图片预处理cv2.resize(img, (IMG_W, IMG_H))里的 IMG_W、IMG_H 必须和训练时完全一致否则预测阶段 resize 出来的字符长宽比已经乱了CNN 自然认不准。这五条坑基本覆盖了这个项目在机房、笔记本、答辩机器三种环境下的高频故障。遇到报错先对照现象定位原因不要直接重装环境90% 的问题出在路径和版本而不是代码本身。6. 进阶把识别函数抽成独立接口批量处理整个目录跑通 GUI 之后这个项目还差最后一环才算是“可复用”的工程而不是“可演示”的毕设把识别核心从 GUI 里剥离出来做成一个输入图片、输出字符串的纯函数接口。这样你可以脱离界面批量处理任意目录下的图片结果落到 CSV 里无论是做数据集评估还是整理答辩效果图都方便。# batch_predict.py —— 批量识别目录下所有图片结果写入 CSV import glob import csv import cv2 import numpy as np from core import recognize_plate # 复用 core.py 的识别主函数 results [] for path in sorted(glob.glob(test_imgs/*.jpg)): # 用 imdecode 绕开中文路径问题 img cv2.imdecode(np.fromfile(path, dtypenp.uint8), cv2.IMREAD_COLOR) if img is None: results.append([path, READ_ERROR]) continue text recognize_plate(img) results.append([path, text]) print(path.split(/)[-1], -, text) # 以 utf-8-sig 编码写 CSVExcel 打开不会乱码 with open(plate_results.csv, w, newline, encodingutf-8-sig) as f: csv.writer(f).writerows(results)这段脚本里我特意加了几个看似多余的实际处理。sorted(glob.glob(...))保证输出顺序稳定不然每次跑结果文件里图片顺序都随机整理对比表时会很痛苦READ_ERROR标记把读图失败的样本单独记录而不是直接跳过因为批量处理时漏掉的图片往往正是照片集里最需要排查的那几张utf-8-sig编码可以理解为给 CSV 文件加了一个 BOM 头Excel 双击打开时中文列名和图片路径不会变乱码。脚本跑完后我习惯再做一个校验动作把recognize_plate的中间结果——Unet 的 mask 和裁剪出的车牌图——每张都存一份到同名文件夹里和识别文本放到一起作为答辩的辅助材料。老师看到的不只是结论还有模型内部每一步的中间状态可信度完全不同。从那以后我每次拿到这一类“下载即用”的毕设包第一件事都不是双击 GUI而是先把识别函数抽出来写一个批量脚本用 20 张图跑一遍确认模型的稳定输出再回头看界面代码。等哪一天界面崩了或者模型加载不了批量脚本还能继续出结果后路就是这样留下来的。希望帮到你。本文还有配套的精品资源点击获取