1

I use OpenCV to read in the frames of many FLV videos. The part where I do the reading is:

def frame_preprocessing(image, left=320, right=600, top=220, bottom=348):
    height, width, channel = image.shape
    return image[top:height-bottom,left:width-right,:]

# Create a VideoCapture object and read from input file
cap = cv2.VideoCapture(file_path)

if cap.isOpened(): # Check if camera opened successfully
    ret, frame = cap.read()
    if ret == True:
        frame = frame_preprocessing(frame).astype('int8')
else:
    print("Error opening video stream or file")

frames = np.empty(shape=(nb_frames_in_file,) + frame.shape, dtype=np.int8)
frames[0, :, :, :] = frame

nr_frame = 1
# Read until video is completed
while (cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    if ret == True:
        frames[nr_frame, :, :, :] = frame_preprocessing(frame).astype('int8')
        nr_frame = nr_frame + 1
    else:
        break

# When everything done, release the video capture object
cap.release()

Instead of using the function frame_preprocessing to cut out a certain section of the frames, I would like to not load the entire image in the first place. How can I tell OpenCV to only read a certain section of the frames?

Make42
  • 12,236
  • 24
  • 79
  • 155
  • You want to just read a part of the frame, e.g. upper half of the frame, is that it? Do you think it will be faster that way? – Eypros Sep 14 '18 at 10:57
  • @Eypros: Yes, that is correct. Let's say the video is of size 300 x 400, and I want to only read the pixels 200-250 x 200-300. I hope it will be faster, yes. – Make42 Sep 14 '18 at 11:21
  • I don't think you can easily read a part of a frame. You need to dig in the original code (I don't think it would be implemented). Also I am not sure it's possible if a frame is required for another frame to be decoded etc. See p/b-Frames etc – Eypros Sep 14 '18 at 11:40
  • Not with OpenCV. Perhaps if you use ffmpeg or something like that directly. TBH, I don't see you gaining much doing this (other than a lot more code to write). – Dan Mašek Sep 14 '18 at 12:08
  • Rather than call `cv2.VideoCapture()` and `cap.read()` you would need to call `subprocess.popen()` and put an `ffmpeg` command in there that crops the video to what you want and reformats that part into `BGR` frames for OpenCV to read. It would probably be more likely to improve the speed only if you have a multi-core CPU. It's kind if the reverse of this answer, but it should show you the sort of parameters you need for `ffmpeg` https://stackoverflow.com/a/46710797/2836621 – Mark Setchell Sep 15 '18 at 21:39

1 Answers1

0

I'm not sure that it will be faster because the way videos formats (mp4, flv, etc.) zipped. As I understand it the algorithms should first unzip it (full frame) and then only crop it, but maybe I'm wrong. Anyway have a look on crop function of ffmpeg. You can find ffmpeg-python library:

Waiting to hear if it's helpful.

Make42
  • 12,236
  • 24
  • 79
  • 155
ChaosPredictor
  • 3,777
  • 1
  • 36
  • 46