<p>我想你是对的,但我无法用你的代码保存文件。下面是一个视频流到视频小部件,使用多线程来获取帧。每个摄影机流有两个线程:</p>
<ul>
<li>线程#1-专用于仅从相机流读取帧。在</li>
<li>线程2-专用于处理帧(显示和写入)。在</li>
</ul>
<p>我们将读帧与显示/写入分开,因为<code>cv2.VideoCapture.read()</code>是一个阻塞操作。因此,我们在它自己的独立线程中读取帧,通过减少I/O操作的延迟来“提高”FPS。另外,通过将帧捕获隔离到它自己的线程中,总是有一个帧可以被处理,而不必等待I/O操作完成并返回一个新帧。在第二个专门处理的线程中,我们现在可以自由地显示和保存每个帧到输出文件中。在</p>
<p>同样,通过将所有这些封装到单个对象中,我们可以为每个摄影机创建一组线程,无论使用多少个摄影机,都可以轻松缩放。由于每个摄影机流都是在一个后台线程中生成的,所以我们必须使主线程保持活动状态。请确保将<code>src</code>字符串更改为您自己的相机。下面是一个同时录制三个视频流的示例。在</p>
<p><img src="https://i.stack.imgur.com/UcUHS.jpg" width="450"/></p>
<pre><code>from threading import Thread
import cv2
import time
class VideoWriterWidget(object):
def __init__(self, video_file_name, src=0):
# Create a VideoCapture object
self.frame_name = str(src)
self.video_file = video_file_name
self.video_file_name = video_file_name + '.avi'
self.capture = cv2.VideoCapture(src)
# Default resolutions of the frame are obtained (system dependent)
self.frame_width = int(self.capture.get(3))
self.frame_height = int(self.capture.get(4))
# Set up codec and output video settings
self.codec = cv2.VideoWriter_fourcc('M','J','P','G')
self.output_video = cv2.VideoWriter(self.video_file_name, self.codec, 30, (self.frame_width, self.frame_height))
# Start the thread to read frames from the video stream
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
# Start another thread to show/save frames
self.start_recording()
print('initialized {}'.format(self.video_file))
def update(self):
# Read the next frame from the stream in a different thread
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
def show_frame(self):
# Display frames in main program
if self.status:
cv2.imshow(self.frame_name, self.frame)
# Press Q on keyboard to stop recording
key = cv2.waitKey(1)
if key == ord('q'):
self.capture.release()
self.output_video.release()
cv2.destroyAllWindows()
exit(1)
def save_frame(self):
# Save obtained frame into video output file
self.output_video.write(self.frame)
def start_recording(self):
# Create another thread to show/save frames
def start_recording_thread():
while True:
try:
self.show_frame()
self.save_frame()
except AttributeError:
pass
self.recording_thread = Thread(target=start_recording_thread, args=())
self.recording_thread.daemon = True
self.recording_thread.start()
if __name__ == '__main__':
src1 = 'Your link1'
video_writer_widget1 = VideoWriterWidget('Camera 1', src1)
src2 = 'Your link2'
video_writer_widget2 = VideoWriterWidget('Camera 2', src2)
src3 = 'Your link3'
video_writer_widget3 = VideoWriterWidget('Camera 3', src3)
# Since each video player is in its own thread, we need to keep the main thread alive.
# Keep spinning using time.sleep() so the background threads keep running
# Threads are set to daemon=True so they will automatically die
# when the main thread dies
while True:
time.sleep(5)
</code></pre>