簡體   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