相关疑难解决方法(0)

Python3 在网络摄像头 fps 处处理和显示网络摄像头流

如何读取相机并以相机帧速率显示图像?

我想从我的网络摄像头连续读取图像(进行一些快速预处理),然后在窗口中显示图像。这应该以我的网络摄像头提供的帧速率(29 fps)运行。OpenCV GUI 和 Tkinter GUI 似乎太慢了,无法以这样的帧速率显示图像。这些显然是我实验中的瓶颈。即使没有预处理,图像的显示速度也不够快。我在 MacBook Pro 2018 上。

这是我尝试过的。网络摄像头始终使用 OpenCV 读取:

  • 一切都发生在主线程中,图像以 OpenCV 显示:12 fps
  • 读取相机并在单独的线程中进行预处理,在主线程中使用 OpenCV 显示图像:20 fps
  • 像上面一样多线程,但不显示图像:29 fps
  • 像上面一样多线程,但使用 Tkinter 显示图像:不知道确切的 fps,但感觉 <10 fps。

这是代码:

单循环,OpenCV GUI:

import cv2
import time


def main():
    cap = cv2.VideoCapture(0)
    window_name = "FPS Single Loop"
    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)

    start_time = time.time()
    frames = 0

    seconds_to_measure = 10
    while start_time + seconds_to_measure > time.time():
        success, img = cap.read()
        img = img[:, ::-1]  # mirror
        time.sleep(0.01)  # simulate some processing …
Run Code Online (Sandbox Code Playgroud)

python multithreading opencv tkinter python-3.x

8
推荐指数
1
解决办法
2081
查看次数

OpenCV和Python多线程-在VideoCapture对象中寻找

我一直在研究一个使用OpenCV从视频中读取帧并创建“活动”(即从一帧变为另一帧的事物)组合的python应用程序。为此,我只想每秒检查一帧左右。

很长时间以来,我一直在使用以下代码(简化后的代码,简化了一些错误检查,分类等操作)来获取视频对象和第一帧:

video_capture = cv2.VideoCapture(video_fullpath)
this_frame = get_frame(0)

def get_frame(time):
    video_capture.set(cv2.CAP_PROP_POS_MSEC, time)
    capture_success, this_frame = video_capture.read()
    return this_frame
Run Code Online (Sandbox Code Playgroud)

使用上面的后两行代码获取后续帧的过程确实很慢。在2015年的MacBook Pro上,每帧的获取时间为0.3-0.4s(视频中的间隔为1秒,这是一个约100MB的.mp4视频文件)。相比之下,我将其余各帧与其前一帧进行比较的其余操作非常快-通常少于0.01s。

因此,我一直在研究多线程,但我一直在努力。

我可以在“超前”的基础上进行多线程工作,即在处理一帧的同时可以获取下一帧。处理完前一帧后,我将等待“超前”操作完成后再继续。我使用以下代码进行操作:

while True:
    this_frame, next_frame_thread = get_frame_async(prev_frame.time + time_increment)
    << do processing of this_frame ... >>
    next_frame_thread.join()

def get_frame_async(time):
    if time not in frames:
        frames[time] = get_frame(time)
    next_frame_thread = Thread(target=get_frame, args=(time,))
    next_frame_thread.start()
    return frames[time], next_frame_thread
Run Code Online (Sandbox Code Playgroud)

上面的方法似乎是可行的,但是因为与其他所有操作相比,查找操作是如此缓慢,因此实际上并没有节省太多时间-实际上很难看到任何好处。

然后,我想知道是否可以并行获取多个帧。但是,每当我尝试尝试时,都会遇到一系列错误,这些错误大多与async_lock有关(例如Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:155)。我想知道这是否仅仅是OpenCV VideoCapture对象不能一次搜索多个位置……这似乎是合理的。但是,如果是这样,是否有任何方法可以大大加快此操作?

我一直在使用一些不同的资源,包括这个https://nrsyed.com/2018/07/05/multithreading-with-opencv-python-to-improve-video-processing-performance/,它显示了巨大的速度-起伏,但我正在为为什么我在async_lock周围遇到这些错误而感到困惑。仅仅是搜索操作吗?在寻找视频时,找不到任何多线程示例,而只是人们顺序阅读所有帧的示例。

任何在哪里/哪些部件最有可能从多线程中受益(或另一种方法)的任何技巧或指南都将受到欢迎。这是我第一次尝试多线程,因此完全接受我可能错过了一些显而易见的事情!基于此页面(https://www.toptal.com/python/beginners-guide-to-concurrency-and-parallelism-in-python),我对各种可用的选项感到有些不知所措。

谢谢!

python multithreading opencv

5
推荐指数
1
解决办法
3407
查看次数

标签 统计

multithreading ×2

opencv ×2

python ×2

python-3.x ×1

tkinter ×1