10

私はpython、opencv、ffmpegで構築されたウェブカメラビデオレコーダープログラムを持っています

ビデオの色が現実よりも青いことを除いて、問題なく動作します。問題は画像のカラーフォーマットにあるようです。

OpenCvはBGRイメージを提供しており、ffmpeg+libx264はYUV420pを期待しているようです。YUV420pがYCbCrに対応していることを読みました。

opencvにはBGRからYCbCrへの変換はありません。YCrCbへの変換のみがあります。

私はいくつかの検索を行い、opencvイメージをffmpeg+libx264で問題ないものに変換するためにさまざまな代替手段を試しました。何も機能していません。この時点で、私は少し迷っています。この色の問題を修正するのに役立つポインタをいただければ幸いです。

4

5 に答える 5

13

そうです、OpenCVのデフォルトのピクセルフォーマットはBGRです。

ffmpeg側の同等のフォーマットはBGR24であるため、必要がない場合はYUV420pに変換する必要はありません。

この投稿では、Pythonアプリケーションを使用してWebカメラからフレームをキャプチャし、フレームをstdoutに書き込む方法を示します。目的は、cmd行でこのアプリを呼び出し、結果を直接ffmpegアプリケーションにパイプすることです。ffmpegアプリケーションは、フレームをディスクに保存します。確かにかなり賢いです!

Capture.py

import cv, sys

cap = cv.CaptureFromCAM(0)
if not cap:
    sys.stdout.write("failed CaptureFromCAM")

while True :
    if not cv.GrabFrame(cap) : 
        break

    frame = cv.RetrieveFrame(cap)
    sys.stdout.write( frame.tostring() )

また、シェルで実行されるコマンドは次のとおりです。

python capture.py | ffmpeg -f rawvideo -pix_fmt bgr24 -s 640x480 -r 30 -i - -an -f avi -r 30 foo.avi

ここで

  • -rは、カメラから出るフレームレートを示します
  • -anは「オーディオをエンコードしないでください」と言います

このソリューションは、OpenCV2.4.2を搭載したMacOSXでテストしました。

編集:

カメラから録画し、OpenCVを使用してビデオをディスク上のmp4ファイルに書き込もうとしたことがない場合は、次のようにします。

import cv, sys

cap = cv.CaptureFromCAM(0)   # 0 is for /dev/video0
if not cap:
    sys.stdout.write("!!! Failed CaptureFromCAM")
    sys.exit(1)

frame = cv.RetrieveFrame(cap)
if not frame: 
    sys.stdout.write("!!! Failed to retrieve first frame")
    sys.exit(1)

# Unfortunately, the following instruction returns 0
#fps = cv.GetCaptureProperty(cap, cv.CV_CAP_PROP_FPS)
fps = 25.0      # so we need to hardcode the FPS
print "Recording at: ", fps, " fps"  

frame_size = cv.GetSize(frame)
print "Video size: ", frame_size  

writer = cv.CreateVideoWriter("out.mp4", cv.CV_FOURCC('F', 'M', 'P', '4'), fps, frame_size, True)
if not writer:
    sys.stdout.write("!!! Error in creating video writer")
    sys.exit(1)


while True :
    if not cv.GrabFrame(cap) : 
        break
    frame = cv.RetrieveFrame(cap)
    cv.WriteFrame(writer, frame)

cv.ReleaseVideoWriter(writer)
cv.ReleaseCapture(cap)

私はこれをMacOSXとOpenCV2.4.2のPython2.7でテストしました。

于 2012-09-24T21:43:06.887 に答える
1

分割マージを使用してOpenCVのCb/Crチャネルを切り替えてみました か?

于 2012-09-29T22:27:40.257 に答える
0

libx264コーデックはBGRイメージを処理できます。YCbCrへの変換を使用する必要はありません。ffmpegに特定のpix_ftmを与える必要はありません。RGBを使用していて、ビデオに青みがかった効果を引き起こしていました。

解決策は、変換せずにカメラによって再調整された元の画像を使用することでした。:)

以前の調査でこれを試しましたが、アプリがクラッシュしていました。解決策は、カメラから返されたフレームをコピーすることです。

    frame = opencv.QueryFrame(camera)
    if not frame:
        return None, None

    # RGB : use this one for displaying on the screen
    im_rgb = opencv.CreateImage(self.size,  opencv.IPL_DEPTH_8U, 3)
    opencv.CvtColor(frame, im_rgb, opencv.CV_BGR2RGB)

    # BGR : Use this one for the video
    im_bgr = opencv.CreateImage(self.size,  opencv.IPL_DEPTH_8U, 3)
    opencv.Copy(frame, im_bgr)

    return im_rgb, im_bgr
于 2012-10-05T09:36:29.833 に答える
0

http://en.wikipedia.org/wiki/YCbCrにある変換式を確認しましたか?

于 2012-09-19T22:48:26.337 に答える
0

私はすでにここでこれに答えました。しかし、私のVidGearPythonライブラリは、OpenCVフレームをFFmpegにパイプライン化するプロセス全体を自動化し、フォーマット変換も堅牢に処理します。基本的なPythonの例を次に示します。

# import libraries
from vidgear.gears import WriteGear
import cv2

output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"} #define (Codec,CRF,preset) FFmpeg tweak parameters for writer

stream = cv2.VideoCapture(0) #Open live webcam video stream on first index(i.e. 0) device

writer = WriteGear(output_filename = 'Output.mp4', compression_mode = True, logging = True, **output_params) #Define writer with output filename 'Output.mp4' 

# infinite loop
while True:

    (grabbed, frame) = stream.read()
    # read frames

    # check if frame empty
    if not is grabbed:
        #if True break the infinite loop
        break


    # {do something with frame here}
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # write a modified frame to writer
        writer.write(gray) 

        # Show output window
    cv2.imshow("Output Frame", frame)

    key = cv2.waitKey(1) & 0xFF
    # check for 'q' key-press
    if key == ord("q"):
        #if 'q' key-pressed break out
        break

cv2.destroyAllWindows()
# close output window

stream.release()
# safely close video stream
writer.close()
# safely close writer

ソース:https ://github.com/abhiTronix/vidgear/wiki/Compression-Mode:-FFmpeg#2-writegear-classcompression-mode-with-opencv-directly

より高度なアプリケーションとエキサイティングな機能については、完全なVidGearドキュメントを確認できます。

お役に立てば幸いです。

于 2019-05-01T14:05:21.917 に答える