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 应用程序从网络摄像头捕获帧并将帧写入stdout。目的是在 cmd-line 上调用此应用程序并将结果直接通过管道传输到 ffmpeg 应用程序,该应用程序将帧存储在磁盘上。确实很聪明!

捕获.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() )

而要在shell上执行的命令是:

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

哪里

  • -r 给出来自相机的帧速率
  • -an 表示“不编码音频”

我在我的 Mac OS X 上使用 OpenCV 2.4.2 测试了这个解决方案。

编辑:

如果您还没有尝试从相机录制并使用 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)

我已经在 Mac OS X 和 OpenCV 2.4.2 上使用 Python 2.7 对此进行了测试。

于 2012-09-24T21:43:06.887 回答
1

您是否尝试过使用splitmerge在 OpenCV 中切换 Cb/Cr 通道 ?

于 2012-09-29T22:27:40.257 回答
0

检查存在于:http ://en.wikipedia.org/wiki/YCbCr 中的转换公式?

于 2012-09-19T22:48:26.337 回答
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

我已经在这里回答了这个问题。但我的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 回答