0

Here, I have a code that takes a video as input and let the user draw a ROI. Later the cropped video will be displayed. This code was originally taken from I would like to define a Region of Interest in a video and only process that area. I have provided the code below. Question: I would like to save the cropped video in .mp4 format. The video output shows only a 1kb file. Can you go through the code and suggest a solution?

NB: I went through answer provided at OpenCV video not getting saved. Still I have failed to figure out the error.

import numpy as np
import cv2
import matplotlib.pyplot as plt


ORIGINAL_WINDOW_TITLE = 'Original'
FIRST_FRAME_WINDOW_TITLE = 'First Frame'
DIFFERENCE_WINDOW_TITLE = 'Difference'


canvas = None
drawing = False # true if mouse is pressed

#Retrieve first frame
def initialize_camera(cap):
    _, frame = cap.read()
    return frame


# mouse callback function
def mouse_draw_rect(event,x,y,flags, params):
    global drawing, canvas

    if drawing:
        canvas = params[0].copy()

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        params.append((x,y)) #Save first point

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            cv2.rectangle(canvas, params[1],(x,y),(0,255,0),2)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        params.append((x,y)) #Save second point
        cv2.rectangle(canvas,params[1],params[2],(0,255,0),2)


def select_roi(frame):
    global canvas

    #here, it is the copy of the first frame. 
    canvas = frame.copy()
    params = [frame]
    
    ROI_SELECTION_WINDOW = 'Select ROI'
    cv2.namedWindow(ROI_SELECTION_WINDOW)
    
    cv2.setMouseCallback(ROI_SELECTION_WINDOW, mouse_draw_rect, params)
    roi_selected = False
    while True:
        cv2.imshow(ROI_SELECTION_WINDOW, canvas)
        key = cv2.waitKey(10)

        #Press Enter to break the loop
        if key == 13:
            break;


    cv2.destroyWindow(ROI_SELECTION_WINDOW)
    roi_selected = (3 == len(params))
    print(len(params))

    if roi_selected:
        p1 = params[1]
        p2 = params[2]
        if (p1[0] == p2[0]) and (p1[1] == p2[1]):
            roi_selected = False

    #Use whole frame if ROI has not been selected
    if not roi_selected:
        print('ROI Not Selected. Using Full Frame')
        p1 = (0,0)
        p2 = (frame.shape[1] - 1, frame.shape[0] -1)


    return roi_selected, p1, p2




if __name__ == '__main__':

    cap = cv2.VideoCapture(r'E:\cardiovascular\brad1low.mp4')

    #Grab first frame
    first_frame = initialize_camera(cap)

    #Select ROI for processing. Hit Enter after drawing the rectangle to finalize selection
    roi_selected, point1, point2 = select_roi(first_frame)    

    #Grab ROI of first frame
    first_frame_roi = first_frame[point1[1]:point2[1], point1[0]:point2[0]]
    print(f'first frame roi is {first_frame_roi}')

    #An empty image of full size just for visualization of difference
    difference_image_canvas = np.zeros_like(first_frame)
    out = cv2.VideoWriter(r'E:\cardiovascular\filename2.mp4', cv2.VideoWriter_fourcc(*'MP4V'), int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), (int(first_frame_roi.shape[0]), (int(first_frame_roi.shape[1]))))


    while cap.isOpened():

        ret, frame = cap.read()


        if ret:

            #ROI of current frame
            roi = frame[point1[1]:point2[1], point1[0]:point2[0]]
            print(f'roi is {roi}')

            cv2.imshow(DIFFERENCE_WINDOW_TITLE, roi)
            out.write(roi)
            
            key = cv2.waitKey(30) & 0xff
            if key == 27:
                break
        else:
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • `select_roi(frame)` is returning the values from `if not roi_selected` ie the whole frame. Have a look at [OpenCV's ROI selector function instead](https://www.geeksforgeeks.org/python-opencv-selectroi-function/) – DrBwts Nov 30 '22 at 15:10
  • The size provided when constructing `VideoWriter` is wrong -- you have width and height swapped. If you try to write frames of incorrect size, the write fails silently. – Dan Mašek Nov 30 '22 at 17:42
  • welcome. [tour], [ask], [mre]. you speak of an error. traceback is required. – Christoph Rackwitz Dec 01 '22 at 00:34
  • 1
    @DanMašek, thank you so much. the width and height were swapped wrongly. I have provided rightly and now the video is getting saved with the right dimension and FPS. – Vijith Kumar V Dec 01 '22 at 02:55

0 Answers0