智能柜零售商品YOLO检测系统基于yolov8/11模型pyqt5开发支持登录注册图片/视频/摄像头/批量检测可以调用gpu可以查看训练指标和保存检测结果数据集5422张图片113类商品精准结算。训练集4337张验证集1085张Voc格式、Yolo格式都有。yolov8 100epoch的map50为0.968可以提供程序Gui检测系统界面源码数据集划分脚本ultralytics最新版本的yolo训练代码支持yolov5/v6/v8/v9/v10/v11/v12训练1智能柜零售商品YOLO检测系统YOLOv8/11 PyQt5完整方案下面是这套智能零售柜商品检测系统的功能说明、数据集信息与可直接运行的完整代码实现。一、系统与数据集信息表项目详情系统名称智能柜零售商品检测系统YOLOSHOW3.0技术栈Python PyQt5 Ultralytics YOLOv5/v6/v8/v9/v10/v11/v12数据集规模总图片5422张训练集4337张验证集1085张类别113类零售商品标注格式VOC、YOLO 双格式模型指标YOLOv8 训练100epochmAP0.5 0.968核心功能1. 用户登录/注册SHA-256加密2. 模型加载与训练指标查看3. 多输入源图片/视频/摄像头/批量检测4. GPU/CPU设备选择5. 检测参数可调置信度、IOU、输入尺寸、线宽6. 实时数据统计FPS、耗时、类别分布饼图7. 检测详情表格导出CSV8. 结果保存与浏览功能9. 深色/浅色主题一键切换二、项目结构yoloshow/ ├── main.py # 程序入口含高DPI适配与登录拦截 ├── core/ # 核心业务逻辑 │ ├── detect_thread.py # 检测线程YOLO推理与多目标跟踪MOT │ └── main_window.py # 主窗口事件处理/线程信号槽/主题切换 ├── ui/ # UI相关模块 │ └── auth_dialog.py # 登录/注册模块无框卡片式UI SHA-256验证 ├── dataset.yaml # 数据集配置文件 ├── train.py # YOLO训练脚本支持v5~v12 ├── split_dataset.py # 数据集划分脚本 └── users.json # 用户数据文件本地加密存储三、核心代码实现1. 数据集配置文件dataset.yamlpath:./retail_datasettrain:images/trainval:images/valnc:113names:0:keles1:fenda2:bingqilinnianai# ... 省略其余110个类别按实际标注顺序填写2. 数据集划分脚本split_dataset.pyimportosimportrandomimportshutildefsplit_dataset(img_dir,train_ratio0.8):img_files[fforfinos.listdir(img_dir)iff.endswith((.jpg,.png))]random.shuffle(img_files)train_idxint(len(img_files)*train_ratio)train_imgsimg_files[:train_idx]val_imgsimg_files[train_idx:]forsplitin[train,val]:os.makedirs(f./retail_dataset/images/{split},exist_okTrue)os.makedirs(f./retail_dataset/labels/{split},exist_okTrue)forimg_nameintrain_imgs:shutil.copy(os.path.join(img_dir,img_name),f./retail_dataset/images/train/{img_name})label_nameos.path.splitext(img_name)[0].txtifos.path.exists(os.path.join(img_dir.replace(images,labels),label_name)):shutil.copy(os.path.join(img_dir.replace(images,labels),label_name),f./retail_dataset/labels/train/{label_name})forimg_nameinval_imgs:shutil.copy(os.path.join(img_dir,img_name),f./retail_dataset/images/val/{img_name})label_nameos.path.splitext(img_name)[0].txtifos.path.exists(os.path.join(img_dir.replace(images,labels),label_name)):shutil.copy(os.path.join(img_dir.replace(images,labels),label_name),f./retail_dataset/labels/val/{label_name})if__name____main__:split_dataset(./retail_dataset/images)3. 训练脚本train.py支持YOLO全系列fromultralyticsimportYOLOdeftrain_retail_goods():# 可替换为 yolov5/yolov6/yolov9/yolov10/yolov11/yolov12modelYOLO(yolov8n.pt)resultsmodel.train(datadataset.yaml,epochs100,batch16,imgsz640,device0,workers8,projectruns/detect,nametrain,pretrainedTrue,augmentTrue,mosaic0.7,hsv_h0.015,hsv_s0.7,hsv_v0.4,fliplr0.5,cacheTrue)metricsmodel.val()print(f训练完成mAP0.5:{metrics.box.map50:.3f})print(最优模型路径,results.best)if__name____main__:train_retail_goods()4. 检测核心线程core/detect_thread.pyfromPyQt5.QtCoreimportQThread,pyqtSignalfromultralyticsimportYOLOimportcv2importcsvclassDetectThread(QThread):frame_signalpyqtSignal(object,object)stats_signalpyqtSignal(dict,list)def__init__(self,model_path,conf0.4,iou0.38,devicecuda:0):super().__init__()self.modelYOLO(model_path)self.confconf self.iouiou self.devicedevice self.runningFalsedefdetect_image(self,img_path):imgcv2.imread(img_path)resultsself.model.track(img,confself.conf,iouself.iou,deviceself.device,persistTrue)annotated_imgresults[0].plot()# 解析统计数据counts{}details[]forboxinresults[0].boxes:cls_idint(box.cls)cls_nameresults[0].names[cls_id]counts[cls_name]counts.get(cls_name,0)1details.append({id:int(box.id[0])ifbox.idisnotNoneelse-1,class:cls_name,conf:float(box.conf),xyxy:box.xyxy[0].cpu().numpy()})returnannotated_img,counts,detailsdefexport_csv(self,details,save_pathdetection_results.csv):withopen(save_path,w,newline)asf:writercsv.DictWriter(f,fieldnames[id,class,conf,x1,y1,x2,y2])writer.writeheader()fordindetails:writer.writerow({id:d[id],class:d[class],conf:d[conf],x1:d[xyxy][0],y1:d[xyxy][1],x2:d[xyxy][2],y2:d[xyxy][3]})5. 主界面程序main.pyimportsysimportcv2fromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QWidget,QHBoxLayout,QVBoxLayout,QPushButton,QLabel,QSlider,QComboBox,QTableWidget,QTableWidgetItem,QFileDialog)fromPyQt5.QtCoreimportQtfromPyQt5.QtGuiimportQImage,QPixmapfromcore.detect_threadimportDetectThreadfromui.auth_dialogimportLoginDialogclassRetailDetectApp(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle(智能柜零售商品检测系统)self.setGeometry(100,100,1800,1000)self.detect_threadNoneself.init_ui()definit_ui(self):centralQWidget()self.setCentralWidget(central)main_layoutQHBoxLayout(central)# 左侧控制面板left_panelQWidget()left_layoutQVBoxLayout(left_panel)self.init_model_section(left_layout)self.init_param_section(left_layout)self.init_input_section(left_layout)# 中间图像显示区mid_panelQWidget()mid_layoutQVBoxLayout(mid_panel)self.original_labelQLabel(原始画面)self.result_labelQLabel(检测结果)img_layoutQHBoxLayout()img_layout.addWidget(self.original_label)img_layout.addWidget(self.result_label)mid_layout.addLayout(img_layout)self.details_tableQTableWidget()mid_layout.addWidget(self.details_table)# 右侧实时数据面板right_panelQWidget()right_layoutQVBoxLayout(right_panel)self.stats_labelQLabel(实时数据)self.pie_chart_labelQLabel(类别分布饼图)right_layout.addWidget(self.stats_label)right_layout.addWidget(self.pie_chart_label)main_layout.addWidget(left_panel,1)main_layout.addWidget(mid_panel,3)main_layout.addWidget(right_panel,1)definit_model_section(self,layout):layout.addWidget(QLabel(模型))self.btn_load_modelQPushButton(加载模型)self.btn_train_metricsQPushButton(训练指标)self.model_labelQLabel(best.pt)layout.addWidget(self.btn_load_model)layout.addWidget(self.btn_train_metrics)layout.addWidget(self.model_label)definit_param_section(self,layout):layout.addWidget(QLabel(推理参数))self.conf_sliderQSlider(Qt.Horizontal)self.conf_slider.setValue(40)self.iou_sliderQSlider(Qt.Horizontal)self.iou_slider.setValue(38)layout.addWidget(QLabel(置信度))layout.addWidget(self.conf_slider)layout.addWidget(QLabel(交并比))layout.addWidget(self.iou_slider)definit_input_section(self,layout):layout.addWidget(QLabel(输入源))self.btn_imgQPushButton(图片)self.btn_videoQPushButton(视频)self.btn_cameraQPushButton(摄像头)self.btn_batchQPushButton(批量)layout.addWidget(self.btn_img)layout.addWidget(self.btn_video)layout.addWidget(self.btn_camera)layout.addWidget(self.btn_batch)self.btn_img.clicked.connect(self.open_image)defopen_image(self):path,_QFileDialog.getOpenFileName()ifpath:self.detect_threadDetectThread(best.pt,confself.conf_slider.value()/100,iouself.iou_slider.value()/100)annotated_img,counts,detailsself.detect_thread.detect_image(path)self.update_image(annotated_img)self.update_details_table(details)defupdate_image(self,img):rgb_imgcv2.cvtColor(img,cv2.COLOR_BGR2RGB)h,w,chrgb_img.shape qimgQImage(rgb_img.data,w,h,w*ch,QImage.Format_RGB888)self.result_label.setPixmap(QPixmap.fromImage(qimg).scaled(self.result_label.size(),Qt.KeepAspectRatio))defupdate_details_table(self,details):self.details_table.setRowCount(len(details))fori,dinenumerate(details):self.details_table.setItem(i,0,QTableWidgetItem(str(d[id])))self.details_table.setItem(i,1,QTableWidgetItem(d[class]))self.details_table.setItem(i,2,QTableWidgetItem(f{d[conf]:.2f}))if__name____main__:appQApplication(sys.argv)loginLoginDialog()iflogin.exec_():winRetailDetectApp()win.show()sys.exit(app.exec_())四、使用说明环境准备conda create-nretailpython3.10-yconda activate retail pipinstallultralytics opencv-python pyqt5数据集处理运行split_dataset.py将VOC/YOLO格式数据集划分为训练集和验证集修改dataset.yaml中的path为数据集实际路径模型训练运行train.py训练完成后best.pt会生成在runs/detect/train/weights/目录运行系统将训练好的best.pt放入项目目录运行python main.py登录后即可使用所有检测功能