OpenCV has an example for multithreaded video processing in their github repo.

https://github.com/opencv/opencv/blob/master/samples/python/video_threaded.py

Import ThreadPool from multiprocessing.pool and kick off a new thread for every cpu core. OpenCV has a function called getNumberOfCPUs()

Example:

from __future__ import print_function

import numpy as np
import cv2 as cv

from multiprocessing.pool import ThreadPool
from collections import deque

from common import clock, draw_str, StatValue
import video


class DummyTask:
    def __init__(self, data):
    self.data = data
def ready(self):
    return True
def get(self):
    return self.data

if __name__ == '__main__':
    import sys

    print(__doc__)

    try:
        fn = sys.argv[1]
    except:
        fn = 0
    cap = video.create_capture(fn)


    def process_frame(frame, t0):
    # some intensive computation...
        frame = cv.medianBlur(frame, 19)
        frame = cv.medianBlur(frame, 19)
        return frame, t0

    threadn = cv.getNumberOfCPUs()
    pool = ThreadPool(processes = threadn)
    pending = deque()

    threaded_mode = True

    latency = StatValue()
    frame_interval = StatValue()
    last_frame_time = clock()
    while True:
        while len(pending) > 0 and pending[0].ready():
            res, t0 = pending.popleft().get()
            latency.update(clock() - t0)
            draw_str(res, (20, 20), "threaded      :  " +             str(threaded_mode))
            draw_str(res, (20, 40), "latency        :  %.1f ms" %     (latency.value*1000))
            draw_str(res, (20, 60), "frame interval :  %.1f ms" % (frame_interval.value*1000))
            cv.imshow('threaded video', res)
        if len(pending) < threadn:
            ret, frame = cap.read()
            t = clock()
            frame_interval.update(t - last_frame_time)
            last_frame_time = t
            if threaded_mode:
                task = pool.apply_async(process_frame, (frame.copy(), t))
            else:
                task = DummyTask(process_frame(frame, t))
            pending.append(task)
        ch = cv.waitKey(1)
        if ch == ord(' '):
            threaded_mode = not threaded_mode
        if ch == 27:
            break
    cv.destroyAllWindows()

You should be able to use that example code and place your image processing in the process_frame function.

Add a counter to in your loop and call cv2.imshow when count == X

Answer from Michael James on Stack Overflow
Top answer
1 of 1
8

OpenCV has an example for multithreaded video processing in their github repo.

https://github.com/opencv/opencv/blob/master/samples/python/video_threaded.py

Import ThreadPool from multiprocessing.pool and kick off a new thread for every cpu core. OpenCV has a function called getNumberOfCPUs()

Example:

from __future__ import print_function

import numpy as np
import cv2 as cv

from multiprocessing.pool import ThreadPool
from collections import deque

from common import clock, draw_str, StatValue
import video


class DummyTask:
    def __init__(self, data):
    self.data = data
def ready(self):
    return True
def get(self):
    return self.data

if __name__ == '__main__':
    import sys

    print(__doc__)

    try:
        fn = sys.argv[1]
    except:
        fn = 0
    cap = video.create_capture(fn)


    def process_frame(frame, t0):
    # some intensive computation...
        frame = cv.medianBlur(frame, 19)
        frame = cv.medianBlur(frame, 19)
        return frame, t0

    threadn = cv.getNumberOfCPUs()
    pool = ThreadPool(processes = threadn)
    pending = deque()

    threaded_mode = True

    latency = StatValue()
    frame_interval = StatValue()
    last_frame_time = clock()
    while True:
        while len(pending) > 0 and pending[0].ready():
            res, t0 = pending.popleft().get()
            latency.update(clock() - t0)
            draw_str(res, (20, 20), "threaded      :  " +             str(threaded_mode))
            draw_str(res, (20, 40), "latency        :  %.1f ms" %     (latency.value*1000))
            draw_str(res, (20, 60), "frame interval :  %.1f ms" % (frame_interval.value*1000))
            cv.imshow('threaded video', res)
        if len(pending) < threadn:
            ret, frame = cap.read()
            t = clock()
            frame_interval.update(t - last_frame_time)
            last_frame_time = t
            if threaded_mode:
                task = pool.apply_async(process_frame, (frame.copy(), t))
            else:
                task = DummyTask(process_frame(frame, t))
            pending.append(task)
        ch = cv.waitKey(1)
        if ch == ord(' '):
            threaded_mode = not threaded_mode
        if ch == 27:
            break
    cv.destroyAllWindows()

You should be able to use that example code and place your image processing in the process_frame function.

Add a counter to in your loop and call cv2.imshow when count == X

🌐
Xailient
xailient.com › blog › parallel-processing-using-python-for-faster-video-processing
Parallel Processing Using Python for Faster Video Processing | Xailient
In this post, we will look at how to use Python for parallel processing of videos. We will read video from the disk, perform face detection, and write the video with output of face detection (bounding boxes) back to the disk. Let’s get started. ... OpenCV: is a computer vision library that ...
Discussions

python - Run processes in parallel while capturing video with opencv - Stack Overflow
I'm using opencv to capture a video from my webcam. Every 5 seconds, I'm processing a single frame / an image which can take some seconds. So far everything works. But whenever a frame is processed... More on stackoverflow.com
🌐 stackoverflow.com
June 20, 2019
How many parallel VideoCapture's can one camera handle? - Python - OpenCV
I want to read from one camera in many parallel processes. Here is what I’ve tried. from multiprocessing import Process import cv2 import time import random def get_capture(): time.sleep(random.randint(0, 3)) cap = cv2.VideoCapture(0) w, h = cap.get(cv2.CAP_PROP_FRAME_WIDTH), cap.get(cv2... More on forum.opencv.org
🌐 forum.opencv.org
0
February 9, 2024
python - Using multiprocessing with opencv to run a function in parallel with inputs of frames from different cameras - Stack Overflow
I am trying to run a function which takes frames from various camera feeds and saves them to disk. I have three cameras connected to my laptop USB ports and trying to start all the cameras at onc... More on stackoverflow.com
🌐 stackoverflow.com
September 8, 2018
multithreading - Multi-threading in image processing - video python opencv - Stack Overflow
Im working on object detection from a live stream video using opencv python. The program I have is running on a single thread because of that the resulting video shown on the screen doesnt even loo... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
gist.github.com › yinguobing › 7d1318e31f6e3455f30527a39361512a
OpenCV minimal example showing multithreaded video processing. · GitHub
OpenCV minimal example showing multithreaded video processing. ... This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters ... Isn't this just a near straight up copy from the official documentation? https://github.com/opencv/opencv/blob/master/samples/python/video_threaded.py
🌐
Nrsyed
nrsyed.com › 2018 › 07 › 05 › multithreading-with-opencv-python-to-improve-video-processing-performance
Multithreading with OpenCV-Python to improve video processing performance • Najam R. Syed
July 6, 2018 - To do this, we’ll first define a class called VideoGet in a file named VideoGet.py, which can be found on Github. We import the threading module, which will allow us to spawn new threads. In the class __init__() method, we initialize an OpenCV VideoCapture object and read the first frame.
🌐
Stack Overflow
stackoverflow.com › questions › 56690006 › run-processes-in-parallel-while-capturing-video-with-opencv
python - Run processes in parallel while capturing video with opencv - Stack Overflow
June 20, 2019 - Threading in python is a bit strangely named. If you spawn threads via the ThreadPoolExecutor, those threads are executed in the same process. You are still handicapped by the Global Interpreter Lock. Using threads in python only makes sense when you are IO-bottlenecked and the CPU is essentially sitting idle waiting for IO.
🌐
GitHub
github.com › opencv › opencv › blob › master › samples › python › video_threaded.py
opencv/samples/python/video_threaded.py at master · opencv/opencv
March 20, 2019 - Multithreaded video processing sample. Usage: video_threaded.py {<video device number>|<video file name>} · Shows how python threading capabilities can be used · to organize parallel captured frame processing pipeline · for smoother playback. · Keyboard shortcuts: ·
Author: opencv
🌐
OpenCV
docs.opencv.org › 4.x › d7 › dff › tutorial_how_to_use_OpenCV_parallel_for_.html
OpenCV: How to use the OpenCV parallel_for_ to parallelize your code
When looking at the sequential implementation, we can notice that each pixel is computed independently. To optimize the computation, we can perform multiple pixel calculations in parallel, by exploiting the multi-core architecture of modern processor.
🌐
PyImageSearch
pyimagesearch.com › home › blog › multiprocessing with opencv and python
Multiprocessing with OpenCV and Python - PyImageSearch
December 29, 2022 - There are overhead function calls, both at the Python level and operating system level, that prevent us from seeing a true 20x speedup. The short answer is no, not all algorithms can be made parallel and distributed to all cores of a processor — some algorithms are simply single threaded in nature. Furthermore, you cannot use the multiprocessing library to speedup compiled OpenCV routines like cv2.GaussianBlur, cv2.Canny, or any of the deep neural network routines in the cv2.dnn package.
Find elsewhere
🌐
GitHub
github.com › rsnk96 › fast-cv
GitHub - rsnk96/fast-cv: Parallelized Video Processing implementations using OpenCV in Python, ffmpeg · GitHub
October 8, 2020 - Parallelized Video Processing implementations using OpenCV in Python, ffmpeg - rsnk96/fast-cv
Starred by 18 users
Forked by 8 users
Languages: Jupyter Notebook 94.7% | Python 4.4%
🌐
OpenCV
forum.opencv.org › python
How many parallel VideoCapture's can one camera handle? - Python - OpenCV
February 9, 2024 - I want to read from one camera in many parallel processes. Here is what I’ve tried. from multiprocessing import Process import cv2 import time import random def get_capture(): time.sleep(random.randint(0, 3)) cap = cv2.VideoCapture(0) w, h = cap.get(cv2.CAP_PROP_FRAME_WIDTH), cap.get(cv2...
🌐
GitHub
github.com › vmlaker › sherlock
GitHub - vmlaker/sherlock: High-performance realtime video processing. In Python!! · GitHub
A collection of small codes for processing live video (like from a webcam) with OpenCV. Image data in memory (NumPy arrays) are shared by multiple processes using numpy-sharedmem Python module. Parallel processing workflow is implemented with MPipe.
Author: vmlaker
🌐
Stack Overflow
stackoverflow.com › questions › 52232871 › using-multiprocessing-with-opencv-to-run-a-function-in-parallel-with-inputs-of-f
python - Using multiprocessing with opencv to run a function in parallel with inputs of frames from different cameras - Stack Overflow
September 8, 2018 - from __future__ import absolute_import from __future__ import division from __future__ import print_function from multiprocessing import Process import cv2 #from scipy.stats import math import datetime count = 0 def saving_frame(frame): count = 0 date_string = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M") count = count +1 cv2.imwrite('Frame_'+str(count)+date_string+'.png',frame) return def runInParallel(*fns): proc = [] for fn in fns: p = Process(target=fn) p.start() proc.append(p) for p in proc: p.join() video_capture_1 = cv2.VideoCapture(0) video_capture_2 = cv2.VideoCapture(1) video_ca
🌐
Jevois
jevois.org › moddoc › PythonParallel › modinfo.html
PythonParallel
This module by default simply converts the input image to a grayscale OpenCV image, and then applies the Canny edge detection algorithm, 4 times running in parallel with 4 different edge coarseness settings. The resulting image is simply the 4 horizontally stacked results from the 4 parallel runs.
🌐
Medium
gvasu.medium.com › faster-real-time-video-processing-using-multi-threading-in-python-8902589e1055
Faster Real-Time Video Processing using Multi-Threading in Python | by Vasu Gupta | Medium
September 28, 2021 - # printing time elapsed and fps elapsed = end-start fps = num_frames_processed/elapsed print("FPS: {} , Elapsed Time: {} ".format(fps, elapsed))# releasing input stream , closing all windows vcap.release() cv2.destroyAllWindows() Below is a walkthrough of the code with multi-threading. Complete code can also be accessed here LINK ... # importing required libraries import cv2 # OpenCV library import time # time library from threading import Thread # library for multi-threading
🌐
Jancy Standard Library
vovkos.github.io › doxyrest-showcase › opencv › sphinx_rtd_theme › page_tutorial_how_to_use_OpenCV_parallel_for_.html
How to use the OpenCV parallel_for_ to parallelize your code — OpenCV Documentation
When looking at the sequential ... by exploiting the multi-core architecture of modern processor. To achieve this easily, we will use the OpenCV cv::parallel_for_ framework....
🌐
Medium
medium.com › data-science › faster-video-processing-in-python-using-parallel-computing-25da1ad4a01
Faster Video Processing in Python using Parallel Computing | by Sabina Pokhrel | TDS Archive | Medium
April 9, 2020 - If you are processing images in batches, you can utilize the power of parallel processing and speed-up the task. In this post, we will look at how to use python for prallel processing of videos. We will read video from the disk, perform face detection, and write the video with output of face detection (bounding boxes) back to the disk. Lets get started. ... OpenCV: is a computer vision library that is commonly used.
🌐
Medium
sihabsahariar.medium.com › a-multi-threading-approach-for-faster-opencv-video-streaming-in-python-7324f11dbd2f
A Multi-Threading Approach for Faster OpenCV Video Streaming in Python | by Sihab Sahariar | Medium
September 20, 2022 - # 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_strea
🌐
Data
scieencerepository.data.blog › 2020 › 04 › 09 › faster-video-processing-in-python-using-parallel-computing
Faster Video Processing in Python using Parallel Computing – Data Science Repository
April 10, 2020 - If you are processing images in batches, you can utilize the power of parallel processing and speed-up the task. In this post, we will look at how to use python for prallel processing of videos. We will read video from the disk, perform face detection, and write the video with output of face detection (bounding boxes) back to the disk. Lets get started. ... OpenCV: is a computer vision library that is commonly used.
Top answer
1 of 2
5

Working on the assumption that the detection algorithm is CPU-intensive, you need to be using multiprocessing instead of multithreading since multiple threads will not run Python bytecode in parallel due to contention for the Global Interpreter Lock. You should also get rid of all the calls to sleep. It is also not clear when you run multiple threads or processes the way you are doing it what guarantees that the frames will be output in the correct order, that is, the processing of the second frame could complete before the processing of the first frame and get written to the detection_buffer first.

The following uses a processing pool of 6 processes (there is no need now for an implicit input queue).

from multiprocessing import Pool, Queue
import time
import cv2

# intialize global variables for the pool processes:
def init_pool(d_b):
    global detection_buffer
    detection_buffer = d_b


def detect_object(frame):
    time.sleep(1)
    detection_buffer.put(frame)


def show():
    while True:
        print("show")
        frame = detection_buffer.get()
        if frame is not None:
            cv2.imshow("Video", frame)
        else:
            break
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    return


# required for Windows:
if __name__ == "__main__":

    detection_buffer = Queue()
    # 6 workers: 1 for the show task and 5 to process frames:
    pool = Pool(6, initializer=init_pool, initargs=(detection_buffer,))
    # run the "show" task:
    show_future = pool.apply_async(show)

    cap = cv2.VideoCapture(0)

    futures = []
    while True:
        ret, frame = cap.read()
        if ret:
            f = pool.apply_async(detect_object, args=(frame,))
            futures.append(f)
            time.sleep(0.025)
        else:
            break
    # wait for all the frame-putting tasks to complete:
    for f in futures:
        f.get()
    # signal the "show" task to end by placing None in the queue
    detection_buffer.put(None)
    show_future.get()
    print("program ended")
2 of 2
2

for me what I've done is building 2 threads for 2 funtions and use one queue:

  1. to get the frame and process it
  2. to dispaly

the cap variable was inside my process function.

def process:
     cap = cv2.VideoCapture(filename)
     ret, frame = cap.read()

      while ret:
          ret, frame = cap.read()
#detection part in my case I use tensorflow then 
     # end of detection part 
          q.put(result_of_detection)

def Display():
  while True:
    if q.empty() != True:
        frame = q.get()
        cv2.imshow("frame1", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

if __name__ == '__main__':
#  start threads
p1 = threading.Thread(target=process)
p2 = threading.Thread(target=Display)
p1.start()
p2.start()

it works just fine for me

hope I helped :D

Also, I think this page could may help: https://pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/