简介:本资源是一套基于YOLOv8的教室窗户破损识别系统完整实现,面向计算机科学、人工智能、自动化等专业的在校学生及初学者,解决教育场景中窗户安全状态智能巡检的实际问题,适用于毕业设计、课程设计、大作业或项目原型开发。压缩包共8个文件(3个Python主程序、3个PyTorch模型文件、2个说明文档),总大小15.91MB,涵盖训练、推理、可视化全流程:包含可直接运行的图形化界面(Visual_interface.py)、预训练与最优权重模型(yolov8n.pt、best.pt)、视频检测脚本(Detection_video.py)及详细部署指南与README说明。已有40人学习下载,所有代码均经实测验证,支持一键启动并自动生成F1分数曲线、混淆矩阵、PR曲线、验证集预测图与标签分布图等核心评估结果,结构清晰、注释完备,无需调参即可获得可信检测效果,是兼具工程完整性与教学实用性的高质量毕设级视觉识别方案。
1. 项目选题与整体设计方案
1.1 为什么选“教室窗户破损识别”这个方向
每年到了毕业设计选题季,我都会收到不少学弟学妹的咨询,问到底选什么题目既好做、又能出成果、还不容易被导师卡住。说实话,“教室窗户破损识别”这个方向在计算机视觉的众多题目里,属于性价比很高的一类。它不像人脸识别、车牌识别那样被做烂了,也不像医疗影像、遥感分析那样对数据量和算力要求极高,但又确确实实是一个有明确落地场景的“视觉检测”任务。
窗户破损检测为什么值得做?往小了说,它是校园设施巡检的刚性需求——老旧教学楼的外窗常年风吹日晒,玻璃开裂、边角碎裂、密封条老化都是安全隐患,靠人工巡检效率太低,而且很多窗户位置较高,肉眼很难看清。往大了说,这套技术本质上是“缺陷检测”的通用范式,换一个数据集就能迁移到厂房玻璃幕墙检测、温室大棚玻璃破损检测、公交站台玻璃破碎报警等场景。所以做这个选题,你积累的不是“一个作业”,而是一套可复用的目标检测流水线能力。
我当时做这个项目,最核心的技术选型就是YOLOv8。为什么不用Faster R-CNN,也不用SSD?因为YOLOv8在精度和速度之间平衡得非常好,尤其适合毕设这种需要“快速出效果、还能跑得动”的场景。Faster R-CNN虽然精度天花板更高,但训练和推理速度太慢,你自己调参的迭代周期会非常痛苦。而YOLOv8在GTX 1660 Ti这种级别的显卡上就能流畅训练,推理帧率更是实时级别,做可视化界面演示的时候体验特别顺滑。
1.2 系统整体架构与技术路线
整套系统的架构并不复杂,但模块划分很清晰。我把它拆成了四个部分:数据层、训练层、推理层、展示层。
数据层负责数据的采集与标注。这里不依赖任何现成的公开数据集,因为“教室窗户破损”这种细粒度场景,公开数据集里几乎找不到现成的标注。所以我采用的是自己拍摄+网络爬取辅助扩充的方式,再用LabelImg逐张标注,最后做数据增强来扩充样本量。
训练层基于Ultralytics官方提供的YOLOv8框架,直接使用Python接口训练。训练过程中最关键的是数据集的YAML配置、超参数调整和训练日志监控。这一步做好了,模型的mAP能达到比较理想的水准。
推理层负责将训练好的模型权重加载进来,对图片、视频或摄像头实时画面进行检测。这个环节的核心是封装一个推理类,对外提供统一的接口,方便可视化界面调用。
展示层就是大家最关心的可视化界面,我用PyQt5来做。界面包含图像显示区、检测设置区、结果统计区和日志输出区。用户可以通过界面上传图片、选择视频文件、打开摄像头,检测结果实时显示在窗口中,识别到的破损窗户会用边界框框出来,并标注类别和置信度。
技术栈总结下来就是:YOLOv8 + PyTorch + PyQt5 + OpenCV + LabelImg + PyInstaller。其中PyTorch负责模型训练,OpenCV负责图像处理与摄像头采集,PyQt5负责界面呈现,PyInstaller负责最终的打包发布。
注意:如果你拿到的项目压缩包里自带了一个训练好的best.pt权重文件,那我强烈建议你拿到手先别急着重新训练,直接跑一遍推理demo,确认流程通了之后再考虑要不要自己重新训练一轮。这样做的原因很朴实:环境问题比模型问题更容易让你崩溃,先通流程再调精度,是最高效的路径。
1.3 项目的难点与亮点分析
这个项目真正的难点不在“训练模型”,而在“数据”和“场景适配”。
窗户破损的形态千差万别:有的是整块玻璃碎裂成蜘蛛网状,有的是边角缺了一小块,有的是玻璃上出现了贯穿性的长裂纹,还有的是窗框松动导致玻璃移位。这些形态差异非常大,如果数据不够丰富,模型很容易过拟合到某一种特定形态上。
另一个难点是背景干扰。教室窗户后面往往有窗帘、黑板、桌椅、树木等复杂背景,遮挡和反光也会对检测造成干扰。这要求我们在标注数据的时候,就要有意识地让样本覆盖各种光线条件和遮挡情况。
至于亮点,我觉得有两个:第一,整个系统是一个“能演示、能落地、能答辩”的完整闭环,从数据集到训练再到可视化界面全部打通,这在毕设评分里非常有优势。第二,我做了数据增强的多样化配置,包括亮度调整、旋转、平移、缩放、翻转等,大幅提升了模型在真实环境下的泛化能力。
2. 数据集构建与标注实操
2.1 数据从哪里来:采集策略与数据规模
很多同学做毕设的时候卡在第一步:“我上哪儿找那么多窗户破损的图片?” 我的经验是三步走。
第一步,自己拍。如果你所在的教学楼恰好有一些旧窗户、裂纹玻璃,那就拿手机在不同时间段、不同角度多拍一些。白天拍逆光的,傍晚拍顺光的,晴天拍反射的,阴天拍散射的。拍的时候注意覆盖不同楼层、不同教室、不同窗户样式。别小看自己拍的照片,这些恰恰是最贴近实际部署场景的正样本。
第二步,网络获取。可以到开源图片网站搜索“broken window glass”“cracked window”等关键词,用脚本批量下载。这样做的好处是快速扩充数据量,但需要注意图片质量和版权问题——用于学术研究问题不大,商用需要谨慎。下载之后要人工筛选一遍,去掉低分辨率、严重模糊、纯示意图等干扰图片。
第三步,间接扩充。如果实在凑不够破损样本,可以把“完好的窗户”也加入数据集,作为背景负样本。虽然YOLO并不强制要求负样本,但加入一定比例的负样本可以减少误检,让模型明白“不是所有窗户都要框出来,只有破损的才要框”。
我最终的数据集规模是:破损窗户图片约1800张,负样本(完好窗户)约400张,总计2200张。按7:2:1的比例划分训练集、验证集和测试集。这个规模对于单类别目标检测来说属于中等偏小,但因为加了数据增强,实际训练效果完全够用。
2.2 标注工具与标注规范:LabelImg实操指南
标注工具我用的是LabelImg,这是视觉检测入门最经典的标注工具,纯图形界面,安装简单,导出的格式能直接转成YOLO需要的txt格式。
安装LabelImg有两种方式。一种是pip安装:
pip install labelImg另一种是GitHub克隆源码后运行:
git clone https://github.com/HumanSignal/labelImg.git cd labelImg pyrcc5 -o libs/resources.py resources.qrc python labelImg.py推荐用第一种方式,省事。
标注过程有几个非常关键的细节,直接决定模型好坏。首先是标注框的紧致度:不要像画简笔画一样大概框个范围就完事,而是要紧贴破损区域的边缘。YOLO的训练逻辑是将候选框与标注框计算IoU,如果你的标注框比实际目标大一圈,模型学出来的预测框也会偏大;如果标注框只框住了破损的一部分,模型学到的特征就不完整。其次是破损伤痕的标注策略:一块大面积碎玻璃上有多条裂纹,不要标注成多个小框,而是用一个稍微大一点的框覆盖整个破损连通区域,除非两条裂纹中间有明显的完好区域分隔。再有就是边界情况的处理:如果窗框和玻璃同时出现在画面里,只标注玻璃破损的部分,不要把“窗户存在”本身误标成破损。
我把标注要点整理成了一张速查表,给当时一起做项目的小伙伴用:
| 情况 | 标注策略 |
|---|---|
| 整块玻璃大面积碎裂 | 用一个大框覆盖整个碎裂区域 |
| 边角缺块 | 框住缺口边缘,不要包含完好的窗框 |
| 细长裂纹 | 框住整条裂纹,框边距裂纹边缘3到5像素 |
| 玻璃表面反光严重 | 标注前调整亮度确认破损区域,避免把反光误判为裂纹 |
| 多扇窗户同框 | 只有可见破损的那扇标框,完好窗户不标 |
| 轻微破损、不确定是否标注 | 宁缺毋滥,删除该图或做负样本 |
2.3 数据增强与格式转换:从XML到YOLO的txt
LabelImg默认导出的是Pascal VOC格式的XML文件,YOLOv8需要的却是每个图片对应一个同名txt文件的格式,内容为“类别编号 x_center y_center width height”,其中x_center、y_center、width、height都是归一化到0到1之间的相对坐标。
转换脚本其实不复杂,核心代码如下:
import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_path, save_dir, classes): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find('size/width').text) img_h = int(root.find('size/height').text) out_lines = [] for obj in root.findall('object'): cls_name = obj.find('name').text if cls_name not in classes: continue cls_id = classes.index(cls_name) bbox = obj.find('bndbox') xmin = int(bbox.find('xmin').text) ymin = int(bbox.find('ymin').text) xmax = int(bbox.find('xmax').text) ymax = int(bbox.find('ymax').text) x_center = ((xmin + xmax) / 2) / img_w y_center = ((ymin + ymax) / 2) / img_h width = (xmax - xmin) / img_w height = (ymax - ymin) / img_h out_lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") if out_lines: txt_name = os.path.splitext(os.path.basename(xml_path))[0] + '.txt' with open(os.path.join(save_dir, txt_name), 'w') as f: f.write('\n'.join(out_lines))数据增强我用的不是自己手写的图像处理函数,而是直接利用YOLOv8训练时自带的在线增强策略。Ultralytics框架在训练阶段默认会做马赛克增强(mosaic)、随机翻转、随机色彩抖动等操作,这些不需要我们额外配置。不过如果你发现自己的数据集偏小,可以在训练参数里把hsv_h、hsv_s、degrees这些增强强度调高一点。我当时把degrees设成了10(即允许正负10度旋转),把hsv_s从默认的0.7调到了0.9,有效提升了模型对不同光线条件的适应能力。
3. 模型训练与调试全流程
3.1 环境配置:从零到能跑通YOLOv8
训练环境我是这么搭的:操作系统Windows 11,显卡GTX 1660 Ti,显存6GB。这个配置属于学生党的经典配置,性能不算强,但跑YOLOv8n和YOLOv8s是绰绰有余的。
Python环境管理我强烈建议用Anaconda,专门为这个项目建一个独立的虚拟环境,避免和日常开发环境互相污染。
conda create -n yolo-window python=3.9 conda activate yolo-window pip install ultralytics pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 pip install pyqt5 opencv-python pillow这里有一个非常容易踩的坑:PyTorch和CUDA版本的匹配问题。如果你直接用pip install torch,装的很可能是CPU版本,训练速度慢到怀疑人生。正确的做法是先到PyTorch官网根据自己的CUDA版本选择对应的安装命令。GTX 1660 Ti的驱动支持CUDA 11.8,所以用上面的命令装cu118版本是稳妥的。装完之后可以用下面的命令验证CUDA是否可用:
import torch print(torch.cuda.is_available()) # 输出True说明GPU可用 print(torch.cuda.get_device_name(0))如果输出True,恭喜你,GPU环境配好了。如果输出False,大概率是PyTorch版本装错了,回炉重装。
3.2 数据集组织与YAML配置文件编写
YOLOv8训练前需要把数据集按照固定的目录结构组织好:
datasets/ windows/ images/ train/ val/ test/ labels/ train/ val/ test/ data.yaml注意,images和labels两个目录下的子目录名称必须完全对应——images/train里的每张图片,必须在labels/train里有同名的txt标注文件。一个很常见的低级错误是图片缩略名和标注名对不上,导致训练时报“Found no labels”的警告。
data.yaml文件是训练的关键配置,内容如下:
train: D:/yolov8-window/datasets/windows/images/train val: D:/yolov8-window/datasets/windows/images/val test: D:/yolov8-window/datasets/windows/images/test nc: 1 names: ['broken_window']这里有两个坑。第一,路径建议写绝对路径,不要写相对路径。虽然Ultralytics支持相对路径,但有时候工作目录切换会导致路径解析失败,绝对路径最保险。第二,nc即类别数量,如果你的项目只有“破损窗户”一个类别,那就是1;如果你做了多类别,比如“broken_window”“good_window”“cracked_frame”三个类别,nc就要改成3,names也要对应修改。
3.3 训练参数选择与调优心得
训练命令本身不复杂,核心是参数的理解和选择。
yolo detect train data=data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=8 device=0 project=runs name=exp1我第一次跑的时候用的是YOLOv8s预训练权重,batch设为8,epochs跑到80轮左右,验证集mAP50大概在0.78左右。后来我换了YOLOv8n,发现虽然参数量小了三分之一,但在这个相对简单的单类别任务上,mAP50居然还能保持在0.74以上,而训练速度提升了很多。如果你拿到的显卡显存只有4GB,建议直接用yolov8n.pt,把batch降到4,还是能顺利跑完的。
几个重要的参数我展开讲一下:
- imgsz是输入图像的尺寸,默认640。在显存允许的情况下,越大理论上精度越高,但训练速度会变慢。如果图像里窗户本身很小、破损区域很细微,可以考虑把imgsz设为800或者960,但代价是显存占用大幅上升。
- batch是批大小,受显存限制。6GB显存跑yolov8n、imgsz=640时,batch=8比较稳;batch=16容易OOM。如果显存不够但你又不想降batch,可以开启梯度累积——用ultralytics的nbs(名义批大小)参数,设置nbs=64,它会自动在每积累到64张图后才更新一次权重。
- epochs是训练轮数。不要盲目追求大epochs,尤其是数据量不大的情况下,训练到后面会出现过拟合——训练集loss降得挺漂亮,验证集mAP反而开始往下掉。我建议训练过程中密切关注val loss曲线的拐点,在验证集性能不再提升的时候提前停止,使用early-stopping机制(Ultralytics默认开启,patience默认100)。
训练完成后,在runs/detect/exp*/weights/目录下会生成两个文件:best.pt和last.pt。best.pt是验证集表现最好的权重,last.pt是最后一轮的权重。部署和推理一律使用best.pt,last.pt只是用来断点续训的。
3.4 训练日志分析与精度评估
训练过程输出的日志信息很丰富,但很多初学者看不懂。我挑几个关键指标解释一下:
- box_loss:边界框回归损失,反映预测框与真实标注框的位置差异。这个值越低越好。
- cls_loss:分类损失,反映类别预测的对错。单类别分类一般不会太差。
- dfl_loss:分布焦点损失,是YOLOv8特有的一种边界框回归辅助损失。
- mAP50:IoU阈值为0.5时的平均精度。这是最常看的指标,0.5以上算及格,0.7以上算表现不错。
- mAP50-95:IoU从0.5到0.95的区间平均精度,这个指标更严格,通常比mAP50低不少。
我当时最好的模型是YOLOv8s训练100轮后的结果:mAP50约0.82,mAP50-95约0.56,精度precision约0.87,召回recall约0.79。对于单类别窗户破损检测而言,这个成绩已经能满足实际使用需求了。
如果你训练完发现mAP50始终在0.5以下,先别急着调网络结构,检查一下数据集标注是否准确、数据量是否太少、学习率是否过大。大部分初学者模型效果差,问题都出在数据上而不是网络上。
3.5 模型改进思路:轻量化与注意力机制
如果你学有余力,想把模型效果再往上提一档,可以尝试两个方向。
第一个方向是模型剪枝和轻量化。YOLOv8本身有n/s/m/l/x五个版本,如果部署环境算力紧张,可以用YOLOv8n作为baseline,再做通道剪枝,把不重要的卷积通道去掉,模型大小可以再压缩30%左右。剪枝的工具可以用Ultralytics自带的prune功能,也可以用torch.prune手动实现。
第二个方向是引入注意力机制。比如在C2f模块中嵌入SE模块或CBAM模块,让模型更加关注破损区域的特征而忽略背景干扰。这个操作需要修改YOLOv8的网络结构代码,建议在修改前先备份原始模型定义文件。我试过在 backbone 的最后一个 C2f 模块后面加一个 SE 注意力模块,mAP50约提升2到3个百分点,代价是推理时间增加了约15%。对毕设来说,这个精度的提升完全是收益大于成本。
4. 可视化界面开发与部署打包
4.1 界面功能规划与布局设计
可视化界面是毕设答辩时候的“门面”,一个操作顺畅、界面清爽的系统,确实能给你的答辩表现加分不少。我当时用PyQt5做的界面整体布局是左右结构的:
- 左侧是图像显示区,负责显示原始图像和检测后的结果图像,占整个窗口大约70%的宽度。
- 右侧是控制面板,从上到下依次是:模型加载按钮、图片检测按钮、视频检测按钮、摄像头检测按钮、置信度阈值滑块、检测类别选择下拉框、实时结果统计(检测个数、处理耗时)、日志输出框。
窗口标题栏显示“教室窗户破损识别系统”,底部状态栏显示当前使用的模型路径和推理设备。
具体到PyQt5的组件选型,图像显示用QLabel配合setPixmap显示QPixmap;按钮用QPushButton;滑条用QSlider;下拉框用QComboBox;日志输出用QTextEdit并设置为只读模式。整体代码量在600行左右,工作量适中,适合在答辩前集中时间完成。
4.2 核心推理模块封装与集成
界面写得再花哨,如果推理模块耦合得乱七八糟,后面调试的时候会非常痛苦。我的建议是单独写一个detector.py文件,封装一个WindowDetector类,对外提供简洁的接口。
from ultralytics import YOLO import cv2 class WindowDetector: def __init__(self, model_path, conf_thres=0.25): self.model = YOLO(model_path) self.conf_thres = conf_thres def detect_image(self, image_path, save_path=None): results = self.model.predict( source=image_path, conf=self.conf_thres, verbose=False ) annotated = results[0].plot() if save_path: cv2.imwrite(save_path, annotated) return annotated, len(results[0].boxes) def detect_frame(self, frame): results = self.model.predict( source=frame, conf=self.conf_thres, verbose=False ) annotated = results[0].plot() return annotated, len(results[0].boxes)detect_image接收图片路径,返回标注后的图像和检测数量;detect_frame接收一帧图像(numpy数组),返回标注帧和检测数量。界面线程只需要调用这两个方法,就能完成所有检测逻辑,完全不需要关心模型内部的实现细节。
这里有一个多线程的问题必须注意:PyQt5的主线程是GUI线程,负责刷新界面。如果直接在按钮点击事件里调用模型推理,推理过程会阻塞界面,导致窗口卡死。正确做法是用QThread或者QThreadPool将推理任务放到子线程中执行,推理完成后通过信号槽机制把结果传回主线程更新界面。我第一次写的时候偷懒没有用多线程,结果在视频检测的时候窗口直接假死,后来老老实实改成了线程池方案,才解决这个问题。
4.3 依赖打包与exe生成:PyInstaller避坑实录
打包是整个项目交付的最后一公里,也是坑最多的一环。打包工具我用的是PyInstaller,命令如下:
pip install pyinstaller pyinstaller -D -w main.py --name WindowDetector --icon icon.ico-D参数表示生成目录模式(dist目录下会有整个文件夹),-w表示不显示控制台窗口。如果你希望双击exe之后能看到控制台日志,可以去掉-w,调试阶段建议不要带-w,方便看到报错信息。
打包过程中我踩过几个印象很深的坑,分享出来帮大家避雷:
第一个坑是模型路径问题。PyInstaller打包后的exe在运行时,当前工作目录不一定是exe所在目录。如果你在代码里写了相对路径来加载模型,很容易出现“文件找不到”的报错。解决方案是把模型文件放进资源目录,或者用sys._MEIPASS来获取打包后的临时解包目录。更简单粗暴的方案是让程序启动时弹窗让用户手动选择模型路径,虽然体验略差,但最不容易出错。
第二个坑是动态库丢失。PyQt5和OpenCV都有大量的C++动态链接库,PyInstaller默认会尝试自动收集,但偶尔会漏掉一些。如果你遇到“DLL load failed”的报错,可以用--collect-all参数强制收集:
pyinstaller -D -w main.py --name WindowDetector --collect-all ultralytics --collect-all cv2 --collect-all PyQt5第三个坑是打包体积过大。一个空白的PyQt5程序打包出来就有100多MB,加上PyTorch库之后体积直奔1GB以上。这是因为PyTorch的CUDA运行库体积本身就很大。如果用户机器上没有NVIDIA显卡,可以安装CPU版本的PyTorch再打包,体积能省掉三四百MB,但检测速度会慢一些。还能接受的话建议顺势把部署时的模型推理也切到CPU模式,保证兼容性。
4.4 完整部署流程与使用说明
项目最终交付的时候,我把整个部署流程整理成了一个文档,确保一个从没接触过YOLO的用户也能看着文档跑起来。部署分两条路线:源码运行和exe运行。
源码运行适合有Python基础的用户,步骤是:
- 安装Anaconda,创建Python 3.9虚拟环境;
- 在虚拟环境中安装requirements.txt里的所有依赖;
- 将数据集目录放在项目根目录下(或者直接使用训练好的权重);
- 运行main.py启动界面;
- 点击“加载模型”按钮,选择best.pt文件;
- 点击“选择图片”或“选择视频”,开始检测。
exe运行适合完全不想碰代码的用户,步骤更简单:把dist/WindowDetector整个文件夹拷到目标机器,双击WindowDetector.exe启动。注意要保证exe和模型文件在同一目录下,并且目标机器上安装了VC++运行库。
4.5 常见问题快速排查表
这部分是我觉得整个项目里最有价值的内容,因为很多问题是只有真刀真枪跑过才发现得了的。我整理成了一个速查表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 训练时提示“Found no labels” | 标注txt文件和图片名称不对应 | 检查labels目录下文件名是否与images一致,检查转换脚本输出 |
| CUDA out of memory | batch过大或imgsz过大 | 降低batch到4或2,降低imgsz到480 |
| 训练loss下不去 | 数据标注错误过多,学习率不合适 | 抽样检查标注质量,降低lr到0.001以下重训 |
| 推理时误检率偏高 | 置信度阈值过低 | 将conf_thres从0.25提高到0.4到0.5 |
| 界面点击检测卡死 | 推理放在了主线程 | 改成QThread子线程推理 |
| 摄像头打开失败 | 摄像头索引错误或被占用 | 尝试cap = cv2.VideoCapture(1)或释放其他占用程序 |
| PyInstaller打包后模型加载失败 | 模型路径相对路径问题 | 改用绝对路径或sys._MEIPASS方式加载 |
| 视频检测帧率太低 | 模型推理速度成为瓶颈 | 换用yolov8n模型,缩小imgsz,开启half精度 |
5. 项目验收要点与二次开发建议
5.1 毕设答辩时的验收标准
如果你把这个项目当毕设来推进,答辩时老师最关心的几个点是:数据集是否真实有效、模型是否自己训练过(而不是只下载了个权重)、系统演示是否流畅、对模型原理的理解是否到位。建议你提前准备好一份训练过程的截图记录,包括每个阶段的loss曲线、验证集的mAP指标变化、以及几张典型图片的检测效果对比。这些材料不仅能证明工作量,也能在答辩现场帮你有理有据地讲清楚技术细节。
5.2 从“够用”到“好用”的扩展方向
一个模型训出来只是开始,要把系统做得更有应用价值,还有很多方向可以扩展。比如把视频检测改造成实时监控模式,接入RTSP流,就能对教学楼进行7x24小时的不间断巡检;比如给检测系统加上告警能力,检测到破损窗户后自动调用短信或邮件接口通知后勤人员;再比如用TensorRT对模型做量化加速,让推理速度在嵌入式设备上也保持实时。这些都是可以在原创性说明里突出写的加分项。
我在实际使用中还有一个体会:如果你手头的数据集里完好窗户的照片特别多,你可以顺手训练一个两分类模型(完好的窗户 vs 破损的窗户),然后在界面里增加一个下拉框让用户自由切换检测模式。这个功能做起来不复杂,但演示效果会非常惊艳,因为老师会看到你的系统不仅能“找出破损”,还能“区分好坏”。
最后再分享一个小技巧:如果你拿到的压缩包里自带的模型在你自己拍摄的照片上效果不好,不要全盘否定它,先检查一下输入图像的分辨率。很多模型训练时的imgsz是640,如果你的照片是4000x3000的,检测小目标时容易丢失细节。在界面里做一次自适应缩放,把长边缩放到1280再送入模型,往往就能明显提升效果。这种工程细节虽然不起眼,但恰恰是区分“会用模型”和“会做系统”的分水岭。
本文还有配套的精品资源,点击获取