news 2026/4/3 4:30:34

python舰船分类检测系统 船只分类 YOLOv8模型 pyqt5界面 10种不同类型舰船 openCV 深度学习torch

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python舰船分类检测系统 船只分类 YOLOv8模型 pyqt5界面 10种不同类型舰船 openCV 深度学习torch

博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

点击查看作者主页,了解更多项目!

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅

2、最全计算机专业毕业设计选题大全(建议收藏)✅

1、项目介绍

技术栈:
Python语言、YOLOv8模型、pyqt5界面、10种不同类型舰船、openCV、torch

软件主要功能

  1. 可进行10种不同类型舰船分类检测,分别为[‘航空母舰’, ‘散货船’, ‘汽车运输船’, ‘集装箱船’, ‘游轮’, ‘驱逐舰’, ‘休闲船’, ‘帆船’, ‘潜艇’, ‘拖船’];
  2. 支持图片、视频及摄像头进行检测,同时支持图片的批量检测;
  3. 界面可实时显示目标位置、目标总数、置信度、用时等信息;
  4. 支持图片或者视频的检测结果保存;

2、项目界面

(1)界面设计

(2)游轮

(3)汽车运输船

(4)游轮

(5)航空母舰

(6)集装箱船

(7)帆船

(8)游轮

3、项目说明

技术栈:
Python语言、YOLOv8模型、pyqt5界面、10种不同类型舰船、openCV、torch

软件主要功能

  1. 可进行10种不同类型舰船分类检测,分别为[‘航空母舰’, ‘散货船’, ‘汽车运输船’, ‘集装箱船’, ‘游轮’, ‘驱逐舰’, ‘休闲船’, ‘帆船’, ‘潜艇’, ‘拖船’];
  2. 支持图片、视频及摄像头进行检测,同时支持图片的批量检测;
  3. 界面可实时显示目标位置、目标总数、置信度、用时等信息;
  4. 支持图片或者视频的检测结果保存;

4、核心代码

# -*- coding: utf-8 -*-importtimefromPyQt5.QtWidgetsimportQApplication,QMainWindow,QFileDialog,\ QMessageBox,QWidget,QHeaderView,QTableWidgetItem,QAbstractItemViewimportsysimportosfromPILimportImageFontfromultralyticsimportYOLO sys.path.append('UIProgram')fromUIProgram.UiMainimportUi_MainWindowimportsysfromPyQt5.QtCoreimportQTimer,Qt,QThread,pyqtSignal,QCoreApplicationimportdetect_toolsastoolsimportcv2importConfigfromUIProgram.QssLoaderimportQSSLoaderfromUIProgram.precess_barimportProgressBarimportnumpyasnpimporttorchclassMainWindow(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.25self.iou=0.7defsignalconnect(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)definitMain(self):self.show_width=770self.show_height=480self.org_path=Noneself.is_camera_open=Falseself.cap=Noneself.device=0iftorch.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)}")defopen_img(self):ifself.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 *.jepg *.png)")ifnotfile_path:returnself.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,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))foreinlocation_list]cls_list=self.results.boxes.cls.tolist()self.cls_list=[int(i)foriincls_list]self.conf_list=self.results.boxes.conf.tolist()self.conf_list=['%.2f %%'%(each*100)foreachinself.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)forindex,idinenumerate(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_names self.ui.comboBox.clear()self.ui.comboBox.addItems(choose_list)iftarget_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)defdetact_batch_imgs(self):ifself.cap:# 打开图片前关闭摄像头self.video_stop()self.is_camera_open=Falseself.ui.CaplineEdit.setText('摄像头未开启')self.cap=Nonedirectory=QFileDialog.getExistingDirectory(self,"选取文件夹","./")# 起始路径ifnotdirectory:returnself.org_path=directory img_suffix=['jpg','png','jpeg','bmp']forfile_nameinos.listdir(directory):full_path=os.path.join(directory,file_name)ifos.path.isfile(full_path)andfile_name.split('.')[-1].lower()inimg_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,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))foreinlocation_list]cls_list=self.results.boxes.cls.tolist()self.cls_list=[int(i)foriincls_list]self.conf_list=self.results.boxes.conf.tolist()self.conf_list=['%.2f %%'%(each*100)foreachinself.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)forindex,idinenumerate(self.cls_list)]choose_list=choose_list+target_names self.ui.comboBox.clear()self.ui.comboBox.addItems(choose_list)iftarget_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()#刷新页面defdraw_rect_and_tabel(self,results,img):now_img=img.copy()location_list=results.boxes.xyxy.tolist()self.location_list=[list(map(int,e))foreinlocation_list]cls_list=results.boxes.cls.tolist()self.cls_list=[int(i)foriincls_list]self.conf_list=results.boxes.conf.tolist()self.conf_list=['%.2f %%'%(each*100)foreachinself.conf_list]forloacation,type_id,confinzip(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))iftarget_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)returnnow_imgdefcombox_change(self):com_text=self.ui.comboBox.currentText()ifcom_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)defget_video_path(self):file_path,_=QFileDialog.getOpenFileName(None,'打开视频','./',"Image files (*.avi *.mp4 *.wmv *.mkv)")ifnotfile_path:returnNoneself.org_path=file_path self.ui.VideolineEdit.setText(file_path)returnfile_pathdefvideo_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)deftabel_info_show(self,locations,clses,confs,path=None):path=pathforlocation,cls,confinzip(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()defvideo_stop(self):self.cap.release()self.timer_camera.stop()# self.timer_info.stop()defopen_frame(self):ret,now_img=self.cap.read()ifret:# 目标检测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))foreinlocation_list]cls_list=results.boxes.cls.tolist()self.cls_list=[int(i)foriincls_list]self.conf_list=results.boxes.conf.tolist()self.conf_list=['%.2f %%'%(each*100)foreachinself.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)forindex,idinenumerate(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_names self.ui.comboBox.clear()self.ui.comboBox.addItems(choose_list)iftarget_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()defvedio_show(self):ifself.is_camera_open:self.is_camera_open=Falseself.ui.CaplineEdit.setText('摄像头未开启')video_path=self.get_video_path()ifnotvideo_path:returnNoneself.cap=cv2.VideoCapture(video_path)self.video_start()self.ui.comboBox.setDisabled(True)defcamera_show(self):self.is_camera_open=notself.is_camera_openifself.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('')ifself.cap:self.cap.release()cv2.destroyAllWindows()self.ui.label_show.clear()defget_resize_size(self,img):_img=img.copy()img_height,img_width,depth=_img.shape ratio=img_width/img_heightifratio>=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)returnself.img_width,self.img_heightdefsave_detect_video(self):ifself.capisNoneandnotself.org_path:QMessageBox.about(self,'提示','当前没有可保存信息,请先打开图片或视频!')returnifself.is_camera_open:QMessageBox.about(self,'提示','摄像头视频无法保存!')returnifself.cap:res=QMessageBox.information(self,'提示','保存视频检测结果可能需要较长时间,请确认是否继续保存?',QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)ifres==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:ifos.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,'提示','图片保存成功!\n文件路径:{}'.format(save_img_path))else:img_suffix=['jpg','png','jpeg','bmp']forfile_nameinos.listdir(self.org_path):full_path=os.path.join(self.org_path,file_name)ifos.path.isfile(full_path)andfile_name.split('.')[-1].lower()inimg_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,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))defupdate_process_bar(self,cur_num,total):ifcur_num==1:self.progress_bar=ProgressBar(self)self.progress_bar.show()ifcur_num>=total:self.progress_bar.close()QMessageBox.about(self,'提示','视频保存成功!\n文件在{}目录下'.format(Config.save_path))returnifself.progress_bar.isVisible()isFalse:# 点击取消保存时,终止进程self.btn2Thread_object.stop()returnvalue=int(cur_num/total*100)self.progress_bar.setValue(cur_num,total,value)QApplication.processEvents()classbtn2Thread(QThread):""" 进行检测后的视频保存 """# 声明一个信号update_ui_signal=pyqtSignal(int,int)def__init__(self,path,model,com_text,conf,iou):super(btn2Thread,self).__init__()self.org_path=path self.model=model self.com_text=com_text self.conf=conf self.iou=iou# 用于绘制不同颜色矩形框self.colors=tools.Colors()self.is_running=True# 标志位,表示线程是否正在运行defrun(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_COUNT total=int(cap.get(prop))print("[INFO] 视频总帧数:{}".format(total))cur_num=0# 确定视频打开并循环读取while(cap.isOpened()andself.is_running):cur_num+=1print('当前第{}帧,总帧数{}'.format(cur_num,total))# 逐帧读取,ret返回布尔值# 参数ret为True 或者False,代表有没有读取到图片# frame表示截取到一帧的图片ret,frame=cap.read()ifret==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()defstop(self):self.is_running=Falseif__name__=="__main__":app=QApplication(sys.argv)win=MainWindow()win.show()sys.exit(app.exec_())

5、项目获取

(绿色聊天软件)yuanmazhiwu 或 biyesheji0005

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 18:16:14

【干货】构建生产级RAG大模型应用:小白也能上手的完整实现手册!

简介 文章全面介绍了检索增强生成(RAG)技术,这是构建需要最新、领域专属知识的大模型应用的标准架构。文章从向量数据库、分块策略到性能优化与生产部署,提供了全链路实践指南,包括混合搜索、交叉编码器重排序、查询改写等优化技巧&#xff…

作者头像 李华
网站建设 2026/4/2 16:57:46

从零开始学C++:深入理解【类与对象】——类的6个默认成员函数

类的6个成员函数 前言一、C什么是“默认成员函数”?二、逐个详解六大默认成员函数1、默认构造函数2、析构函数3、拷贝构造函数4、拷贝赋值运算符5、移动构造函数6、移动赋值运算符 三、“三法则”VS“五法则”四、如何禁止拷贝或移动?五、总结表总结 前言…

作者头像 李华
网站建设 2026/3/16 2:18:52

Netcode for GameObjects Boss Room 多人RPG战斗(4)

Unity Boss Room 启动流程分析 核心启动组件 Boss Room 项目的启动流程由多个关键组件协同工作,以下是主要组件及其职责: ApplicationController.cs - 应用程序入口控制器 配置依赖注入容器,注册核心服务(ConnectionManager、NetworkManager等) 加载初始场景(MainMenu)…

作者头像 李华
网站建设 2026/3/30 20:19:49

Netcode for GameObjects Boss Room 多人RPG战斗(5)

L5_网络同步 Unity Boss Room 网络同步机制分析 1. 核心网络同步技术 Boss Room 项目主要使用 Unity Netcode for GameObjects (Netcode) 实现网络同步,核心技术包括: 1.1 NetworkVariable NetworkVariable 用于在网络上同步状态值,Boss Room 中主要应用于: 生命值同…

作者头像 李华
网站建设 2026/3/30 7:46:32

低代码平台重构:Flutter组件库与鸿蒙分布式能力融合实践

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。 低代码平台重构:Flutter组件库与鸿蒙分布式能力融合实践 低代码平台通过可视化拖拽方式降低开发门槛,结合Flutter的跨平台能力与鸿蒙的分布式特性,可构建覆…

作者头像 李华
网站建设 2026/4/2 14:53:35

如何通过LobeChat最大化利用GPU算力资源?

如何通过LobeChat最大化利用GPU算力资源? 在如今大模型遍地开花的时代,越来越多的开发者和企业希望将强大的AI能力部署到本地环境——无论是出于数据隐私、响应延迟还是成本控制的考量。但一个现实问题摆在面前:这些动辄数十亿参数的语言模型…

作者头像 李华