'Python CV2 video writer doesn't save video

I have a simple python code using OpenCV and Keras that performs some detections on frames (follow-up from my previous question here). But when I want to record and save the frames as a video using video_writer, the generated video is empty.

What is wrong in the video_writer?

#........some code    
# start the webcam feed
cap = cv2.VideoCapture(1)

canvasImageOriginal = cv2.imread("fg2.png")
canvasImage = cv2.imread("fg2.png")
canvasHappy = cv2.imread("fg2happy.png")
canvasSad = cv2.imread("fg2sad.png")
x0, x1 = 330, 1290
y0, y1 = 155, 700

#=========
w=960#int(cap.get(cv2.CV_CAP_PROP_FRAME_WIDTH ))
h=540#int(cap.get(cv2.CV_CAP_PROP_FRAME_HEIGHT ))
# video recorder
fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_writer = cv2.VideoWriter('output.avi', fourcc, 25.0, (w, h))
#=========


prediction_history = []
LOOKBACK = 5 # how far you want to look back

counter = 0
while True:
    # Find haar cascade to draw bounding box around face
    ret, frame = cap.read()
    frame=cv2.flip(frame,3)
    if not ret:
        break
    facecasc = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = facecasc.detectMultiScale(gray,scaleFactor=1.3, minNeighbors=5)

    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (255, 0, 0), 2)
        roi_gray = gray[y:y + h, x:x + w]
        cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray, (48, 48)), -1), 0)
        prediction = model.predict(cropped_img)
        
        maxindex = int(np.argmax(prediction))
        text = emotion_dict[maxindex]
        print(prediction[0][3])
        
        prediction_history.append(maxindex)
        most_common_index = max(set(prediction_history[-LOOKBACK:][::-1]), key = prediction_history.count)
        text = emotion_dict[most_common_index]
        
        #if ("Sad" in text) or ("Angry" in text) or ("Disgusted" in text):
        #    text = "Sad"
        if ("Happy" in text) or ("Sad" in text) :
            cv2.putText(frame, text, (x+20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
            if ("Happy" in text):
                counter= counter+1
                if counter == 10:
                    #print("Happy!")
                    
                    canvasImage = canvasHappy
        else:
            counter = 0
            canvasImage = canvasImageOriginal
            
                
            
            

    dim = (800,480)
    frame_shrunk = cv2.resize(frame, (x1 - x0, y1 - y0))
    canvasImage[y0:y1, x0:x1] = frame_shrunk
    #cv2.imshow('Video', cv2.resize(frame,dim,interpolation = cv2.INTER_CUBIC))
    cv2.imshow('Demo', canvasImage)
    video_writer.write(frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
video_writer.release()
cv2.destroyAllWindows()


Solution 1:[1]

As it is mentioned above, please check print(frame.shape).

When I did it, I saw (300,450,3), and I changed the resolution of videowriter as (450,300) and it worked for me. As a result, I can say that frame.shape=(y, x, maybe color) but the resolution of videowriter=(x,y).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 richardec