0

I am attempting to use opencv_python to break an mp4 file down into it's frames so I can later open them with pillow, or at least be able to use the images to run my own methods on them.

I understand that the following snippet of code gets a frame from a live video or a recorded video.

    import cv2
    cap = cv2.VideoCapture("myfile.mp4")
    boolean, frame = cap.read()

What exactly does the read function return and how can I create an array of images which I can modify.

Citrus Ozel II
  • 11
  • 1
  • 1
  • 2
  • see: http://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html – parsethis Dec 21 '16 at 02:07
  • see also http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html – parsethis Dec 21 '16 at 02:10
  • 1
    Thanks for the links, but this does not answer my question. My goal is to actually store these images in an array without using disk space. – Citrus Ozel II Dec 21 '16 at 02:13

2 Answers2

1

adapted from How to process images of a video, frame by frame, in video streaming using OpenCV and Python. Untested. However, the frames are read into a numpy array and and append to a list that is converted to a numpy array when the all the frames are read in.

import cv2
import numpy as np


images = []

cap = cv2.VideoCapture("./out.mp4")
while not cap.isOpened():
    cap = cv2.VideoCapture("./out.mp4")
    cv2.waitKey(1000)
    print "Wait for the header"

pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
while True:
    frame_ready, frame = cap.read() # get the frame
    if frame_ready:
        # The frame is ready and already captured
        # cv2.imshow('video', frame)

        # store the current frame in as a numpy array
        np_frame = cv2.imread('video', frame)
        images.append(np_frame)
        
        pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
    else:
        # The next frame is not ready, so we try to read it again
        cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
        print "frame is not ready"
        # It is better to wait for a while for the next frame to be ready
        cv2.waitKey(1000)

    if cv2.waitKey(10) == 27:
        break
    if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
        # If the number of captured frames is equal to the total number of frames,
        # we stop
        break

all_frames = np.array(images)
djvg
  • 11,722
  • 5
  • 72
  • 103
parsethis
  • 7,998
  • 3
  • 29
  • 31
0

Simply use this code to get an array of frames from your video:

import cv2
import numpy as np
frames = []
video = cv2.VideoCapture("spiderino_turning.mp4")
while True:
    read, frame= video.read()
    if not read:
        break
    frames.append(frame)
frames = np.array(frames)

but regarding your question, video.read() returns two values. The first one (read in the example code) indicates if the frame is successfully read or not (i.e., True on succeeding and False on any error). The second returning value is the frame that can be empty if the read attempt is unsuccessful or a 3D array (i.e., color image) otherwise. But why can a read attempt be unsuccessful?

  1. If you are reading from a camera, any problem with the camera (e.g., the cable is disconnected or the camera's battery is dead) can cause an error.
  2. If you are reading from a video, the read attempt will fail when all the frames are read, and there are no more.
Khalil Youssefi
  • 385
  • 6
  • 10