I am working on a video processing project using OpenCV in Python, and I've encountered a strange issue related to counting the number of frames in a video. I am using cv2.VideoCapture to read the frames from a video file, but I am getting inconsistent results when counting the total number of frames.
Here's the code snippet I'm using:
import cv2
video_path = 'MSP-IMPROV-S01A-F01-P-MF01.avi'
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"FPS: {fps}")
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print("Total frames using cv2.VideoCapture:", total_frames)
cap = cv2.VideoCapture(video_path)
frame_count = 0
while cap.isOpened():
ret, _ = cap.read()
if not ret:
break
frame_count += 1
cap.release()
print("Manually counted frames:", frame_count)
The output I'm getting is as follows:
FPS: 59.94005994005994
Total frames using cv2.VideoCapture: 1187
Manually counted frames: 594
Initially, I was puzzled by the discrepancy in the frame counts. However, upon closer inspection of the output frames, I noticed that the frames are being halved, and it seems OpenCV is skipping frames uniformly with a stride of one (i.e., one every two frames).
Could this be an issue with how OpenCV is reading the video file? Here are some additional considerations:
The video file format is AVI. Could this format be influencing how OpenCV reads the frames? Is this a known behavior or limitation in OpenCV's frame reading mechanism? Are there specific settings or parameters in cv2.VideoCapture that I need to adjust to avoid skipping frames? I would greatly appreciate any insights or suggestions on how to ensure that OpenCV reads every frame of the video without skipping.
Thank you for your help!
I think this answer might be useful in any case. Though I would be surprised if your video would not be interlaced, since this clear twice amount of frames is a very big indicator.
I created a function to test if the video is interlaced, it is based on ffmpeg, so you would have to get it with
sudo apt install ffmpeg.After that, I wrote this function in python to return
True,False, or an error message in case anything goes wrong:After this, you can use this function in your main, to dictate how the counting should work:
I copy pasted your code into the answer with only the small adjustment of dividing the number of cv2 frames by 2 when interlaced is detected.
Hope this helps you further.