I want to process and extract the video using the Create Background Subtraction method with OpenCV. However, after writing the code as below, the video does not play.
import numpy as np
import time
video_path = 'aaa.mp4'
output_path = 'aaa_test.mp4'
video = cv2.VideoCapture(video_path)
w=round(video.get(cv2.CAP_PROP_FRAME_WIDTH))
h=round(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'MP4v')
out = cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w,h))
fgbg = cv2.createBackgroundSubtractorMOG2(history=200,varThreshold=32,detectShadows=False)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(1,1))
while(1):
start = time.time()
return_value, frame = video.read()
if return_value:
pass
else :
print('END')
break
background_extraction_mask = fgbg.apply(frame)
background_extraction_mask = cv2.dilate(background_extraction_mask,kernel,iterations=1)
background_extraction_mask = np.stack((background_extraction_mask,)*3, axis=-1)
concat_image = np.concatenate((frame,background_extraction_mask), axis=1)
cv2.imshow('background extraction video', concat_image)
out.write(concat_image)
cv2.waitKey(1)
video.release()
out.release()
cv2.destroyAllWindows()
CodePudding user response:
There are two issues I could find:
- FOURCC code is case sensitive - it should be
'mp4v'
instead of'MP4v'
. - The written video frame is twice the width of the original video frame due to the horizontal concatenation.
Replacecv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w, h))
withcv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w*2, h))
Complete code sample:
import cv2
import numpy as np
import time
video_path = 'aaa.mp4'
output_path = 'aaa_test.mp4'
video = cv2.VideoCapture(video_path)
w = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # fourcc = cv2.VideoWriter_fourcc(*'MP4v') # FOURCC is case sensitive
out = cv2.VideoWriter('aaa_1_1.mp4', fourcc, fps, (w*2, h)) # Size must match the actual frame size, so use (w*2, h) instead of (w, h) because written frame is two concatenated frames.
fgbg = cv2.createBackgroundSubtractorMOG2(history=200, varThreshold=32, detectShadows=False)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
while True:
start = time.time()
return_value, frame = video.read()
if not return_value:
print('END')
break
background_extraction_mask = fgbg.apply(frame)
background_extraction_mask = cv2.dilate(background_extraction_mask, kernel, iterations=1)
background_extraction_mask = np.stack((background_extraction_mask,)*3, axis=-1)
concat_image = np.concatenate((frame, background_extraction_mask), axis=1)
cv2.imshow('background extraction video', concat_image)
cv2.waitKey(1)
out.write(concat_image)
video.release()
out.release()
cv2.destroyAllWindows()
CodePudding user response:
My apologized. It worked for me. You are missing namespace add this. Also waitKey() should be inside while looping.
import cv2
while(1):
start = time.time()
return_value, frame = video.read()
if return_value:
pass
else :
print('END')
break
background_extraction_mask = fgbg.apply(frame)
background_extraction_mask = cv2.dilate(background_extraction_mask,kernel,iterations=1)
background_extraction_mask = np.stack((background_extraction_mask,)*3, axis=-1)
concat_image = np.concatenate((frame,background_extraction_mask), axis=1)
cv2.imshow('background extraction video', concat_image)
out.write(concat_image)
cv2.waitKey(1)
video.release()
out.release()
cv2.destroyAllWindows()