How to read grayscale img from a video with OpenCV?

I read all pictures from my pic directory and then convert them each to gray-scale with canny edge detections before writing it all to a video.

But, when I use my video software to play it, it shows a green background, and I can't read video frames from it. Could someone show me how to solve it?

Sample code

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

fourcc = cv.VideoWriter_fourcc(*"I420")
out = cv.VideoWriter("t2.avi", fourcc, 1, (640, 480), 0)
for pic in glob.glob1("./pic/", "A*"):
    img = cv.imread(f"./pic/{pic}", -1)
    
    edge = cv.Canny(img, 100, 200)
    edge = cv.resize(edge, (640, 480))
    out.write(edge)

out.release()

# Cant read video frame here:
cap = cv.VideoCapture("t2.avi")
ret, frame = cap.read()
if ret:
    plt.imshow(frame)
else:
    print("end")
    cap.release()

Video plays with green background enter image description here

1 answer

  • answered 2022-05-07 08:49 Rotem

    It looks like a compatibility issue between I420 FOURCC and Grayscale format.

    Replace fourcc = cv.VideoWriter_fourcc(*"I420") with:

    fourcc = cv.VideoWriter_fourcc(*"GREY")
    

    Note:

    • I am using OpenCV 4.5.5 in Windows 10, and it's working with "GREY".
      I am not sure it's going to work in all platforms and versions.

    I420 applies colored video.
    You may use I420 with colored video:

    Replace out = cv.VideoWriter("t2.avi", fourcc, 1, (640, 480), 0) with:

    out = cv.VideoWriter("t2.avi", fourcc, 1, (640, 480), 1)
    

    Convert edge to BGR before writing:

    edge = cv.cvtColor(edge, cv.COLOR_GRAY2BGR)
    out.write(edge)
    

    Code sample using "GREY" FOURCC:

    import numpy as np
    import cv2 as cv
    #import matplotlib.pyplot as plt
    import glob
    
    #fourcc = cv.VideoWriter_fourcc(*"I420")
    fourcc = cv.VideoWriter_fourcc(*"GREY")
    out = cv.VideoWriter("t2.avi", fourcc, 1, (640, 480), 0)
    for pic in glob.glob1("./pic/", "A*"):
        img = cv.imread(f"./pic/{pic}", -1)
        
        edge = cv.Canny(img, 100, 200)
        edge = cv.resize(edge, (640, 480))
        out.write(edge)
    
    out.release()
    
    # Cant read video frame here:
    cap = cv.VideoCapture("t2.avi")
    
    while True:
        ret, frame = cap.read()
        if ret:
            #plt.imshow(frame)
            cv.imshow('frame', frame)
            cv.waitKey(1000)
        else:
            print("end")
            cap.release()
            break
    
    cv.destroyAllWindows()
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum