Home > Enterprise >  How to read grayscale img from a video with OpenCV?
How to read grayscale img from a video with OpenCV?

Time:05-09

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

CodePudding user response:

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()
  • Related