3

I am performing template matching and everything seems to be working fine in cv2.imshow(). I want to write a video with all frames resulting from the template matching process. Part of my code includes resizing the template image and the video frame dimensions, I don't know if the video writing problem comes from this step or not. The errors are coming mostly from the out.write(frame) part.

I get the following error after using the code below:

cv2.error: OpenCV(3.4.2) C:\Miniconda3\conda-bld\opencv-suite_1534379934306\work\modules\videoio\src\cap_ffmpeg.cpp:296: error: (-215:Assertion failed) image.depth() == 0 in function 'cv::`anonymous-namespace'::CvVideoWriter_FFMPEG_proxy::write'

Any ideas?

import cv2
import numpy as np

cap = cv2.VideoCapture(input_video_file)
fps = int(round(cap.get(5)))
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')   # saving output video as .mp4
out = cv2.VideoWriter(output_video_file, fourcc, fps, (frame_width, frame_height))

# while loop where the real work happens
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            if cv2.waitKey(28) & 0xFF == ord('q'):
                break
            
            # Read template image from path
            template = cv2.imread('D:\KU_Leuven\Computer_Vision\Assignment_1\Videos\Raspberry_Template.jpg',0)
            h2,w2 = template.shape[:2]
                    
            #resize video frame dimensions
            scale_percent =60 # percentage of original video frame size
            width = int(frame.shape[1] * scale_percent / 100)
            height = int(frame.shape[0] * scale_percent / 100)
            dim = (width, height)
            frame = cv2.resize(frame , dsize = dim)

            #resize template dimensions
            scale_percent = 16# percentage of original template image size
            width = int(template.shape[1] * scale_percent / 100)
            height = int(template.shape[0] * scale_percent / 100)
            dim = (width, height)
            template = cv2.resize(template , dsize = dim)
            
            method = eval('cv2.TM_CCOEFF_NORMED')

            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            
            # template match
            res = cv2.matchTemplate(gray,template,method)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
            
            # Draw box around the Max likelihood location of the template
            top_left = max_loc
            h,w =template.shape[:2]
            bottom_right = (top_left[0] + w, top_left[1] + h)
            cv2.rectangle(gray,top_left, bottom_right, (255,0,0), 2)
            
            res = cv2.putText(res,'Likelihood Map from Template Matching', (50,50),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255,255,255), 2, cv2.LINE_AA) 
            
            cv2.rectangle(frame,top_left, bottom_right, (51,255,51), 2)
            cv2.imshow("Color Video Feed - Box",frame)

            cv2.imshow("Grayscale Video Feed - Box",gray)
            
            cv2.imshow("Likelihood Map",res) # produces the correct result

            res = cv2.resize(res,(frame_width,frame_height))         
            out.write(res)
                                    
            # Press Q on keyboard to  exit
            if cv2.waitKey(25) & 0xFF == ord('q'):
                break

        # Break the loop
        else:
            break

    # When everything done, release the video capture and writing object
    cap.release()
    out.release()
    # Closes all the frames
    cv2.destroyAllWindows()
Tony-Gl.
  • 33
  • 5

1 Answers1

1

The following may help for using opencv VideoWriter in order to save H264 encoded video into mp4 file:

import cv2
#print(cv2.__version__)

# Uncommenting the following would allow checking if your opencv build has FFMPEG and GSTREAMER support
#print(cv2.getBuildInformation())

# Video source
cap = cv2.VideoCapture('videotestsrc ! videoconvert ! queue ! video/x-raw, format=BGR ! appsink drop=1', cv2.CAP_GSTREAMER)

# fps is a float value, width and height are integer values
fps = float(cap.get(cv2.CAP_PROP_FPS))
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# Using FFMPEG backend: 4CC specifies codec, container is found from filename extension...here using mp4
output_video_file='test_H264.mp4'
fourcc = cv2.VideoWriter_fourcc(*'X264')        
out = cv2.VideoWriter(output_video_file, cv2.CAP_FFMPEG, fourcc, fps, (frame_width, frame_height))

# Alternatively, using GSTREAMER backend:
#out = cv2.VideoWriter('appsrc ! queue ! video/x-raw,format=BGR ! videoconvert ! x264enc ! h264parse ! qtmux ! filesink location=test_H264.mp4', cv2.CAP_GSTREAMER, 0, fps, (frame_width, frame_height))
# With NVIDIA, you may use HW encoder:
#out = cv2.VideoWriter('appsrc ! queue ! video/x-raw,format=BGR ! videoconvert ! video/x-raw,format=BGRx ! nvvidconv ! video/x-raw(memory:NVMM),format=NV12 ! nvv4l2h264enc ! h264parse ! qtmux ! filesink location=test_H264.mp4', cv2.CAP_GSTREAMER, 0, fps, (frame_width, frame_height))


if  not cap.isOpened():
    print("Failed to open capture")
    exit()

if  not out.isOpened():
    print("Failed to open writer")
    exit()

while cap.isOpened():
    ret, frame = cap.read()
    out.write(frame)
    cv2.imshow('Test', frame)
    cv2.waitKey(1)
SeB
  • 1,159
  • 6
  • 17
  • I still get the following error: cv2.error: OpenCV(3.4.2) C:\Miniconda3\conda-bld\opencv-suite_1534379934306\work\modules\videoio\src\cap_ffmpeg.cpp:296: error: (-215:Assertion failed) image.depth() == 0 in function 'cv::`anonymous-namespace'::CvVideoWriter_FFMPEG_proxy::write' – Tony-Gl. Mar 21 '22 at 20:37
  • Seems the frame is void... Did you try exactly my example ? If yes, maybe your opencv build doesn't have gstreamer support...you may check uncommenting in the code above. (I'd expect the capture to fail to open, though, so not sure). You may also check ret value for read success. – SeB Mar 21 '22 at 20:44
  • I have used the same codec configuration as in my code above and I successfully saved another video. I think the problem, in this template matching scenario, is either the size of the "res" frame to be written in the video or the color space (?) I am experimenting with changes like these. – Tony-Gl. Mar 21 '22 at 20:55