一种在 Python 中实现更快 OpenCV 视频流的多线程方法

这篇具有很好参考价值的文章主要介绍了一种在 Python 中实现更快 OpenCV 视频流的多线程方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

python多进程多线程视频处理,python,opencv,开发语言,人工智能,计算机视觉

概述

在本文中,我们将看到两个没有多线程的 Python 代码示例,用于从摄像头读取视频帧。我们将看到使用/不使用多线程获得的 FPS 的差异。

什么是多线程?

线程是进程中的一个执行单元。多线程是指通过在线程之间快速切换对 CPU 的控制(称为上下文切换)来并发执行多个线程。在我们的示例中,我们将看到多线程通过提高 FPS(每秒帧数)实现更快的实时视频处理。

Python中的线程基础

以下代码片段显示了如何使用python 中的threading模块创建线程:

# importing the threading module 
import threading 

# importing the time module 
import time

# Function to print "Hello", however, the function sleeps
# for 2 seconds at the 11th iteration
def print_hello(): 
  for i in range(20):
    if i == 10:
      time.sleep(2)
    print("Hello")

# Function to print numbers till a given number
def print_numbers(num): 
  for i in range(num+1):
    print(i)

# Creating the threads. Target is set to the name of the
# function that neeeds to be executed inside the thread and
# args are the arguments to be supplied to the function that

# needs to be executed.
print("Greetings from the main thread.")
thread1 = threading.Thread(target = print_hello, args = ())
thread2 = threading.Thread(target = print_numbers, args = (10,))  

# Starting the two threads
thread1.start() 
thread2.start() 
print("It's the main thread again!")

让我们通过跟踪代码的执行来尝试理解输出:

  1. 主线程执行。打印“Greetings from the main thread”,创建thread1thread2并启动线程。

  2. 发生上下文切换,开始执行thread1

  3. 在前十次迭代之后,thread1进入睡眠状态,thread2开始执行,在下一次上下文切换之前完成。

  4. 现在,主线程获得了 CPU 的控制权并打印出“It’s the main thread again!”

  5. 另一个上下文切换发生,thread2恢复执行并完成。

  6. 由于主线程没有更多指令要执行,因此程序终止。

使用thread.join()

如果需要阻塞主线程,直到thread1和thread2完成执行,该怎么办?

thread.join()会派上用场,因为它会阻塞调用线程,直到调用其 join() 方法的线程终止:

# importing the threading module 
import threading 

# importing the time module 
import time
# Function to print "Hello", however, the function sleeps

# for 2 seconds at the 11th iteration
def print_hello(): 
  for i in range(20):
    if i == 10:
      time.sleep(2)
    print("Hello")

# Function to print numbers till a given number
def print_numbers(num): 
  for i in range(num+1):
    print(i)

# Creating the threads. Target is set to the name of the
# function that neeeds to be executed inside the thread and
# args are the arguments to be supplied to the function that
# needs to be executed.
print("Greetings from the main thread.")
thread1 = threading.Thread(target = print_hello, args = ())
thread2 = threading.Thread(target = print_numbers, args = (10,))  

# Starting the two threads
thread1.start() 
thread2.start() 
thread1.join()
thread2.join()
print("It's the main thread again!")
print("Threads 1 and 2 have finished executing.")

原因多线程有助于更快的处理

视频处理代码分为两部分:从摄像头读取下一个可用帧并对帧进行视频处理,例如运行深度学习模型进行人脸识别等。

读取下一帧并在没有多线程的程序中按顺序进行处理。程序等待下一帧可用,然后再对其进行必要的处理。读取帧所需的时间主要与请求、等待和将下一个视频帧从相机传输到内存所需的时间有关。对视频帧进行计算所花费的时间,无论是在 CPU 还是 GPU 上,占据了视频处理所花费的大部分时间。

在具有多线程的程序中,读取下一帧并处理它不需要是顺序的。当一个线程执行读取下一帧的任务时,主线程可以使用 CPU 或 GPU 来处理最后读取的帧。这样,通过重叠两个任务,可以减少读取和处理帧的总时间。

OpenCV 代码——没有多线程

# importing required libraries 
import cv2 
import time

# opening video capture stream
vcap = cv2.VideoCapture(0)
if vcap.isOpened() is False :
    print("[Exiting]: Error accessing webcam stream.")
    exit(0)
fps_input_stream = int(vcap.get(5))
print("FPS of webcam hardware/input stream: {}".format(fps_input_stream))
grabbed, frame = vcap.read() # reading single frame for initialization/ hardware warm-up

# processing frames in input stream
num_frames_processed = 0 
start = time.time()
while True :
    grabbed, frame = vcap.read()
    if grabbed is False :
        print('[Exiting] No more frames to read')
        break

# adding a delay for simulating time taken for processing a frame 
    delay = 0.03 # delay value in seconds. so, delay=1 is equivalent to 1 second 
    time.sleep(delay) 
    num_frames_processed += 1
cv2.imshow('frame' , frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
end = time.time()

# printing time elapsed and fps 
elapsed = end-start
fps = num_frames_processed/elapsed 
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))

# releasing input stream , closing all windows 
vcap.release()
cv2.destroyAllWindows()

OpenCV 代码——多线程

# importing required libraries 
import cv2 
import time 
from threading import Thread # library for implementing multi-threaded processing

# defining a helper class for implementing multi-threaded processing 
class WebcamStream :
    def __init__(self, stream_id=0):
        self.stream_id = stream_id   # default is 0 for primary camera 
        
        # opening video capture stream 
        self.vcap      = cv2.VideoCapture(self.stream_id)
        if self.vcap.isOpened() is False :
            print("[Exiting]: Error accessing webcam stream.")
            exit(0)
        fps_input_stream = int(self.vcap.get(5))
        print("FPS of webcam hardware/input stream: {}".format(fps_input_stream))
            
        # reading a single frame from vcap stream for initializing 
        self.grabbed , self.frame = self.vcap.read()
        if self.grabbed is False :
            print('[Exiting] No more frames to read')
            exit(0)

# self.stopped is set to False when frames are being read from self.vcap stream 
        self.stopped = True

# reference to the thread for reading next available frame from input stream 
        self.t = Thread(target=self.update, args=())
        self.t.daemon = True # daemon threads keep running in the background while the program is executing 
        
    # method for starting the thread for grabbing next available frame in input stream 
    def start(self):
        self.stopped = False
        self.t.start()

# method for reading next frame 
    def update(self):
        while True :
            if self.stopped is True :
                break
            self.grabbed , self.frame = self.vcap.read()
            if self.grabbed is False :
                print('[Exiting] No more frames to read')
                self.stopped = True
                break 
        self.vcap.release()

# method for returning latest read frame 
    def read(self):
        return self.frame

# method called to stop reading frames 
    def stop(self):
        self.stopped = True

# initializing and starting multi-threaded webcam capture input stream 
webcam_stream = WebcamStream(stream_id=0) #  stream_id = 0 is for primary camera 
webcam_stream.start()

# processing frames in input stream
num_frames_processed = 0 
start = time.time()
while True :
    if webcam_stream.stopped is True :
        break
    else :
        frame = webcam_stream.read()

# adding a delay for simulating time taken for processing a frame 
    delay = 0.03 # delay value in seconds. so, delay=1 is equivalent to 1 second 
    time.sleep(delay) 
    num_frames_processed += 1
cv2.imshow('frame' , frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
end = time.time()
webcam_stream.stop() # stop the webcam stream

# printing time elapsed and fps 
elapsed = end-start
fps = num_frames_processed/elapsed 
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))

# closing all windows 
cv2.destroyAllWindows()

下载所有代码

https://github.com/SihabSahariar/Multi-threading-OpenCV-

资源

  1. https://stackoverflow.com/questions/55099413/python-opencv-streaming-from-camera-multithreading-timestamps

  2. https://stackoverflow.com/questions/55828451/video-streaming-from-ip-camera-in-python-using-opencv-cv2-videocapture

  3. https://stackoverflow.com/questions/58592291/how-to-capture-multiple-camera-streams-with-opencv

  4. https://stackoverflow.com/questions/58293187/opencv-real-time-streaming-video-capture-is-slow-how-to-drop-frames-or-get-sync

  5. https://stackoverflow.com/questions/55141315/storing-rtsp-stream-as-video-file-with-opencv-videowriter

  6. https://stackoverflow.com/questions/29317262/opencv-video-saving-in-python/71624807#71624807

  7. https://stackoverflow.com/questions/72120491/python-opencv-multiprocessing-cv2-videocapture-mp4

参考

  1. https://github.com/PyImageSearch/imutils/tree/master/imutils/video

  2. https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/

  3. https://forum.opencv.org/t/videocapture-opens-video-sources-by-multi-thread/8045

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓文章来源地址https://www.toymoban.com/news/detail-597447.html

到了这里,关于一种在 Python 中实现更快 OpenCV 视频流的多线程方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Opencv保存ESP32-CAM视频流

    Opencv保存ESP32-CAM视频流 esp32cam是一个很便宜的视频模组,可以用作监控等功能。此时就需要保存esp32的视频流,方便查看等操作,python代码如下 前置条件:视频流正常,已安装opencv

    2024年02月08日
    浏览(68)
  • opencv基本操作二(读取视频流与保存视频、读取摄像头并保存视频)

    opencv常用 读视频函数 cv2.VideoCapture 、 cv2.VideoCapture.get 等,可以参考这里 opencv常用 写视频函数 cv2.VideoWriter 等可以参考这里 ,其中视频格式可以参考这里 videoCapture.read() 是按帧读取视频, ret,frame 是获 .read() 方法的两个返回值。其中 ret 是布尔值,如果读取帧是正确的则返回

    2023年04月08日
    浏览(101)
  • 【精选】基于OpenCV的实时视频流车牌识别(源码&教程)

    近年来,智能交通系统(ITS)在我国应用日益广泛。作为ITS重要组成部分的自动车牌识别系统在交通流量检测、交通诱导控制、违章车辆监控等方面有着广泛的应用,是确保道路安全畅通的重要手段,也为统计有关资料,为管理者决策提供有效数字依据的重要途径。由于一般的识别系

    2024年01月23日
    浏览(64)
  • 基于OpenCv+Django的网络实时视频流传输(前后端分离)

    秋风阁——北溪入江流:https://focus-wind.com/ 秋风阁——基于OpenCv+Django的网络实时视频流传输(前后端分离) 使用OpenCv捕获摄像机画面后,我们有时候需要将画面显示在界面上。本博客基于Django的前后端分离模式,将视频流从后端读取,传送给前端显示。 在使用Django进行视频

    2024年02月08日
    浏览(54)
  • 树莓派学习:学习opencv+用opencv获取树莓派mjpg摄像头视频流

    目录 前提步骤 打开树莓派摄像头 查看是否有图像,登录游览器打开树莓派IP地址的8080端口 获取mjpg的视频流url 代码 先设定好mjpg的视频流的url 利用opencv库中的v2.VideoCapture类读取mjpg视频流   cv2.VideoCapture() 检查摄像头是否成功打开,如果没有,则打印错误消息并退出程序 

    2024年02月03日
    浏览(60)
  • 使用Flask+OpenCV实现浏览器/微信小程序的视频流传输

    前言 一、 Flask+浏览器实现 二、 Flask+微信小程序实现 三、Flask+uni-app小程序实现 后记 近期在做的东西涉及到实时视频的处理,碰到一些问题,因此将之记录下来,便于日后翻看,同时也希望能给遇到同样问题的小伙伴提供帮助。 实现代码如下: 分为 app.py 和index.html。 1. F

    2024年02月06日
    浏览(76)
  • VS+QT+Opencv使用YOLOv4对视频流进行目标检测

    对单张图像的检测,请参考:https://blog.csdn.net/qq_45445740/article/details/109659938

    2024年02月12日
    浏览(56)
  • 视频流识别---python

    在Python中实现预处理,需要用到一些常见的图像处理库,如OpenCV、PIL等。 首先,需要加载视频并读取视频帧。可以使用OpenCV库中的cv2.VideoCapture()函数读取视频,然后使用cv2.read()函数读取视频的每一帧。读取到的每一帧是一个numpy数组,可以对其进行各种图像处理操作。 以下

    2024年01月17日
    浏览(52)
  • WSL2通过OpenCV调用并展示本机摄像头的RTSP视频流

    本篇博客的由来如上图哈哈,WSL2 相关安装教程可以参考我之前的博客:Win11安装WSL2和Nvidia驱动 更多文章欢迎来我的博客小站看呀,会有更多的技术细节~ ubuntu上请执行 或者编译安装 如果报错 Could NOT find OpenSSL ,安装如下依赖即可解决 下载解压 EasyDarwin Easydarwin是国内团队开

    2024年02月09日
    浏览(78)
  • Python之FastAPI返回音视频流

    今天想要记录一下困扰我几天的一个问题,关于FastAPI返回音视频流。首先FastAPI挂载静态资源其实超级简单,但是对于音视频流,如果你想要有播放进度可以拖动,需要单独处理。 有以下几点想跟大家分享: 如何返回音视频流,并且前端video元素可以拖动播放 关于video标签需

    2024年02月02日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包