opencv python多线程视频捕获 [英] opencv python Multi Threading Video Capture

查看:740
本文介绍了opencv python多线程视频捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取2个视频文件,并同时在单独的Windows中显示它们. 这是我的代码:

I am trying to read to 2 Video Files and show them in separate Windows Simultaneously. This is my code:

import threading
import cv2
threadLock=threading.Lock()
class myThread (threading.Thread):
    maxRetries=20
    def __init__(self, threadID, name,video_url):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.video_url=video_url

    def attemptRead(self,cvVideo):
        threadLock.acquire()
        (isRead,cvImage)=cvVideo.read()
        threadLock.release()
        if isRead==False:
            count=1
            while isRead==False and count<myThread.maxRetries:
                threadLock.acquire()
                (isRead,cvImage)=cvVideo.read()
                threadLock.release()
                print self.name+' try no: ',count
                count+=1
        return (isRead,cvImage)

    def run(self):
        print "Starting " + self.name
        windowName = self.name
        cv2.namedWindow(windowName)
        cvVideo = cv2.VideoCapture(self.video_url)


        while True:
            (isRead,cvImage)=self.attemptRead(cvVideo)
            if isRead==False:
                break
            cv2.imshow(windowName,cvImage)
            key=cv2.waitKey(50)
            if key==27:
                break

        cv2.destroyWindow(windowName)
        print self.name + "Exiting"

def main():
    thread1 = myThread(1, "Thread1",'C:/Traffic Pics/Videos/Panjim Capture.mp4')
    thread2 = myThread(2, "Thread2",'C:/Traffic Pics/Videos/Miramar Capture.mp4')

    thread1.start()
    thread2.start()

print "Exiting Main Thread"

if __name__ == '__main__':
    main()

正在发生的事情是, 线程2 窗口正在显示.尝试读取超出 max_retries限制(在我的情况下为10)的视频后,线程1退出. 问题是,尽管我创建了单独的 cvVideo 对象,但似乎无法同时使用它们. 可能是什么问题?

What's happening is that, only the Thread 2 Window is showing. Thread 1 exits after attempting to read the video beyond the max_retries limit(10 in my case). The problem is that although I create separate cvVideo objects, I can't seem to use them simultaneously. What could be the problem?

推荐答案

* edit:我将在下面保留代码,但是我想您有编解码器问题吗?我安装了xvid编解码器(这是示例Megamind.avi的编码方式),并且该程序可以在运行megamind视频的一个或两个线程中正常运行.可以让megamind视频在单线程版本中运行吗?

*edit: I'll leave the code below, but I guess you have a codec problem? I installed the xvid codec (which is what the sample Megamind.avi is encoded with) and the program works fine with either or both threads running the megamind video. Can you get the megamind video to run in the single threaded version?

这是关于opencv视频编解码器的SO帖子万一有帮助.这是我使用的 xvid下载(k-lite对我不起作用).

Here is an SO post on opencv video codecs in case it helps. Here is the xvid download that I used (k-lite didn't work for me).

您编写的代码基本上对我有用.对于您和其他想要尝试的人,我做了以下事情:

The code you wrote basically works for me. For you and anyone else that wants to try, I did the following:

  • 应用了PEP 8建议
  • 删除了不必要的读取尝试代码(也删除了工作视频最后一帧之后的误导性线程重新读取警告)
  • 使用了一个视频文件,也许每个使用opencv的人都拥有
  • 删除了线程锁定,至少在我的系统上,该线程锁定对opencv似乎无关紧要
  • 移动了一些其他小东西

VideoCapture.read可能还会出现其他错误,这些错误使值得使用read_attempt方法,但我只能找到

There may be other errors that come up with VideoCapture.read that would make a read_attempt method worthwhile, but I could only find the two errors the docs mention. For those it just returns false which the code already tests for.

import os
import threading

import cv2

my_opencv_path = "C:/opencv2.4.3"
video_path_1 = os.path.join(my_opencv_path, "samples", "cpp", "tutorial_code",
                            "HighGUI", "video-input-psnr-ssim", "video",
                            "Megamind.avi")
video_path_2 = os.path.join(my_opencv_path, "samples", "c", "tree.avi")
assert os.path.isfile(video_path_1)
assert os.path.isfile(video_path_2)


class MyThread (threading.Thread):
    maxRetries = 20

    def __init__(self, thread_id, name, video_url, thread_lock):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.name = name
        self.video_url = video_url
        self.thread_lock = thread_lock

    def run(self):
        print "Starting " + self.name
        window_name = self.name
        cv2.namedWindow(window_name)
        video = cv2.VideoCapture(self.video_url)
        while True:
            # self.thread_lock.acquire()  # These didn't seem necessary
            got_a_frame, image = video.read()
            # self.thread_lock.release()
            if not got_a_frame:  # error on video source or last frame finished
                break
            cv2.imshow(window_name, image)
            key = cv2.waitKey(50)
            if key == 27:
                break
        cv2.destroyWindow(window_name)
        print self.name + " Exiting"


def main():
    thread_lock = threading.Lock()
    thread1 = MyThread(1, "Thread 1", video_path_1, thread_lock)
    thread2 = MyThread(2, "Thread 2", video_path_2, thread_lock)
    thread1.start()
    thread2.start()
    print "Exiting Main Thread"

if __name__ == '__main__':
    main()

这篇关于opencv python多线程视频捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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