練水果檢測數(shù)據(jù)集 深度學(xué)習(xí)目標(biāo)檢測算法 建立基于YOLOv8的水果檢測識別系統(tǒng)+pyqt5界面)
深度學(xué)習(xí)目標(biāo)檢測算法yolov8訓(xùn)練水果檢測數(shù)據(jù)集 建立基于YOLOv8的水果檢測識別系統(tǒng)pyqt5界面文章目錄深度學(xué)習(xí)目標(biāo)檢測算法yolov8訓(xùn)練水果檢測數(shù)據(jù)集 建立基于YOLOv8的水果檢測識別系統(tǒng)pyqt5界面1. 安裝依賴2. 數(shù)據(jù)準(zhǔn)備3. 訓(xùn)練模型4. GUI設(shè)計與推理邏輯5. SE注意力機制**1. SE模塊的實現(xiàn)****2. 修改YOLOv8主干網(wǎng)絡(luò)****2.1 找到目標(biāo)卷積層****2.2 修改YOLOv8源碼****3. 配置訓(xùn)練腳本****4. 驗證改進效果****5. 總結(jié)****注意事項**以官方y(tǒng)olov8為主干實現(xiàn)對市面常見水果的檢測識別OpenCV實現(xiàn)對水果的檢測訓(xùn)練的分類模型識別對水果品種類別的檢測且利用PyQt5設(shè)計了簡約的系統(tǒng)UI界面。可選擇添加SE注意力機制的主干模型您還可以更換自己訓(xùn)練的主干模型進行自己數(shù)據(jù)的檢測。1基于YOLOv8的水果檢測識別系統(tǒng)該系統(tǒng)支持外接攝像頭實時檢測、常見水果品種的識別且利用PyQt5設(shè)計簡約的UI界面。以下是詳細的實現(xiàn)步驟和代碼示例。1. 安裝依賴首先確保安裝了必要的庫pipinstallultralytics opencv-python pyqt5 pandas torch torchvision2. 數(shù)據(jù)準(zhǔn)備假設(shè)你的數(shù)據(jù)集目錄結(jié)構(gòu)如下dataset/ ├── images/ │ ├── train/ │ │ ├── img1.jpg │ │ └── ... │ └── val/ │ ├── img1.jpg │ └── ... └── labels/ ├── train/ │ ├── img1.txt │ └── ... └── val/ ├── img1.txt └── ...每個標(biāo)簽文件是.txt格式每一行表示一個目標(biāo)格式為class_id x_center y_center width height創(chuàng)建一個data.yaml文件用于定義數(shù)據(jù)集路徑和類別名稱train:./dataset/images/trainval:./dataset/images/valnc:5# 類別數(shù)量names:[apple,banana,orange,grape,strawberry]# 常見水果類別名稱3. 訓(xùn)練模型編寫訓(xùn)練代碼使用YOLOv8進行訓(xùn)練fromultralyticsimportYOLOdeftrain_model():# 加載預(yù)訓(xùn)練模型modelYOLO(yolov8n.pt)# 使用YOLOv8 Nano預(yù)訓(xùn)練模型# 開始訓(xùn)練model.train(datadata.yaml,# 數(shù)據(jù)集配置文件epochs100,# 訓(xùn)練輪數(shù)imgsz640,# 輸入圖片尺寸batch16,# 批次大小devicecuda,# 使用 GPUworkers8,# 數(shù)據(jù)加載線程數(shù)projectruns/train,# 訓(xùn)練結(jié)果保存路徑nameexp# 實驗名稱)if__name____main__:train_model()4. GUI設(shè)計與推理邏輯使用PyQt5設(shè)計GUI并集成YOLOv8進行推理fromPyQt5.QtWidgetsimportQApplication,QMainWindow,QPushButton,QLabel,QVBoxLayout,QWidget,QFileDialog,QMessageBox,QComboBoxfromPyQt5.QtGuiimportQImage,QPixmapfromPyQt5.QtCoreimportQTimerfromultralyticsimportYOLOimportcv2importpandasaspdimportosclassFruitDetector(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle(水果檢測識別系統(tǒng))self.setGeometry(100,100,800,600)self.modelYOLO(runs/train/exp/weights/best.pt)# 加載訓(xùn)練好的模型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(導(dǎo)出結(jié)果,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):處理圖片并顯示結(jié)果ifnotis_video:framecv2.imread(file_path)# 使用 YOLOv8 進行檢測resultsself.model(frame)# 統(tǒng)計目標(biāo)數(shù)量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()})# 顯示結(jié)果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):切換目標(biāo)類別self.current_classclass_nameifclass_name!AllelseNonedefexport_results(self):導(dǎo)出檢測結(jié)果為 Excel 或 CSV 文件ifnotself.results_data:QMessageBox.warning(self,警告,沒有檢測結(jié)果可導(dǎo)出)returnfile_path,_QFileDialog.getSaveFileName(self,保存結(jié)果,,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,成功,結(jié)果已導(dǎo)出)if__name____main__:appQApplication([])windowFruitDetector()window.show()app.exec_()5. SE注意力機制添加SESqueeze-and-Excitation注意力機制到主干網(wǎng)絡(luò)中你需要在訓(xùn)練之前修改YOLOv8的架構(gòu)。這通常涉及到自定義YOLOv8模型或使用一些第三方擴展包。在YOLOv8中添加SESqueeze-and-Excitation注意力機制可以增強模型對特征的表示能力從而提高檢測性能。SE模塊的核心思想是通過全局平均池化Global Average Pooling, GAP來獲取通道級的上下文信息并通過一個小型全連接網(wǎng)絡(luò)重新校準(zhǔn)每個通道的重要性。以下是將SE模塊集成到Y(jié)OLOv8主干網(wǎng)絡(luò)中的步驟和代碼實現(xiàn)1. SE模塊的實現(xiàn)首先我們需要定義一個通用的SE模塊。以下是PyTorch實現(xiàn)的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主干網(wǎng)絡(luò)YOLOv8的主干網(wǎng)絡(luò)基于CSPDarknet架構(gòu)。為了插入SE模塊我們需要找到合適的卷積層并將其與SE模塊結(jié)合。2.1 找到目標(biāo)卷積層YOLOv8的主干網(wǎng)絡(luò)通常由多個Conv模塊組成這些模塊包含卷積層、批歸一化層BatchNorm和激活函數(shù)SiLU。我們可以在每個Conv模塊后添加SE模塊。2.2 修改YOLOv8源碼假設(shè)你已經(jīng)克隆了YOLOv8的官方倉庫ultralytics我們將修改其主干網(wǎng)絡(luò)代碼。找到主干網(wǎng)絡(luò)文件YOLOv8的主干網(wǎng)絡(luò)代碼通常位于ultralytics/nn/modules/backbone.py文件中。修改Conv模塊在Conv類的基礎(chǔ)上擴展加入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模塊在主干網(wǎng)絡(luò)中用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)# 隱藏層通道數(shù)self.cv1SEConv(c1,c_,1,1,reductionreduction)self.cv2SEConv(c_,c2,3,1,reductionreduction)更新主干網(wǎng)絡(luò)將所有使用Conv的地方替換為SEConv或者只在關(guān)鍵位置如瓶頸層添加SE模塊。3. 配置訓(xùn)練腳本在訓(xùn)練腳本中加載修改后的模型進行訓(xùn)練fromultralyticsimportYOLOdeftrain_model():# 加載自定義模型已添加SE模塊modelYOLO(yolov8n.yaml)# 確保yaml文件指向修改后的主干網(wǎng)絡(luò)# 開始訓(xùn)練model.train(datadata.yaml,# 數(shù)據(jù)集配置文件epochs100,# 訓(xùn)練輪數(shù)imgsz640,# 輸入圖片尺寸batch16,# 批次大小devicecuda,# 使用 GPUworkers8,# 數(shù)據(jù)加載線程數(shù)projectruns/train,# 訓(xùn)練結(jié)果保存路徑nameexp-se# 實驗名稱)if__name____main__:train_model()4. 驗證改進效果完成訓(xùn)練后使用驗證代碼評估添加SE模塊后的模型性能fromultralyticsimportYOLOdefevaluate_model():modelYOLO(runs/train/exp-se/weights/best.pt)# 加載訓(xùn)練好的模型metricsmodel.val()# 在驗證集上評估模型print(metrics)if__name____main__:evaluate_model()5. 總結(jié)將SE注意力機制集成到了YOLOv8的主干網(wǎng)絡(luò)中。SE模塊通過對通道特征的動態(tài)加權(quán)增強了模型對重要特征的關(guān)注從而提高了檢測性能。注意事項計算開銷SE模塊會增加少量計算開銷但通常是可以接受的。超參數(shù)調(diào)整reduction參數(shù)控制SE模塊的壓縮比例可以根據(jù)任務(wù)需求調(diào)整。實驗驗證確保在實際應(yīng)用中對比帶SE模塊和不帶SE模塊的模型性能以驗證其有效性。