繁体   English   中英

将 RGB 视频转换为灰度视频以减小文件大小

[英]Convert RGB Video to Gray Scale video for file size reduction

我正在我的应用程序中使用 OpenCV 创建彩色视频(RGB),生成的视频文件需要上传到服务器。 彩色视频文件大小足以在当前可用带宽下上传到服务器时产生瓶颈。 因此,我尝试通过将其转换为 opencv 中的灰度视频来减小文件大小。 请在下面找到我当前工作的 OpenCV 实现:

cap = cv2.VideoCapture(RGB_video_filepath)
    fps = cap.get(cv2.CAP_PROP_FPS)
    print("Input Video FPS: ".format(fps))
    outputfilepath = "gray_video_output.avi"

    mjpg_forcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    divx_forcc = cv2.VideoWriter_fourcc(*'DIVX')
    xvid_forcc = cv2.VideoWriter_fourcc(*'XVID')
    fmpp4_codec = cv2.VideoWriter_fourcc('F','M','P','4')
    mp4v_codec = cv2.VideoWriter_fourcc(*'MP4V')
    vid_writer = cv2.VideoWriter(outputfilepath, mjpg_codec, 2, (640, 480), 0)

    while cv2.waitKey(1) < 0:
        # get frame from the video
        hasFrame, frame = cap.read()


        # Stop the program if reached end of video
        if not hasFrame:
            print("Done processing !!!")
            print("Output file is stored as ", outputfilepath)
            break

        gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        vid_writer.write(gray_frame)
        print("Frame shape: {} {}".format(frame_count, frame.shape))
        cv2.imshow("Camera frame", frame)
        cv2.waitKey(1)

    print("Total frames: {}".format(frame_count))
    vid_writer.release()
    cap.release()

使用上述工作流程,我创建了灰度视频,但我发现视频文件大小几乎相同(RGB 视频文件大小:25 MB,灰度视频大小:23 MB)。

在深入研究 OpenCV 后,我发现 OpenCV 将灰度(单通道)帧复制了 3 次,并作为 3 通道写入视频,尽管 OpenCV 使用 FFMPEG 在基于 Linux 的操作系统上写入视频文件。

我尝试使用 FFMPEG将相同的RGB 视频文件转换为灰度视频文件,如下所示:

ffmpeg -i inputvideofile -vf hue=s=0 outputvideofile

在这里,我保持色相和饱和度通道为空,令人惊讶的是RGB 视频文件(25 MB)被转换为灰度,文件大小减少到 6 MB。

**我很想知道我们是否可以通过使用 OpenCV 即时将 RGB 转换为灰度来实现视频文件大小的减小? **

任何帮助/更新表示赞赏。 谢谢!!

OpenCV 使用 FFMPEG。 尝试使用以下代码使用 ffmpeg-python 将每帧的 numpy 数组保存为视频并比较大小。

import numpy as np
import cv2
import ffmpeg

def save_video(cap,saving_file_name,fps=33.0):

    if cap.isOpened():
        ret, frame = cap.read()
        if ret:
            i_width,i_height = frame.shape[1],frame.shape[0]

    process = (
    ffmpeg
        .input('pipe:',format='rawvideo', pix_fmt='rgb24',s='{}x{}'.format(i_width,i_height))
        .output(saved_video_file_name,pix_fmt='yuv420p',vcodec='libx264',r=fps,crf=37)
        .overwrite_output()
        .run_async(pipe_stdin=True)
    )

    return process

if __name__=='__main__':

    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
    cap.set(3,1920)
    cap.set(4,1080)
    saved_video_file_name = 'output.avi'
    process = save_video(cap,saved_video_file_name)

    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret==True:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert frame/img to gray
            frame = cv2.flip(frame,0)
            process.stdin.write(
                cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    .astype(np.uint8)
                    .tobytes()
                    )

            cv2.imshow('frame',frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                process.stdin.close()
                process.wait()
                cap.release()
                cv2.destroyAllWindows()
                break
        else:
            process.stdin.close()
            process.wait()
            cap.release()
            cv2.destroyAllWindows()
            break

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM