-2

I need to take a video and analyze it frame-by-frame. This is what I have so far:

'''

cap = cv2.VideoCapture(CAM) # CAM = path to the video
    cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
    while cap.isOpened():
        ret, capture = cap.read()
        cv2.cvtColor(capture, frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('frame', capture)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        analyze_frame(frame)
    cap.release()

'''

This works, but it's incredibly slow. Is there any way that I can get it closer to real-time?

esljkfgh
  • 25
  • 1
  • 5
  • `cv2` has special class which runs `VideoCapture` in separated thread. See on `pyimagesearch.com`: [Increasing webcam FPS with Python and OpenCV](https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/) – furas Aug 25 '20 at 20:53
  • You are talking about it is slow but you dont know what is the real reason causing that. How can you be sure about the slowness of stream? Also we dont know what `analyze_frame` doing. – Yunus Temurlenk Aug 26 '20 at 05:03

1 Answers1

2

The reason VideoCapture is so slow because the VideoCapture pipeline spends the most time on the reading and decoding the next frame. While the next frame is being read, decode, and returned the OpenCV application is completely blocked.

So you can use FileVideoStream which uses queue data structure to process the video concurrently.

  • The package you need to install:

  • For virtual environment: pip install imutils
  • For anaconda environment: conda install -c conda-forge imutils

Example code:

import cv2
import time
from imutils.video import FileVideoStream


fvs = FileVideoStream("test.mp4").start()

time.sleep(1.0)

while fvs.more():
    frame = fvs.read()

    cv2.imshow("Frame", frame)

Speed-Test


You can do speed-test using any example video using the below code. below code is designed for FileVideoStream test. Comment fvsvariable and uncomment cap variable to calculate VideoCapture speed. So far fvs more faster than cap variable.

from imutils.video import FileVideoStream
import time
import cv2

print("[INFO] starting video file thread...")
fvs = FileVideoStream("test.mp4").start()
cap = cv2.VideoCapture("test.mp4")
time.sleep(1.0)

start_time = time.time()

while fvs.more():
     # _, frame = cap.read()
     frame = fvs.read()

print("[INFO] elasped time: {:.2f}ms".format(time.time() - start_time))
Ahmet
  • 7,527
  • 3
  • 23
  • 47