【问题标题】:Using OpenCV along with Pyttsx3 using multithreading but the screen in freezing continuously使用 OpenCV 和 Pyttsx3 使用多线程但屏幕连续冻结
【发布时间】:2020-07-01 07:50:00
【问题描述】:

我正在尝试制作一个应用程序,该应用程序将使用 OpenCV 从网络摄像头读取实时流以及 Python 文本到语音 (Pyttsx3) 库,该库将同时读出文本并从网络摄像头提供实时视频,但流当它说出文本时被冻结。 所以我创建了单独的线程来获取流,显示它,还为 pyttsx3 创建了一个单独的线程,但是当它说出文本时,视频再次冻结。

我试过这个代码

from threading import Thread
import cv2
from datetime import datetime
import pyttsx3

class VideoGet:
    """
    Class that continuously gets frames from a VideoCapture object
    with a dedicated thread.
    """

    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        (self.grabbed, self.frame) = self.stream.read()
        self.stopped = False
        
    def start(self):    
        Thread(target=self.get, args=()).start()
        return self

    def get(self):
        while not self.stopped:
            if not self.grabbed:
                self.stop()
            else:
                (self.grabbed, self.frame) = self.stream.read()

    def stop(self):
        self.stopped = True
        
        
        
class VideoShow:
    """
    Class that continuously shows a frame using a dedicated thread.
    """

    def __init__(self, frame=None):
        self.frame = frame
        self.stopped = False
        
    def start(self):
        Thread(target=self.show, args=()).start()
        return self

    def show(self):
        while not self.stopped:
            cv2.imshow("Video", self.frame)
            if cv2.waitKey(1) == ord("q"):
                self.stopped = True

    def stop(self):
        self.stopped = True 



class CountsPerSec:
    """
    Class that tracks the number of occurrences ("counts") of an
    arbitrary event and returns the frequency in occurrences
    (counts) per second. The caller must increment the count.
    """

    def __init__(self):
        self._start_time = None
        self._num_occurrences = 0

    def start(self):
        self._start_time = datetime.now()
        return self

    def increment(self):
        self._num_occurrences += 1

    def countsPerSec(self):
        elapsed_time = (datetime.now() - self._start_time).total_seconds()
        #elapsed_time!=0
        return self._num_occurrences/elapsed_time 
    
    
def putIterationsPerSec(frame, iterations_per_sec):
    """
    Add iterations per second text to lower-left corner of a frame.
    """

    cv2.putText(frame, "{:.0f} iterations/sec".format(iterations_per_sec),
        (10, 450), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255))
    return frame    


class TextToSpeech:
    def __init__(self):
        self.engine=pyttsx3.init(debug=True)
        #self.engine.startLoop(True)
    
    def start(self):
        Thread(target=self.speech("i am "),args=()).start()
        return self
    
    def speech(self,saytext):
        self.engine.say(saytext)
        self.engine.runAndWait()
    
        
    def stop(self):
        self.stopped=True     
        
def threadBoth(source=0):
    """
    Dedicated thread for grabbing video frames with VideoGet object.
    Dedicated thread for showing video frames with VideoShow object.
     Dedicated thread for text to speech object.
    Main thread serves only to pass frames between VideoGet and
    VideoShow objects/threads.
    """
    #tts=TextToSpeech()
    tts1=TextToSpeech().start()
    video_getter = VideoGet(source).start()
    video_shower = VideoShow(video_getter.frame).start()
    
   
    cps = CountsPerSec().start()

    while True:
        if video_getter.stopped or video_shower.stopped:
            video_shower.stop()
            video_getter.stop()
            break
        tts1.speech("hey anmol")
        frame = video_getter.frame
        frame = putIterationsPerSec(frame, cps.countsPerSec())
        video_shower.frame = frame

threadBoth(0)        

   

【问题讨论】:

    标签: python-3.x multithreading opencv text-to-speech python-multithreading


    【解决方案1】:

    您好,我也在寻找实现此功能的方法。我发现这对我有用:

    import pyttsx3
    import threading
    import queue
    
    # To play audio text-to-speech during execution
      class TTSThread(threading.Thread):
     def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.daemon = True
        self.start()
    
    def run(self):
        tts_engine = pyttsx3.init()
        tts_engine.startLoop(False)
        t_running = True
        while t_running:
            if self.queue.empty():
                tts_engine.iterate()
            else:
                data = self.queue.get()
                if data == "exit":
                    t_running = False
                else:
                    tts_engine.say(data)
        tts_engine.endLoop()
    
    q = queue.Queue()
    tts_thread = TTSThread(q)
    

    然后您可以使用以下命令更改要在 while 循环中使用的文本:

    q.put(text)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      相关资源
      最近更新 更多