夠物網站空間100m夠不夠可以做防盜水印的網站
鶴壁市浩天電氣有限公司
2026/01/24 08:49:06
夠物網站空間100m夠不夠,可以做防盜水印的網站,網絡營銷推廣的劣勢,做谷歌推廣比較好的公司一、項目介紹 本文介紹了基于YOLOv10的香蕉成熟度檢測系統(tǒng)#xff0c;旨在通過計算機視覺技術自動識別和分類香蕉的成熟度。該系統(tǒng)能夠準確區(qū)分六種不同的成熟度類別#xff1a;新鮮成熟#xff08;freshripe#xff09;、新鮮未成熟#xff08;freshunripe#xff09;、…一、項目介紹本文介紹了基于YOLOv10的香蕉成熟度檢測系統(tǒng)旨在通過計算機視覺技術自動識別和分類香蕉的成熟度。該系統(tǒng)能夠準確區(qū)分六種不同的成熟度類別新鮮成熟freshripe、新鮮未成熟freshunripe、過熟overripe、成熟ripe、腐爛rotten和未成熟unripe。通過使用YOLOv10模型我們實現了高效的實時檢測并在包含18,074張圖像的數據集上進行了訓練、驗證和測試。實驗結果表明該系統(tǒng)在香蕉成熟度檢測任務中表現出色具有較高的準確率和魯棒性。目錄一、項目介紹二、項目功能展示系統(tǒng)功能演示與介紹視頻圖片檢測批量圖片檢測視頻檢測攝像頭實時檢測三、數據集介紹數據集概述類別分布數據預處理數據集特點數據集配置文件data.yaml數據集制作流程四、項目環(huán)境配置創(chuàng)建虛擬環(huán)境pycharm中配置anaconda安裝所需要庫五、模型訓練訓練代碼訓練結果六、核心代碼七、項目二、項目功能展示系統(tǒng)功能?圖片檢測可對單張圖片進行香蕉成熟度檢測返回檢測框及類別信息。?批量圖片檢測支持文件夾輸入一次性檢測多張圖片生成批量檢測結果。?視頻檢測支持視頻文件輸入檢測視頻中每一幀的香蕉成熟度情況。?攝像頭實時檢測連接USB 攝像頭實現實時監(jiān)測。演示與介紹視頻基于深度學習的香蕉成熟度識別檢測系統(tǒng)YOLOv10YOLO數據集UI界面Python項目源碼模型_嗶哩嗶哩_bilibili基于深度學習的香蕉成熟度識別檢測系統(tǒng)YOLOv10YOLO數據集UI界面Python項目源碼模型圖片檢測該功能允許用戶通過單張圖片進行目標檢測。輸入一張圖片后YOLO模型會實時分析圖像識別出其中的目標并在圖像中框出檢測到的目標輸出帶有目標框的圖像。批量圖片檢測用戶可以一次性上傳多個圖片進行批量處理。該功能支持對多個圖像文件進行并行處理并返回每張圖像的目標檢測結果適用于需要大規(guī)模處理圖像數據的應用場景。視頻檢測視頻檢測功能允許用戶將視頻文件作為輸入。YOLO模型將逐幀分析視頻并在每一幀中標記出檢測到的目標。最終結果可以是帶有目標框的視頻文件或實時展示適用于視頻監(jiān)控和分析等場景。攝像頭實時檢測該功能支持通過連接攝像頭進行實時目標檢測。YOLO模型能夠在攝像頭拍攝的實時視頻流中進行目標檢測實時識別并顯示檢測結果。此功能非常適用于安防監(jiān)控、無人駕駛、智能交通等應用提供即時反饋。核心特點高精度基于YOLO模型提供精確的目標檢測能力適用于不同類型的圖像和視頻。實時性特別優(yōu)化的算法使得實時目標檢測成為可能無論是在視頻還是攝像頭實時檢測中響應速度都非???。批量處理支持高效的批量圖像和視頻處理適合大規(guī)模數據分析。三、數據集介紹數據集概述本研究所使用的數據集包含18,074張香蕉圖像涵蓋了六種不同的成熟度類別。數據集分為訓練集、驗證集和測試集具體分布如下訓練集15,792張圖像驗證集1,525張圖像測試集757張圖像類別分布數據集中包含六種成熟度類別具體如下新鮮成熟freshripe香蕉完全成熟外觀呈現鮮黃色無明顯瑕疵。新鮮未成熟freshunripe香蕉未完全成熟外觀呈現綠色質地較硬。過熟overripe香蕉過度成熟外觀呈現深黃色或帶有褐色斑點質地較軟。成熟ripe香蕉成熟外觀呈現黃色質地適中。腐爛rotten香蕉已經腐爛外觀呈現深褐色或黑色質地非常軟可能有明顯的腐爛痕跡。未成熟unripe香蕉未成熟外觀呈現綠色質地非常硬。數據預處理在訓練YOLOv10模型之前我們對數據集進行了以下預處理步驟圖像增強通過隨機旋轉、縮放、翻轉等操作增加數據的多樣性提高模型的泛化能力。標注文件每張圖像都配有相應的標注文件標注文件中包含香蕉的邊界框信息和類別標簽。數據劃分將數據集按照一定比例劃分為訓練集、驗證集和測試集確保模型訓練和評估的獨立性。數據集特點多樣性數據集中的香蕉圖像涵蓋了不同的光照條件、背景環(huán)境和拍攝角度確保了模型的魯棒性。平衡性各類別的樣本數量相對均衡避免了類別不平衡問題對模型性能的影響。高質量標注所有圖像都經過精確標注確保了訓練數據的質量。訓練集測試集驗證集數據集配置文件data.yamltrain: datasetsimages rain val: datasetsimagesval test: datasetsimages est nc: 10 names: [army worm, legume blister beetle, red spider, rice gall midge, rice leaf roller, rice leafhopper, rice water weevil, wheat phloeothrips, white backed plant hopper, yellow rice borer],數據集制作流程標注數據使用標注工具如LabelImg、CVAT等對圖像中的目標進行標注。每個目標需要標出邊界框并且標注類別。轉換格式將標注的數據轉換為YOLO格式。YOLO標注格式為每行object-class x_center y_center width height這些坐標是相對于圖像尺寸的比例。分割數據集將數據集分為訓練集、驗證集和測試集通常的比例是80%訓練集、10%驗證集和10%測試集。準備標簽文件為每張圖片生成一個對應的標簽文件確保標簽文件與圖片的命名一致。調整圖像尺寸根據YOLO網絡要求統(tǒng)一調整所有圖像的尺寸如416x416或608x608。四、項目環(huán)境配置創(chuàng)建虛擬環(huán)境首先新建一個Anaconda環(huán)境每個項目用不同的環(huán)境這樣項目中所用的依賴包互不干擾。終端輸入conda create -n yolov10 python3.9激活虛擬環(huán)境conda activate yolov10安裝cpu版本pytorchpip install torch torchvision torchaudiopycharm中配置anaconda安裝所需要庫pip install -r requirements.txt五、模型訓練訓練代碼from ultralytics import YOLOv10 model_path yolov10s.pt data_path datasets/data.yaml if __name__ __main__: model YOLOv10(model_path) results model.train(datadata_path, epochs500, batch64, device0, workers0, projectruns/detect, nameexp, )根據實際情況更換模型 yolov10n.yaml (nano)輕量化模型適合嵌入式設備速度快但精度略低。 yolov10s.yaml (small)小模型適合實時任務。 yolov10m.yaml (medium)中等大小模型兼顧速度和精度。 yolov10b.yaml (base)基本版模型適合大部分應用場景。 yolov10l.yaml (large)大型模型適合對精度要求高的任務。--batch 64每批次64張圖像。--epochs 500訓練500輪。--datasets/data.yaml數據集配置文件。--weights yolov10s.pt初始化模型權重yolov10s.pt是預訓練的輕量級YOLO模型。訓練結果六、核心代碼# -*- coding: utf-8 -*- import time from PyQt5.QtWidgets import QApplication , QMainWindow, QFileDialog,QMessageBox,QWidget,QHeaderView,QTableWidgetItem, QAbstractItemView import sys import os from PIL import ImageFont from ultralytics import YOLOv10 sys.path.append(UIProgram) from UIProgram.UiMain import Ui_MainWindow import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal,QCoreApplication import detect_tools as tools import cv2 import Config from UIProgram.QssLoader import QSSLoader from UIProgram.precess_bar import ProgressBar import numpy as np # import torch class MainWindow(QMainWindow): def __init__(self, parentNone): super(QMainWindow, self).__init__(parent) self.ui Ui_MainWindow() self.ui.setupUi(self) self.initMain() self.signalconnect() # 加載css渲染效果 style_file UIProgram/style.css qssStyleSheet QSSLoader.read_qss_file(style_file) self.setStyleSheet(qssStyleSheet) def signalconnect(self): self.ui.PicBtn.clicked.connect(self.open_img) self.ui.comboBox.activated.connect(self.combox_change) self.ui.VideoBtn.clicked.connect(self.vedio_show) self.ui.CapBtn.clicked.connect(self.camera_show) self.ui.SaveBtn.clicked.connect(self.save_detect_video) self.ui.ExitBtn.clicked.connect(QCoreApplication.quit) self.ui.FilesBtn.clicked.connect(self.detact_batch_imgs) def initMain(self): self.show_width 700 self.show_height 500 self.org_path None self.is_camera_open False self.cap None # self.device 0 if torch.cuda.is_available() else cpu # 加載檢測模型 self.model YOLOv10(runs/detect/exp/weights/best.pt, taskdetect) self.model(np.zeros((48, 48, 3))) #預先加載推理模型 self.fontC ImageFont.truetype(Font/platech.ttf, 25, 0) self.colors tools.Colors() self.timer_camera QTimer() # 更新檢測信息表格 # self.timer_info QTimer() # 保存視頻 self.timer_save_video QTimer() # 表格 self.ui.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) self.ui.tableWidget.verticalHeader().setDefaultSectionSize(40) self.ui.tableWidget.setColumnWidth(0, 80) # 設置列寬 self.ui.tableWidget.setColumnWidth(1, 200) self.ui.tableWidget.setColumnWidth(2, 150) self.ui.tableWidget.setColumnWidth(3, 90) self.ui.tableWidget.setColumnWidth(4, 230) self.ui.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) # 設置表格整行選中 self.ui.tableWidget.verticalHeader().setVisible(False) # 隱藏列標題 self.ui.tableWidget.setAlternatingRowColors(True) # 表格背景交替 def open_img(self): if self.cap: # 打開圖片前關閉攝像頭 self.video_stop() self.is_camera_open False self.ui.CaplineEdit.setText(攝像頭未開啟) self.cap None file_path, _ QFileDialog.getOpenFileName(None, 打開圖片, ./, Image files (*.jpg *.jepg *.png)) if not file_path: return self.ui.comboBox.setDisabled(False) self.org_path file_path self.org_img tools.img_cvread(self.org_path) # 目標檢測 t1 time.time() self.results self.model(self.org_path)[0] t2 time.time() take_time_str {:.3f} s.format(t2 - t1) self.ui.time_lb.setText(take_time_str) location_list self.results.boxes.xyxy.tolist() self.location_list [list(map(int, e)) for e in location_list] cls_list self.results.boxes.cls.tolist() self.cls_list [int(i) for i in cls_list] self.conf_list self.results.boxes.conf.tolist() self.conf_list [%.2f %% % (each*100) for each in self.conf_list] total_nums len(location_list) cls_percents [] for i in range(1): if total_nums 0: res 0 else: res self.cls_list.count(i) / total_nums cls_percents.append(res) self.set_percent(cls_percents) now_img self.results.plot() self.draw_img now_img # 獲取縮放后的圖片尺寸 self.img_width, self.img_height self.get_resize_size(now_img) resize_cvimg cv2.resize(now_img,(self.img_width, self.img_height)) pix_img tools.cvimg_to_qpiximg(resize_cvimg) self.ui.label_show.setPixmap(pix_img) self.ui.label_show.setAlignment(Qt.AlignCenter) # 設置路徑顯示 self.ui.PiclineEdit.setText(self.org_path) # 目標數目 target_nums len(self.cls_list) self.ui.label_nums.setText(str(target_nums)) # 設置目標選擇下拉框 choose_list [全部] target_names [Config.names[id] _ str(index) for index,id in enumerate(self.cls_list)] choose_list choose_list target_names self.ui.comboBox.clear() self.ui.comboBox.addItems(choose_list) if target_nums 1: self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]]) self.ui.label_conf.setText(str(self.conf_list[0])) self.ui.label_xmin.setText(str(self.location_list[0][0])) self.ui.label_ymin.setText(str(self.location_list[0][1])) self.ui.label_xmax.setText(str(self.location_list[0][2])) self.ui.label_ymax.setText(str(self.location_list[0][3])) else: self.ui.type_lb.setText() self.ui.label_conf.setText() self.ui.label_xmin.setText() self.ui.label_ymin.setText() self.ui.label_xmax.setText() self.ui.label_ymax.setText() # # 刪除表格所有行 self.ui.tableWidget.setRowCount(0) self.ui.tableWidget.clearContents() self.tabel_info_show(self.location_list, self.cls_list, self.conf_list,pathself.org_path) def detact_batch_imgs(self): if self.cap: # 打開圖片前關閉攝像頭 self.video_stop() self.is_camera_open False self.ui.CaplineEdit.setText(攝像頭未開啟) self.cap None directory QFileDialog.getExistingDirectory(self, 選取文件夾, ./) # 起始路徑 if not directory: return self.org_path directory img_suffix [jpg,png,jpeg,bmp] for file_name in os.listdir(directory): full_path os.path.join(directory,file_name) if os.path.isfile(full_path) and file_name.split(.)[-1].lower() in img_suffix: # self.ui.comboBox.setDisabled(False) img_path full_path self.org_img tools.img_cvread(img_path) # 目標檢測 t1 time.time() self.results self.model(img_path)[0] t2 time.time() take_time_str {:.3f} s.format(t2 - t1) self.ui.time_lb.setText(take_time_str) location_list self.results.boxes.xyxy.tolist() self.location_list [list(map(int, e)) for e in location_list] cls_list self.results.boxes.cls.tolist() self.cls_list [int(i) for i in cls_list] self.conf_list self.results.boxes.conf.tolist() self.conf_list [%.2f %% % (each * 100) for each in self.conf_list] total_nums len(location_list) cls_percents [] for i in range(1): if total_nums 0: res 0 else: res self.cls_list.count(i) / total_nums cls_percents.append(res) self.set_percent(cls_percents) now_img self.results.plot() self.draw_img now_img # 獲取縮放后的圖片尺寸 self.img_width, self.img_height self.get_resize_size(now_img) resize_cvimg cv2.resize(now_img, (self.img_width, self.img_height)) pix_img tools.cvimg_to_qpiximg(resize_cvimg) self.ui.label_show.setPixmap(pix_img) self.ui.label_show.setAlignment(Qt.AlignCenter) # 設置路徑顯示 self.ui.PiclineEdit.setText(img_path) # 目標數目 target_nums len(self.cls_list) self.ui.label_nums.setText(str(target_nums)) # 設置目標選擇下拉框 choose_list [全部] target_names [Config.names[id] _ str(index) for index, id in enumerate(self.cls_list)] choose_list choose_list target_names self.ui.comboBox.clear() self.ui.comboBox.addItems(choose_list) if target_nums 1: self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]]) self.ui.label_conf.setText(str(self.conf_list[0])) self.ui.label_xmin.setText(str(self.location_list[0][0])) self.ui.label_ymin.setText(str(self.location_list[0][1])) self.ui.label_xmax.setText(str(self.location_list[0][2])) self.ui.label_ymax.setText(str(self.location_list[0][3])) else: self.ui.type_lb.setText() self.ui.label_conf.setText() self.ui.label_xmin.setText() self.ui.label_ymin.setText() self.ui.label_xmax.setText() self.ui.label_ymax.setText() # # 刪除表格所有行 self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, pathimg_path) self.ui.tableWidget.scrollToBottom() QApplication.processEvents() #刷新頁面 def draw_rect_and_tabel(self, results, img): now_img img.copy() location_list results.boxes.xyxy.tolist() self.location_list [list(map(int, e)) for e in location_list] cls_list results.boxes.cls.tolist() self.cls_list [int(i) for i in cls_list] self.conf_list results.boxes.conf.tolist() self.conf_list [%.2f %% % (each * 100) for each in self.conf_list] for loacation, type_id, conf in zip(self.location_list, self.cls_list, self.conf_list): type_id int(type_id) color self.colors(int(type_id), True) # cv2.rectangle(now_img, (int(x1), int(y1)), (int(x2), int(y2)), colors(int(type_id), True), 3) now_img tools.drawRectBox(now_img, loacation, Config.CH_names[type_id], self.fontC, color) # 獲取縮放后的圖片尺寸 self.img_width, self.img_height self.get_resize_size(now_img) resize_cvimg cv2.resize(now_img, (self.img_width, self.img_height)) pix_img tools.cvimg_to_qpiximg(resize_cvimg) self.ui.label_show.setPixmap(pix_img) self.ui.label_show.setAlignment(Qt.AlignCenter) # 設置路徑顯示 self.ui.PiclineEdit.setText(self.org_path) # 目標數目 target_nums len(self.cls_list) self.ui.label_nums.setText(str(target_nums)) if target_nums 1: self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]]) self.ui.label_conf.setText(str(self.conf_list[0])) self.ui.label_xmin.setText(str(self.location_list[0][0])) self.ui.label_ymin.setText(str(self.location_list[0][1])) self.ui.label_xmax.setText(str(self.location_list[0][2])) self.ui.label_ymax.setText(str(self.location_list[0][3])) else: self.ui.type_lb.setText() self.ui.label_conf.setText() self.ui.label_xmin.setText() self.ui.label_ymin.setText() self.ui.label_xmax.setText() self.ui.label_ymax.setText() # 刪除表格所有行 self.ui.tableWidget.setRowCount(0) self.ui.tableWidget.clearContents() self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, pathself.org_path) return now_img def combox_change(self): com_text self.ui.comboBox.currentText() if com_text 全部: cur_box self.location_list cur_img self.results.plot() self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]]) self.ui.label_conf.setText(str(self.conf_list[0])) else: index int(com_text.split(_)[-1]) cur_box [self.location_list[index]] cur_img self.results[index].plot() self.ui.type_lb.setText(Config.CH_names[self.cls_list[index]]) self.ui.label_conf.setText(str(self.conf_list[index])) # 設置坐標位置值 self.ui.label_xmin.setText(str(cur_box[0][0])) self.ui.label_ymin.setText(str(cur_box[0][1])) self.ui.label_xmax.setText(str(cur_box[0][2])) self.ui.label_ymax.setText(str(cur_box[0][3])) resize_cvimg cv2.resize(cur_img, (self.img_width, self.img_height)) pix_img tools.cvimg_to_qpiximg(resize_cvimg) self.ui.label_show.clear() self.ui.label_show.setPixmap(pix_img) self.ui.label_show.setAlignment(Qt.AlignCenter) def get_video_path(self): file_path, _ QFileDialog.getOpenFileName(None, 打開視頻, ./, Image files (*.avi *.mp4 *.jepg *.png)) if not file_path: return None self.org_path file_path self.ui.VideolineEdit.setText(file_path) return file_path def video_start(self): # 刪除表格所有行 self.ui.tableWidget.setRowCount(0) self.ui.tableWidget.clearContents() # 清空下拉框 self.ui.comboBox.clear() # 定時器開啟每隔一段時間讀取一幀 self.timer_camera.start(1) self.timer_camera.timeout.connect(self.open_frame) def tabel_info_show(self, locations, clses, confs, pathNone): path path for location, cls, conf in zip(locations, clses, confs): row_count self.ui.tableWidget.rowCount() # 返回當前行數(尾部) self.ui.tableWidget.insertRow(row_count) # 尾部插入一行 item_id QTableWidgetItem(str(row_count1)) # 序號 item_id.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) # 設置文本居中 item_path QTableWidgetItem(str(path)) # 路徑 # item_path.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) item_cls QTableWidgetItem(str(Config.CH_names[cls])) item_cls.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) # 設置文本居中 item_conf QTableWidgetItem(str(conf)) item_conf.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) # 設置文本居中 item_location QTableWidgetItem(str(location)) # 目標框位置 # item_location.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) # 設置文本居中 self.ui.tableWidget.setItem(row_count, 0, item_id) self.ui.tableWidget.setItem(row_count, 1, item_path) self.ui.tableWidget.setItem(row_count, 2, item_cls) self.ui.tableWidget.setItem(row_count, 3, item_conf) self.ui.tableWidget.setItem(row_count, 4, item_location) self.ui.tableWidget.scrollToBottom() def video_stop(self): self.cap.release() self.timer_camera.stop() # self.timer_info.stop() def open_frame(self): ret, now_img self.cap.read() if ret: # 目標檢測 t1 time.time() results self.model(now_img)[0] t2 time.time() take_time_str {:.3f} s.format(t2 - t1) self.ui.time_lb.setText(take_time_str) location_list results.boxes.xyxy.tolist() self.location_list [list(map(int, e)) for e in location_list] cls_list results.boxes.cls.tolist() self.cls_list [int(i) for i in cls_list] self.conf_list results.boxes.conf.tolist() self.conf_list [%.2f %% % (each * 100) for each in self.conf_list] total_nums len(location_list) cls_percents [] for i in range(1): if total_nums! 0 : res self.cls_list.count(i) / total_nums else : res0 cls_percents.append(res) self.set_percent(cls_percents) now_img results.plot() # 獲取縮放后的圖片尺寸 self.img_width, self.img_height self.get_resize_size(now_img) resize_cvimg cv2.resize(now_img, (self.img_width, self.img_height)) pix_img tools.cvimg_to_qpiximg(resize_cvimg) self.ui.label_show.setPixmap(pix_img) self.ui.label_show.setAlignment(Qt.AlignCenter) # 目標數目 target_nums len(self.cls_list) self.ui.label_nums.setText(str(target_nums)) # 設置目標選擇下拉框 choose_list [全部] target_names [Config.names[id] _ str(index) for index, id in enumerate(self.cls_list)] choose_list choose_list target_names self.ui.comboBox.clear() self.ui.comboBox.addItems(choose_list) if target_nums 1: self.ui.type_lb.setText(Config.CH_names[self.cls_list[0]]) self.ui.label_conf.setText(str(self.conf_list[0])) self.ui.label_xmin.setText(str(self.location_list[0][0])) self.ui.label_ymin.setText(str(self.location_list[0][1])) self.ui.label_xmax.setText(str(self.location_list[0][2])) self.ui.label_ymax.setText(str(self.location_list[0][3])) else: self.ui.type_lb.setText() self.ui.label_conf.setText() self.ui.label_xmin.setText() self.ui.label_ymin.setText() self.ui.label_xmax.setText() self.ui.label_ymax.setText() self.tabel_info_show(self.location_list, self.cls_list, self.conf_list, pathself.org_path) else: self.cap.release() self.timer_camera.stop() def vedio_show(self): if self.is_camera_open: self.is_camera_open False self.ui.CaplineEdit.setText(攝像頭未開啟) video_path self.get_video_path() if not video_path: return None self.cap cv2.VideoCapture(video_path) self.video_start() self.ui.comboBox.setDisabled(True) def camera_show(self): self.is_camera_open not self.is_camera_open if self.is_camera_open: self.ui.CaplineEdit.setText(攝像頭開啟) self.cap cv2.VideoCapture(0) self.video_start() self.ui.comboBox.setDisabled(True) else: self.ui.CaplineEdit.setText(攝像頭未開啟) self.ui.label_show.setText() if self.cap: self.cap.release() cv2.destroyAllWindows() self.ui.label_show.clear() def get_resize_size(self, img): _img img.copy() img_height, img_width , depth _img.shape ratio img_width / img_height if ratio self.show_width / self.show_height: self.img_width self.show_width self.img_height int(self.img_width / ratio) else: self.img_height self.show_height self.img_width int(self.img_height * ratio) return self.img_width, self.img_height def save_detect_video(self): if self.cap is None and not self.org_path: QMessageBox.about(self, 提示, 當前沒有可保存信息請先打開圖片或視頻) return if self.is_camera_open: QMessageBox.about(self, 提示, 攝像頭視頻無法保存!) return if self.cap: res QMessageBox.information(self, 提示, 保存視頻檢測結果可能需要較長時間請確認是否繼續(xù)保存,QMessageBox.Yes | QMessageBox.No , QMessageBox.Yes) if res QMessageBox.Yes: self.video_stop() com_text self.ui.comboBox.currentText() self.btn2Thread_object btn2Thread(self.org_path, self.model, com_text) self.btn2Thread_object.start() self.btn2Thread_object.update_ui_signal.connect(self.update_process_bar) else: return else: if os.path.isfile(self.org_path): fileName os.path.basename(self.org_path) name , end_name fileName.rsplit(.,1) save_name name _detect_result. end_name save_img_path os.path.join(Config.save_path, save_name) # 保存圖片 cv2.imwrite(save_img_path, self.draw_img) QMessageBox.about(self, 提示, 圖片保存成功!
文件路徑:{}.format(save_img_path)) else: img_suffix [jpg, png, jpeg, bmp] for file_name in os.listdir(self.org_path): full_path os.path.join(self.org_path, file_name) if os.path.isfile(full_path) and file_name.split(.)[-1].lower() in img_suffix: name, end_name file_name.rsplit(.,1) save_name name _detect_result. end_name save_img_path os.path.join(Config.save_path, save_name) results self.model(full_path)[0] now_img results.plot() # 保存圖片 cv2.imwrite(save_img_path, now_img) QMessageBox.about(self, 提示, 圖片保存成功!
文件路徑:{}.format(Config.save_path)) def update_process_bar(self,cur_num, total): if cur_num 1: self.progress_bar ProgressBar(self) self.progress_bar.show() if cur_num total: self.progress_bar.close() QMessageBox.about(self, 提示, 視頻保存成功!
文件在{}目錄下.format(Config.save_path)) return if self.progress_bar.isVisible() is False: # 點擊取消保存時終止進程 self.btn2Thread_object.stop() return value int(cur_num / total *100) self.progress_bar.setValue(cur_num, total, value) QApplication.processEvents() def set_percent(self, probs): pass class btn2Thread(QThread): update_ui_signal pyqtSignal(int,int) def __init__(self, path, model, com_text): super(btn2Thread, self).__init__() self.org_path path self.model model self.com_text com_text # 用于繪制不同顏色矩形框 self.colors tools.Colors() self.is_running True # 標志位表示線程是否正在運行 def run(self): # VideoCapture方法是cv2庫提供的讀取視頻方法 cap cv2.VideoCapture(self.org_path) # 設置需要保存視頻的格式“xvid” # 該參數是MPEG-4編碼類型文件名后綴為.avi fourcc cv2.VideoWriter_fourcc(*XVID) # 設置視頻幀頻 fps cap.get(cv2.CAP_PROP_FPS) # 設置視頻大小 size (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) # VideoWriter方法是cv2庫提供的保存視頻方法 # 按照設置的格式來out輸出 fileName os.path.basename(self.org_path) name, end_name fileName.split(.) save_name name _detect_result.avi save_video_path os.path.join(Config.save_path, save_name) out cv2.VideoWriter(save_video_path, fourcc, fps, size) prop cv2.CAP_PROP_FRAME_COUNT total int(cap.get(prop)) print([INFO] 視頻總幀數{}.format(total)) cur_num 0 # 確定視頻打開并循環(huán)讀取 while (cap.isOpened() and self.is_running): cur_num 1 print(當前第{}幀總幀數{}.format(cur_num, total)) ret, frame cap.read() if ret True: # 檢測 results self.model(frame)[0] frame results.plot() out.write(frame) self.update_ui_signal.emit(cur_num, total) else: break # 釋放資源 cap.release() out.release() def stop(self): self.is_running False if __name__ __main__: app QApplication(sys.argv) win MainWindow() win.show() sys.exit(app.exec_())七、項目演示與介紹視頻基于深度學習的香蕉成熟度識別檢測系統(tǒng)YOLOv10YOLO數據集UI界面Python項目源碼模型_嗶哩嗶哩_bilibili基于深度學習的香蕉成熟度識別檢測系統(tǒng)YOLOv10YOLO數據集UI界面Python項目源碼模型