|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
各位大佬,我在主程序中调用另一个模块的摄像头录制,卡死在webcam.py的start_capture的while循环中了,主程序中的停止线程(StopCapturingThread)无法触发,需要如何修改呢?
相关代码如下,感谢各位大佬的帮助!:
-------------main.py-------------
from UIs.mainwindow import Ui_Form
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from Module.VideoRecording.webcam import WebCam
from Module.SmartEyePro.external_interfaces import ExternalInterface
import os
import time
class InteractiveFeatures(WebCam, ExternalInterface):
def __init__(self):
self.webcam = None
self.sep = None
self.biosignalsplux = None
self.brainproducts = None
self.connected_dict = {'webcam': False, 'sep': False, 'biosignalsplux': False, 'brainproducts': False}
self.init_list = []
self.sep_logname = None
self.sep_last_ip = None
# 设置摄像头交互功能
def webcam_init(self):
VideoPath = r'D:\PycharmProjects\IntelligentAssessment\inset'
PNGPath = r'D:\PycharmProjects\IntelligentAssessment\inset'
LogPath = r'D:\PycharmProjects\IntelligentAssessment\inset'
CSVPath = r'D:\PycharmProjects\IntelligentAssessment\inset'
IP = '192.168.1.2'
self.webcam = WebCam(VideoPath, PNGPath, CSVPath, IP)
self.connected_dict['webcam'] = True
def webcam_disconnect(self):
self.webcam = None
self.connected_dict['webcam'] = False
def _webcam_start(self):
self.webcam.start_capture()
def _webcam_stop(self):
self.webcam.stop_capture()
# 选中设备开始采集
def start_capture(self):
for progress, state in self.connected_dict.items():
if state:
self.init_list.append(progress)
init_number = len(self.init_list)
for i in range(init_number):
code = "t{} = Thread(target=self._{}_start)".format(i + 1, self.init_list[i])
exec(code)
for i in range(init_number):
code = "t{}.start()".format(i + 1)
eval(code)
for i in range(init_number):
code = "t{}.join()".format(i + 1)
eval(code)
# 选中设备结束采集
def stop_capture(self):
init_number = len(self.init_list)
for i in range(init_number):
code = "self._{}_stop()".format(self.init_list[i])
eval(code)
for i in range(init_number):
code = "self.{}_init()".format(self.init_list[i])
eval(code)
self.init_list = []
# 生成当前时间
def get_now(self):
now = time.localtime()
nowt = time.strftime("%Y-%m-%d-%H-%M-%S", now)
return nowt
# 开始采集线程
class StartCapturingThread(QThread):
startCapturingSignal = Signal()
def __init__(self, parent=None):
super(StartCapturingThread, self).__init__(parent)
def run(self):
self.startCapturingSignal.emit()
# 结束采集线程
class StopCapturingThread(QThread):
stopCapturingSignal = Signal()
def __init__(self, parent=None):
super(StopCapturingThread, self).__init__(parent)
def run(self):
self.stopCapturingSignal.emit()
class MyMainForm(QMainWindow, Ui_Form, InteractiveFeatures, StartCapturingThread, StopCapturingThread):
def __init__(self, parent=None):
super(MyMainForm, self).__init__(parent)
self.start_capturing_thread = StartCapturingThread()
self.stop_capturing_thread = StopCapturingThread()
self.interactive_features = InteractiveFeatures()
self.setupUi(self)
self.pushButton.clicked.connect(self.btn1clicked)
self.pushButton_2.clicked.connect(self.btn2clicked)
self.pushButton_5.clicked.connect(self.btn5clicked)
self.pushButton_6.clicked.connect(self.btn6clicked)
self.pushButton_15.clicked.connect(self.Start)
self.pushButton_16.clicked.connect(self.Stop)
self.pushButton_11.clicked.connect(self.btn11clicked)
def btn1clicked(self):
IP = self.sep_ip.text()
self.interactive_features.sep_logname = self.sep_logfile.text()
ans = self.interactive_features.sep_init(IP)
if ans:
self.label_9.setPixmap(QPixmap(u"SrcPics/connect_green.svg"))
self.label_10.setPixmap(QPixmap(u"SrcPics/disconnect_black.svg"))
self.sep_ip.setEnabled(False)
self.sep_logfile.setEnabled(False)
else:
QMessageBox.information(self, "连接失败", "连接失败,请检查设备后重试!")
def btn5clicked(self):
self.label_21.setPixmap(QPixmap(u"SrcPics/connect_green.svg"))
self.label_22.setPixmap(QPixmap(u"SrcPics/disconnect_black.svg"))
self.camera_ip.setEnabled(False)
self.camera_frequency.setEnabled(False)
self.interactive_features.webcam_init()
def btn2clicked(self):
self.label_9.setPixmap(QPixmap(u"SrcPics/connect_black.svg"))
self.label_10.setPixmap(QPixmap(u"SrcPics/disconnect_red.svg"))
self.sep_ip.setEnabled(True)
self.sep_logfile.setEnabled(True)
self.interactive_features.sep_disconnect()
def btn6clicked(self):
self.label_21.setPixmap(QPixmap(u"SrcPics/connect_black.svg"))
self.label_22.setPixmap(QPixmap(u"SrcPics/disconnect_red.svg"))
self.camera_ip.setEnabled(True)
self.camera_frequency.setEnabled(True)
self.interactive_features.webcam_disconnect()
def btn11clicked(self):
self.sep_logfile.setText(self.interactive_features.get_now())
def Start(self):
# self.start_capturing_thread = StartCapturingThread()
self.start_capturing_thread.startCapturingSignal.connect(self.interactive_features.start_capture)
self.start_capturing_thread.start()
self.pushButton_15.setEnabled(False)
self.pushButton_17.setEnabled(False)
def Stop(self):
# self.stop_capturing_thread = StopCapturingThread()
self.stop_capturing_thread.stopCapturingSignal.connect(self.interactive_features.stop_capture)
self.stop_capturing_thread.start()
self.pushButton_15.setEnabled(True)
self.pushButton_17.setEnabled(True)
-------------webcam.py-------------
"""
下列代码包括如下功能:
1.start_capture(video_path):在video_path目录下录制网络摄像头拍摄的视频
2.analysis2csv(video_path):分析录制视频表情,将其输出给out.csv
3.screenshot_emotion(joy, surprise, fear, video_path, png_path):将video_path下的视频中joy、surprise、fear三种情绪最大的
帧输出至png_path
4.web_video(video_path, png_path):上述功能总函数,需输入video_path、png_path两个参数
"""
import sys
import os
cwd = os.getcwd()
cac_path = os.path.join(cwd, 'Module', 'CacEmotions')
sys.path.append(cac_path)
from Module.CacEmotions.cac_emotion import getEmotioner, emotion_flag, express_flag
import cv2
import pandas as pd
from Module import CAPTUREFLAG
class WebCam:
def __init__(self, video_path, png_path, csv_path, IP):
self.video_path = video_path
self.png_path = png_path
self.csv_path = csv_path
self.ip = IP
self.capture = True
self.is_connected = False
def start_capture(self):
# 初始化摄像头
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
num = 0
print('Starting capture video!')
while cap.isOpened():
isSuccess, frame = cap.read()
if isSuccess and num == 0:
filename = self.video_path + '\\capture.avi'
video_writer = cv2.VideoWriter(filename, fourcc, 10, size)
video_writer.write(frame)
num = num + 1
if not CAPTUREFLAG.captureflag:
break
cap.release()
cv2.destroyAllWindows()
# TODO: 运行start_capture时,stop_capture函数无法触发,建立新的线程解决该问题
def stop_capture(self):
self.capture = False
joy_max, surprise_max, fear_max = self.analysis2csv()
self.screenshot_emotion(joy_max, surprise_max, fear_max)
看你代码start_capture方法里退出循环的标志位是CAPTUREFLAG.captureflag,但是stop_capture方法里却把self.capture设置为False,这么做能结束循环吗???
要么 start_capture 里if not self.capture ,要么 stop_capture 里 CAPTUREFLAG.captureflag = False
还有你贴出来的程序都不能运行,目录结构都不知道是啥,自写模块也不完整,CAPTUREFLAG.captureflag 都不知道到底是个啥,别人怎么帮你解决问题?
我想问的是程序卡死在我调用的模块的while循环当中了,我的主程序中有开始线程和结束线程,但结束线程无法触发,该如何解决这个问题
你说的是主界面卡住无响应还是单纯地结束线程的时候没反应?如果是前者,你应该用新线程执行你的另一个模块,在主线程执行结束方法,而不是反过来;如果是后者,请参考这个回答的前面两行
最后想说的是程序不要用 exec 和 eval 执行代码,这么写调试困难,也是十分不优雅不Pythonic的写法,除非你想执行用户从外部输入的代码。我是看到这里不想再往下看了,追溯困难
|
|