Error creating new directories for video frames for different videos

208 views Asked by At

Per title, I'm trying to write code to loop through multiple videos in a folder to extract their frames, then write each video's frames to their own new folder, e.g. video1 to frames_video1, video2 to frames_video2.

This is my code:

subclip_video_path = main_path + "\\subclips"
frames_path = main_path + "\\frames"

#loop through videos in file
for subclips in subclip_video_path:
    currentVid = cv2.VideoCapture(subclips)
    success, image = currentVid.read()
    count = 0
    while success:
        
        #create new frames folder for each video
        newFrameFolder = ("frames_" + subclips)
        os.makedirs(newFrameFolder)

I get this error:

[ERROR:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-k8sx3e60\opencv\modules\videoio\src\cap.cpp (142) cv::VideoCapture::open VIDEOIO(CV_IMAGES): raised OpenCV exception:

OpenCV(4.4.0) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-k8sx3e60\opencv\modules\videoio\src\cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): P in function 'cv::icvExtractPattern'

What does this mean? How can I fix this?

1

There are 1 answers

1
Ahx On BEST ANSWER
  1. You can't loop though string: for subclips in subclip_video_path:

You need to get the list of your videos:

from glob import glob

sub_clip_video_path = glob("sub_clip_video_path/*.mp4")

This means get all the .mp4 extension video files and store it in sub_clip_video_path variable.

My Result:

['sub_clip_video_path/output.mp4', 'sub_clip_video_path/result.mp4']

Since I'm sure the directory contains two .mp4 extension files, now I can continue.

  1. You don't need to re-declare VideoCapture for each frame.
for count, sub_clips in enumerate(sub_clip_video_path):
    currentVid = cv2.VideoCapture(sub_clips)
    success, image = currentVid.read()
    count = 0

After you declare VideoCapture read all the frames from the current video, then declare VideoCapture for the next video.

for count, sub_clips in enumerate(sub_clip_video_path):
    currentVid = cv2.VideoCapture(sub_clips)
    image_counter = 0
    while currentVid.isOpened():
          .
          .
  1. Don't use while success this will create an infinite loop.

If the first frame grabbed from the video, then the success variable returns True. When you say:

while success:
    #create new frames folder for each video
    newFrameFolder = ("frames_" + subclips)
    os.makedirs(newFrameFolder)

You will create infinite amount of folder for the current frame.

Here my result:

import os
import cv2
from glob import glob

sub_clip_video_path = glob("sub_clip_video_path/*.mp4")  # Each image extension is `.mp4`

for count, sub_clips in enumerate(sub_clip_video_path):
    currentVid = cv2.VideoCapture(sub_clips)
    image_counter = 0
    while currentVid.isOpened():
        success, image = currentVid.read()

        if success:
            newFrameFolder = "frames_video{}".format(count + 1)

            if not os.path.exists(newFrameFolder):
                os.makedirs(newFrameFolder)
            
            image_name = os.path.join(newFrameFolder, "frame{}.png".format(image_counter + 1))
            cv2.imwrite(image_name, image)
            image_counter += 1
        else:
            break
  • I gathered all the videos using glob

  • While the current video is being read:

    • for count, sub_clips in enumerate(sub_clip_video_path):
          currentVid = cv2.VideoCapture(sub_clips)
          image_counter = 0
      
          while currentVid.isOpened():
      
  • If the current frame successfully grabbed, then declare folder name. If the folder does not exist, create it.

    •    if success:
             newFrameFolder = "frames_video{}".format(count + 1)
      
              if not os.path.exists(newFrameFolder):
                  os.makedirs(newFrameFolder)
      
  • Then declare the image name and save it.

    • image_name = os.path.join(newFrameFolder, "frame{}.png".format(image_counter + 1))
      cv2.imwrite(image_name, image)
      image_counter += 1