当我在IDE中运行python项目时,GUI和所有东西都是响应良好的,工作得很好。但当我以.exe运行时,我的线程组件不像在IDE中那样工作。该程序的目标是通过RTSP获取实时提要,并使用opencv显示图像。这是在它自己的线程中完成的
import time
import threading
import cv2
import PIL.Image
"""TODO: add docstring"""
class VideoCapture:
def __init__(self, xmlDict=None, width=None, height=None, fps=None):
"""TODO: add docstring"""
self.xmlDict = xmlDict
self.width = width
self.height = height
self.fps = int(self.xmlDict['FPS'])
self.running = False
# Open the video source
self.vid = cv2.VideoCapture(self.xmlDict['IpAddress'])
if not self.vid.isOpened():
raise ValueError("[MyVideoCapture] Unable to open video source", xmlDict['IpAddress'])
# Get video source width and height
if not self.width:
self.width = int(self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)) # convert float to int
if not self.height:
self.height = int(self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) # convert float to int
if not self.fps:
self.fps = int(self.vid.get(cv2.CAP_PROP_FPS)) # convert float to int
# default value at start
self.ret = False
self.frame = None
self.convert_color = cv2.COLOR_BGR2RGB
#self.convert_color = cv2.COLOR_BGR2GRAY
self.convert_pillow = True
# start thread
self.running = True
self.thread = threading.Thread(target=self.process)
self.thread.start()
def process(self):
"""TODO: add docstring"""
while self.running:
ret, frame = self.vid.read()
if ret:
# process image
frame = cv2.resize(frame, (self.width, self.height))
# it has to record before converting colors
if self.convert_pillow:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = PIL.Image.fromarray(frame)
else:
print('[MyVideoCapture] stream end:', self.video_source)
# TODO: reopen stream
self.running = False
if self.recording:
self.stop_recording()
break
# assign new frame
self.ret = ret
self.frame = frame
# sleep for next frame
#if self.fps != "FULL":
# time.sleep(1/int(self.fps))
我有一个名为“开始”的按钮设置,它每2秒推断一个图像,并打印出标签和信息。当我在.exe中执行此操作时,实时提要和GUI会在进行推理时冻结,但当我在IDE中使用该程序时,它不会冻结。下面是执行此操作的代码
#Button to start inference
self.btn_snapshot = tk.Button(self.btnFrame,width = 10,height = 2, text="Start", command=lambda:threading.Thread(target = self.snapshot).start())
self.btn_snapshot.grid(row = 1,column = 0)
#snapshot function
def snapshot(self):
self.recording = True
while self.recording:
filename = self.vid.snapshot()
result = self.predictImage(filename)
output = self.calculatePassFail(result)
if self.manager:
self.manager.onClick(output)
else:
print('something')
time.sleep(2)
快照函数调用的其他两个方法是predictImage和calculatePassFail
def predictImage(self,imageName):
onnxModel = ImageModel.load(self.xmlDict['ModelPath'])
result = onnxModel.predict_from_file(imageName)
return result
def calculatePassFail(self,result):
calcResult = result.labels[0]
self.labelName = calcResult[0]
self.imgScore = calcResult[1]*100
return f"{self.labelName} with score{self.imgScore}"
所以我找到了一个解决办法,不确定这是否是一个正确的解决办法,但它的工作。因此,出于某种原因,当我使用pyinstaller创建.exe时,有一个控制台窗口,我遇到了问题,但当我使用pyinstaller创建w/out控制台时,使用noconsole标志时,问题消失了,我对图像的推断在它自己的线程中起作用,就像在我的IDE中一样。不知道为什么会这样,但我想它是有效的
相关问题 更多 >
编程相关推荐