深度学习:python动物识别系统 YOLOv8模型 PyQt5 深度学习pytorch 计算机(建议收藏)✅
博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅点击查看作者主页,了解更多项目!
🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅
2、最全计算机专业毕业设计选题大全(建议收藏)✅
1、项目介绍
技术栈:
python语言、YOLOv8、PyQt5界面设计、torch、深度学习
可以识别6种动物: 猫、狗、牛、马、鸟、绵羊
2、项目界面
(1)上传图片检测识别

(2)上传图片检测识别

(3)上传图片检测识别

(4)上传视频检测识别

(5)上传视频检测识别

(6)摄像头实时检测识别

(7)导出数据

3、项目说明
总 结
本研究的核心目标是开发和实现一个基于深度学习的动物检测与识别系统,采用YOLOv8目标检测算法,涵盖了数据采集、模型构建、训练优化及实验验证等多个环节。通过对动物图像数据的细致处理和分析,本研究成功建立了一个高效且准确的动物识别系统。
理论上,系统基于YOLOv8算法,具备强大的实时检测和多目标识别能力。实践中,该系统在训练集上达到了超过98%的准确率,在测试集上的准确率为96%左右,展示了良好的泛化能力和稳定性。这表明系统能够准确识别多种动物类别,并在不同环境和复杂场景下保持较高的识别精度,为智能农业、生态保护、野生动物监控等领域提供了重要的技术支持。
此外本研究详细阐述了数据采集与预处理、模型训练、优化策略及评估指标等多个环节,包括数据增强、超参数调优、损失函数选择等技术细节。这些精细化的环节确保了系统的稳定性、可靠性以及对各种环境和动物种类的适应性。
展望未来,随着计算机视觉和深度学习技术的不断进步,本研究开发的动物检测与识别系统有望进一步提升识别精度和处理速度,并扩展至更多物种和场景。这将为农业管理、野生动物保护、智能安防等领域提供更为精准、智能的技术支持,推动相关行业的数字化转型和可持续发展。
在经过多轮训练和优化后,基于YOLOv8的动物检测与识别系统表现出了强大的图像处理和目标识别能力,尤其在实际应用中展现了较高的精度和稳定性。在训练集上,系统的识别准确率达到了98%以上,表明模型能够充分学习和掌握不同动物的特征,如外形、颜色、纹理以及运动模式等。通过针对特定动物种类的深度学习优化,系统成功实现了对“鸟”、“猫”、“狗”、“牛”、“马”和“绵羊”等动物的高效识别和定位。
在测试集上,模型的准确率约为96%,虽然略低于训练集的表现,但这一差距仍然表明系统具有较强的泛化能力,能够处理未见过的样本并保持较好的识别效果。特别是在复杂场景下,如光照变化、不同背景、动物遮挡等情况下,系统依然能够实现较高的识别准确率,证明其在实际应用中的适应能力和鲁棒性。
此外系统在实时性方面表现优异,能够在视频流或实时监控中对动物进行快速识别与跟踪,且识别延迟控制在100ms以内,确保了实时监控和快速反应的需求。通过YOLOv8的高效目标检测算法,系统能够处理高分辨率的图像并同时识别多个动物目标,且无显著性能下降。
总的来说,该动物检测与识别系统具备很好的实际应用前景,尤其是在智能农业、野生动物保护、安防监控等领域。系统的高识别精度和快速响应能力,不仅提高了动物监测的效率,还能够为决策者提供精准的数据支持。此外系统的高泛化能力意味着其能够应对多种环境条件,适应不同种类和状态的动物监测任务,具备广泛的推广价值。在推动智能化管理和生态保护方面,系统的应用将为未来的可持续发展提供有力的技术支持。
4、核心代码
# -*- 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 YOLO
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 torchclass MainWindow(QMainWindow):def __init__(self, parent=None):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)self.conf = 0.3self.iou = 0.7def 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 = 770self.show_height = 480self.org_path = Noneself.is_camera_open = Falseself.cap = Noneself.device = 0 if torch.cuda.is_available() else 'cpu'# 加载检测模型self.model = YOLO(Config.model_path, task='detect')self.model(np.zeros((48, 48, 3)), device=self.device) #预先加载推理模型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.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 表格铺满# self.ui.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)# self.ui.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 设置表格不可编辑self.ui.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置表格整行选中self.ui.tableWidget.verticalHeader().setVisible(False) # 隐藏列标题self.ui.tableWidget.setAlternatingRowColors(True) # 表格背景交替# 设置主页背景图片border-image: url(:/icons/ui_imgs/icons/camera.png)# self.setStyleSheet("#MainWindow{background-image:url(:/bgs/ui_imgs/bg3.jpg)}")def open_img(self):if self.cap:# 打开图片前关闭摄像头self.video_stop()self.is_camera_open = Falseself.ui.CaplineEdit.setText('摄像头未开启')self.cap = None# 弹出的窗口名称:'打开图片'# 默认打开的目录:'./'# 只能打开.jpg与.gif结尾的图片文件# file_path, _ = QFileDialog.getOpenFileName(self.ui.centralwidget, '打开图片', './', "Image files (*.jpg *.gif)")file_path, _ = QFileDialog.getOpenFileName(None, '打开图片', './', "Image files (*.jpg *.jpeg *.png *.bmp)")if not file_path:returnself.ui.comboBox.setDisabled(False)self.org_path = file_pathself.org_img = tools.img_cvread(self.org_path)# 目标检测t1 = time.time()self.results = self.model(self.org_path, conf=self.conf, iou=self.iou)[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]# now_img = self.cv_img.copy()# 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)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)]# object_list = sorted(set(self.cls_list))# for each in object_list:# choose_list.append(Config.CH_names[each])choose_list = choose_list + target_namesself.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,path=self.org_path)def detact_batch_imgs(self):if self.cap:# 打开图片前关闭摄像头self.video_stop()self.is_camera_open = Falseself.ui.CaplineEdit.setText('摄像头未开启')self.cap = Nonedirectory = QFileDialog.getExistingDirectory(self,"选取文件夹","./") # 起始路径if not directory:returnself.org_path = directoryimg_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_pathself.org_img = tools.img_cvread(img_path)# 目标检测t1 = time.time()self.results = self.model(img_path,conf=self.conf, iou=self.iou)[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]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_namesself.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, path=img_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, path=self.org_path)return now_imgdef combox_change(self):com_text = self.ui.comboBox.currentText()if com_text == '全部':cur_box = self.location_listcur_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 *.wmv *.mkv)")if not file_path:return Noneself.org_path = file_pathself.ui.VideolineEdit.setText(file_path)return file_pathdef 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, path=None):path = pathfor 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_count+1)) # 序号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,conf=self.conf, iou=self.iou)[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]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)]# object_list = sorted(set(self.cls_list))# for each in object_list:# choose_list.append(Config.CH_names[each])choose_list = choose_list + target_namesself.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, path=self.org_path)else:self.cap.release()self.timer_camera.stop()def vedio_show(self):if self.is_camera_open:self.is_camera_open = Falseself.ui.CaplineEdit.setText('摄像头未开启')video_path = self.get_video_path()if not video_path:return Noneself.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_openif 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.shaperatio = img_width / img_heightif ratio >= self.show_width / self.show_height:self.img_width = self.show_widthself.img_height = int(self.img_width / ratio)else:self.img_height = self.show_heightself.img_width = int(self.img_height * ratio)return self.img_width, self.img_heightdef save_detect_video(self):if self.cap is None and not self.org_path:QMessageBox.about(self, '提示', '当前没有可保存信息,请先打开图片或视频!')returnif self.is_camera_open:QMessageBox.about(self, '提示', '摄像头视频无法保存!')returnif self.cap:res = QMessageBox.information(self, '提示', '保存视频检测结果可能需要较长时间,请确认是否继续保存?',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.conf,self.iou)self.btn2Thread_object.start()self.btn2Thread_object.update_ui_signal.connect(self.update_process_bar)else:returnelse: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_namesave_img_path = os.path.join(Config.save_path, save_name)# 保存图片cv2.imwrite(save_img_path, self.draw_img)QMessageBox.about(self, '提示', '图片保存成功!\n文件路径:{}'.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_namesave_img_path = os.path.join(Config.save_path, save_name)results = self.model(full_path,conf=self.conf, iou=self.iou)[0]now_img = results.plot()# 保存图片cv2.imwrite(save_img_path, now_img)QMessageBox.about(self, '提示', '图片保存成功!\n文件路径:{}'.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, '提示', '视频保存成功!\n文件在{}目录下'.format(Config.save_path))returnif self.progress_bar.isVisible() is False:# 点击取消保存时,终止进程self.btn2Thread_object.stop()returnvalue = int(cur_num / total *100)self.progress_bar.setValue(cur_num, total, value)QApplication.processEvents()class btn2Thread(QThread):"""进行检测后的视频保存"""# 声明一个信号update_ui_signal = pyqtSignal(int,int)def __init__(self, path, model, com_text,conf,iou):super(btn2Thread, self).__init__()self.org_path = pathself.model = modelself.com_text = com_textself.conf = confself.iou = iou# 用于绘制不同颜色矩形框self.colors = tools.Colors()self.is_running = True # 标志位,表示线程是否正在运行def run(self):# VideoCapture方法是cv2库提供的读取视频方法cap = cv2.VideoCapture(self.org_path)# 设置需要保存视频的格式“xvid”# 该参数是MPEG-4编码类型,文件名后缀为.avifourcc = 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_COUNTtotal = int(cap.get(prop))print("[INFO] 视频总帧数:{}".format(total))cur_num = 0# 确定视频打开并循环读取while (cap.isOpened() and self.is_running):cur_num += 1print('当前第{}帧,总帧数{}'.format(cur_num, total))# 逐帧读取,ret返回布尔值# 参数ret为True 或者False,代表有没有读取到图片# frame表示截取到一帧的图片ret, frame = cap.read()if ret == True:# 检测results = self.model(frame,conf=self.conf,iou=self.iou)[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 = Falseif __name__ == "__main__":# 对于按钮文字显示不全的,完成高清屏幕自适应设置QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)app = QApplication(sys.argv)win = MainWindow()win.show()sys.exit(app.exec_())
🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目编程以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌
5、源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅
点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻
