Tkinter程序在IDE(Visual Studio)中运行良好,但在使用pyinstaller编译为.exe时,线程的工作方式与IDE中的不同

2024-06-16 15:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

当我在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}"       

Tags: toselfconvertifdefsnapshotresultwidth
1条回答
网友
1楼 · 发布于 2024-06-16 15:07:24

所以我找到了一个解决办法,不确定这是否是一个正确的解决办法,但它的工作。因此,出于某种原因,当我使用pyinstaller创建.exe时,有一个控制台窗口,我遇到了问题,但当我使用pyinstaller创建w/out控制台时,使用noconsole标志时,问题消失了,我对图像的推断在它自己的线程中起作用,就像在我的IDE中一样。不知道为什么会这样,但我想它是有效的

相关问题 更多 >