如何在多线程类之外运行 OpenCV VideoCapture 的读取功能? [英] How to run OpenCV VideoCapture's read function outside multithreading class?

查看:214
本文介绍了如何在多线程类之外运行 OpenCV VideoCapture 的读取功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Nathancy 的 SO 代码阅读两个利用多线程并行来自磁盘的静态视频.以下修改后的代码对我来说非常好:

I am using Nathancy's SO code to read two static videos from disk in parallel, leveraging multithreading. The below modified code works perfectly fine for me:

from threading import Thread
import cv2, time


class VideoStreamWidget(object):
    def __init__(self, src=0):
        self.capture = cv2.VideoCapture(src)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.image) = self.capture.read()
                self.frame = cv2.resize(self.image, (640, 480))
            time.sleep(.01)

    def show_frame(self, win_name='frame_1'):
        # Display frames in main program
        cv2.imshow(win_name, self.frame)
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            cv2.destroyAllWindows()
            exit(1)

if __name__ == '__main__':
    video_stream_widget1 = VideoStreamWidget(src=r'C:\Users\ab\Documents\Video\ch6.asf')
    video_stream_widget2 = VideoStreamWidget(
        src=r'C:\Users\ab\Documents\Video\ch4.asf')
    while True:
        try:
            video_stream_widget1.show_frame('frame_1')
            video_stream_widget2.show_frame('frame_2')
        except AttributeError:
            pass

现在我正在尝试调整上面的代码,因为我想在类外创建一个 while 循环,并从 capture.read() 函数中获取状态和图像,以供循环中的其他代码逐帧使用.但是,它甚至不适用于具有此错误(Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:155)的单个视频流.代码如下:

Now I'm trying to tweak through the above code as I want to create a while loop outside the class and get status and image from capture.read() function to be used by other codes in a loop, frame by frame. But, it is not working for even single video stream with this (Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:155) error. Code is as follows:

from threading import Thread
import cv2, time


class VideoStreamWidget(object):
    def __init__(self, src=0):
        self.capture = cv2.VideoCapture(src)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.image) = self.capture.read()
                self.frame = cv2.resize(self.image, (640, 480))
            # time.sleep(.01)

    # def show_frame(self, win_name='frame_1'):
    #     # Display frames in main program
    #     cv2.imshow(win_name, self.frame)
    #     key = cv2.waitKey(1)
    #     if key == ord('q'):
    #         self.capture.release()
    #         cv2.destroyAllWindows()
    #         exit(1)

if __name__ == '__main__':
    video_stream_widget1 = VideoStreamWidget(src=r'C:\Users\ab\Documents\Video\ch6.asf')
    # video_stream_widget2 = VideoStreamWidget(
    #     src=r'C:\Users\ab\Documents\Video\ch4.asf')
    # while True:
    #     try:
    #         video_stream_widget1.show_frame('frame_1')
    #         video_stream_widget2.show_frame('frame_2')
    #     except AttributeError:
    #         pass
    while True:
        vflag, image_np = video_stream_widget1.status, video_stream_widget1.frame
        print(image_np)

这是一个setter getter问题吗?你能帮忙指出我哪里出错了吗?

Is it a setter getter problem? Can you help point out where am I going wrong?

推荐答案

尝试了几种方法后,在init中添加self.status、self.image和self.frame解决了问题.由于是多线程的,我们需要在构造函数中显式地初始化这些变量.

After trying out couple of ways, adding the self.status, self.image and self.frame in the init solved the problem. Since it is multi-threaded, we need to explicitly init these variables in the constructor.

这篇关于如何在多线程类之外运行 OpenCV VideoCapture 的读取功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆