
深度學習目標檢測算法yolov8訓練水果檢測數據集 建立基于YOLOv8的水果檢測識別系統pyqt5界面文章目錄深度學習目標檢測算法yolov8訓練水果檢測數據集 建立基于YOLOv8的水果檢測識別系統pyqt5界面1. 安裝依賴2. 數據準備3. 訓練模型4. GUI設計與推理邏輯5. SE注意力機制**1. SE模塊的實現****2. 修改YOLOv8主干網絡****2.1 找到目標卷積層****2.2 修改YOLOv8源碼****3. 配置訓練腳本****4. 驗證改進效果****5. 總結****注意事項**以官方yolov8為主干實現對市面常見水果的檢測識別OpenCV實現對水果的檢測訓練的分類模型識別對水果品種類別的檢測且利用PyQt5設計了簡約的系統UI界面。可選擇添加SE注意力機制的主干模型您還可以更換自己訓練的主干模型進行自己數據的檢測。1基于YOLOv8的水果檢測識別系統該系統支持外接攝像頭實時檢測、常見水果品種的識別且利用PyQt5設計簡約的UI界面。以下是詳細的實現步驟和代碼示例。1. 安裝依賴首先確保安裝了必要的庫pipinstallultralytics opencv-python pyqt5 pandas torch torchvision2. 數據準備假設你的數據集目錄結構如下dataset/ ├── images/ │ ├── train/ │ │ ├── img1.jpg │ │ └── ... │ └── val/ │ ├── img1.jpg │ └── ... └── labels/ ├── train/ │ ├── img1.txt │ └── ... └── val/ ├── img1.txt └── ...每個標簽文件是.txt格式每一行表示一個目標格式為class_id x_center y_center width height創建一個data.yaml文件用于定義數據集路徑和類別名稱train:./dataset/images/trainval:./dataset/images/valnc:5# 類別數量names:[apple,banana,orange,grape,strawberry]# 常見水果類別名稱3. 訓練模型編寫訓練代碼使用YOLOv8進行訓練fromultralyticsimportYOLOdeftrain_model():# 加載預訓練模型modelYOLO(yolov8n.pt)# 使用YOLOv8 Nano預訓練模型# 開始訓練model.train(datadata.yaml,# 數據集配置文件epochs100,# 訓練輪數imgsz640,# 輸入圖片尺寸batch16,# 批次大小devicecuda,# 使用 GPUworkers8,# 數據加載線程數projectruns/train,# 訓練結果保存路徑nameexp# 實驗名稱)if__name____main__:train_model()4. GUI設計與推理邏輯使用PyQt5設計GUI并集成YOLOv8進行推理fromPyQt5.QtWidgetsimportQApplication,QMainWindow,QPushButton,QLabel,QVBoxLayout,QWidget,QFileDialog,QMessageBox,QComboBoxfromPyQt5.QtGuiimportQImage,QPixmapfromPyQt5.QtCoreimportQTimerfromultralyticsimportYOLOimportcv2importpandasaspdimportosclassFruitDetector(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle(水果檢測識別系統)self.setGeometry(100,100,800,600)self.modelYOLO(runs/train/exp/weights/best.pt)# 加載訓練好的模型self.class_names[apple,banana,orange,grape,strawberry]self.current_classNoneself.labelQLabel(self)self.label.setGeometry(50,50,700,400)self.btn_imageQPushButton(選擇圖片,self)self.btn_videoQPushButton(選擇視頻,self)self.btn_cameraQPushButton(打開攝像頭,self)self.btn_exportQPushButton(導出結果,self)self.combo_classesQComboBox(self)self.btn_image.setGeometry(50,500,150,40)self.btn_video.setGeometry(220,500,150,40)self.btn_camera.setGeometry(390,500,150,40)self.btn_export.setGeometry(560,500,150,40)self.combo_classes.setGeometry(320,550,150,40)self.btn_image.clicked.connect(self.detect_single_image)self.btn_video.clicked.connect(self.detect_video)self.btn_camera.clicked.connect(self.open_camera)self.btn_export.clicked.connect(self.export_results)self.combo_classes.addItems([All]self.class_names)self.combo_classes.currentTextChanged.connect(self.switch_class)self.capNoneself.timerQTimer()self.timer.timeout.connect(self.update_frame)self.results_data[]defdetect_single_image(self):檢測單張圖片file_path,_QFileDialog.getOpenFileName(self,選擇圖片,,Images (*.jpg *.png))iffile_path:self.process_image(file_path)defdetect_video(self):檢測視頻文件file_path,_QFileDialog.getOpenFileName(self,選擇視頻,,Videos (*.mp4 *.avi))iffile_path:self.capcv2.VideoCapture(file_path)self.timer.start(30)defopen_camera(self):打開攝像頭進行實時檢測self.capcv2.VideoCapture(0)self.timer.start(30)defupdate_frame(self):更新視頻幀或攝像頭捕獲的畫面ret,frameself.cap.read()ifret:self.process_image(frameframe,is_videoTrue)defprocess_image(self,file_pathNone,frameNone,is_videoFalse):處理圖片并顯示結果ifnotis_video:framecv2.imread(file_path)# 使用 YOLOv8 進行檢測resultsself.model(frame)# 統計目標數量counts{cls:0forclsinself.class_names}forresultinresults:boxesresult.boxes.xyxy.cpu().numpy()classesresult.boxes.cls.cpu().numpy()confidencesresult.boxes.conf.cpu().numpy()forbox,cls,confinzip(boxes,classes,confidences):class_nameself.model.names[int(cls)]counts[class_name]1ifself.current_classAllorclass_nameself.current_class:x1,y1,x2,y2map(int,box)labelf{class_name}{conf:.2f}cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)cv2.putText(frame,label,(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.9,(0,255,0),2)ifnotis_video:self.results_data.append({file:file_path,**counts,detection_time:pd.Timestamp.now()})# 顯示結果ifis_video:self.display_frame(frame)else:self.display_image(frame)defdisplay_image(self,frame):顯示圖片framecv2.cvtColor(frame,cv2.COLOR_BGR2RGB)height,width,channelframe.shape bytes_per_line3*width q_imgQImage(frame.data,width,height,bytes_per_line,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(q_img))defdisplay_frame(self,frame):顯示視頻幀framecv2.cvtColor(frame,cv2.COLOR_BGR2RGB)height,width,channelframe.shape bytes_per_line3*width q_imgQImage(frame.data,width,height,bytes_per_line,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(q_img))defswitch_class(self,class_name):切換目標類別self.current_classclass_nameifclass_name!AllelseNonedefexport_results(self):導出檢測結果為 Excel 或 CSV 文件ifnotself.results_data:QMessageBox.warning(self,警告,沒有檢測結果可導出)returnfile_path,_QFileDialog.getSaveFileName(self,保存結果,,Excel Files (*.xlsx);;CSV Files (*.csv))iffile_path:dfpd.DataFrame(self.results_data)iffile_path.endswith(.xlsx):df.to_excel(file_path,indexFalse)eliffile_path.endswith(.csv):df.to_csv(file_path,indexFalse)QMessageBox.information(self,成功,結果已導出)if__name____main__:appQApplication([])windowFruitDetector()window.show()app.exec_()5. SE注意力機制添加SESqueeze-and-Excitation注意力機制到主干網絡中你需要在訓練之前修改YOLOv8的架構。這通常涉及到自定義YOLOv8模型或使用一些第三方擴展包。在YOLOv8中添加SESqueeze-and-Excitation注意力機制可以增強模型對特征的表示能力從而提高檢測性能。SE模塊的核心思想是通過全局平均池化Global Average Pooling, GAP來獲取通道級的上下文信息并通過一個小型全連接網絡重新校準每個通道的重要性。以下是將SE模塊集成到YOLOv8主干網絡中的步驟和代碼實現1. SE模塊的實現首先我們需要定義一個通用的SE模塊。以下是PyTorch實現的SE模塊代碼importtorchimporttorch.nnasnnclassSEBlock(nn.Module):def__init__(self,channel,reduction16):super(SEBlock,self).__init__()self.fc1nn.Linear(channel,channel//reduction,biasFalse)self.relunn.ReLU(inplaceTrue)self.fc2nn.Linear(channel//reduction,channel,biasFalse)self.sigmoidnn.Sigmoid()defforward(self,x):# Global Average Poolingb,c,_,_x.size()yx.view(b,c,-1).mean(dim2)# [b, c]# Fully Connected Layers for Channel-wise Attentionyself.fc1(y)# [b, c // reduction]yself.relu(y)yself.fc2(y)# [b, c]yself.sigmoid(y).view(b,c,1,1)# [b, c, 1, 1]# Scale the feature mapreturnx*y.expand_as(x)2. 修改YOLOv8主干網絡YOLOv8的主干網絡基于CSPDarknet架構。為了插入SE模塊我們需要找到合適的卷積層并將其與SE模塊結合。2.1 找到目標卷積層YOLOv8的主干網絡通常由多個Conv模塊組成這些模塊包含卷積層、批歸一化層BatchNorm和激活函數SiLU。我們可以在每個Conv模塊后添加SE模塊。2.2 修改YOLOv8源碼假設你已經克隆了YOLOv8的官方倉庫ultralytics我們將修改其主干網絡代碼。找到主干網絡文件YOLOv8的主干網絡代碼通常位于ultralytics/nn/modules/backbone.py文件中。修改Conv模塊在Conv類的基礎上擴展加入SE模塊fromultralytics.nn.modulesimportConvclassSEConv(Conv):def__init__(self,c1,c2,k1,s1,pNone,g1,actTrue,reduction16):super().__init__(c1,c2,k,s,p,g,act)self.seSEBlock(c2,reduction)defforward(self,x):xsuper().forward(x)# 原始卷積操作xself.se(x)# 添加SE模塊returnx替換原始Conv模塊在主干網絡中用SEConv替換原來的Conv模塊。例如在C3模塊或Bottleneck模塊中fromultralytics.nn.modulesimportBottleneckclassSEBottleneck(Bottleneck):def__init__(self,c1,c2,shortcutTrue,g1,e0.5,reduction16):super().__init__(c1,c2,shortcut,g,e)c_int(c2*e)# 隱藏層通道數self.cv1SEConv(c1,c_,1,1,reductionreduction)self.cv2SEConv(c_,c2,3,1,reductionreduction)更新主干網絡將所有使用Conv的地方替換為SEConv或者只在關鍵位置如瓶頸層添加SE模塊。3. 配置訓練腳本在訓練腳本中加載修改后的模型進行訓練fromultralyticsimportYOLOdeftrain_model():# 加載自定義模型已添加SE模塊modelYOLO(yolov8n.yaml)# 確保yaml文件指向修改后的主干網絡# 開始訓練model.train(datadata.yaml,# 數據集配置文件epochs100,# 訓練輪數imgsz640,# 輸入圖片尺寸batch16,# 批次大小devicecuda,# 使用 GPUworkers8,# 數據加載線程數projectruns/train,# 訓練結果保存路徑nameexp-se# 實驗名稱)if__name____main__:train_model()4. 驗證改進效果完成訓練后使用驗證代碼評估添加SE模塊后的模型性能fromultralyticsimportYOLOdefevaluate_model():modelYOLO(runs/train/exp-se/weights/best.pt)# 加載訓練好的模型metricsmodel.val()# 在驗證集上評估模型print(metrics)if__name____main__:evaluate_model()5. 總結將SE注意力機制集成到了YOLOv8的主干網絡中。SE模塊通過對通道特征的動態加權增強了模型對重要特征的關注從而提高了檢測性能。注意事項計算開銷SE模塊會增加少量計算開銷但通常是可以接受的。超參數調整reduction參數控制SE模塊的壓縮比例可以根據任務需求調整。實驗驗證確保在實際應用中對比帶SE模塊和不帶SE模塊的模型性能以驗證其有效性。