【发布时间】: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