How to choose Full Frames (Uncompressed) as codec for VideoWriter

时间:2016-11-26 18:33:17

标签: opencv kinect video-capture emgucv codec

i want to store uncompressed frames from a device as a video, but i need to know how to choose " Full Frames (Uncompressed) " as a codec for the VideoWriter (in emgu aka openCV).

Iam able to choose it from the dropdown menu when iam passing -1 like this

VideoWriter myVideoWriter = new VideoWriter ("myVieoColor.avi", -1 , 15, videoSize, true);

But i want to choose the Full Frames (Uncompressed) codec automatically. For example i know i can choose the Lagarith Lossless Video Codec by

VideoWriter myVideoWriter = new VideoWriter ("myVieoColor.avi", Emgu.CV.VideoWriter.Fourcc('L','A','G','S') , 15, videoSize, true);

but iam not able to figure out which fourcc i need to use.

Perhaps someone can help me out please

3 个答案:

答案 0 :(得分:4)

如果我们在打开此编解码器选择对话框时进入调试器,我们可以看到它是this callAVISaveOptions(...)的结果。因此,找出您选择的内容的一种方法是在line 799上设置断点并检查fourcc的内容。

但是,有更简单的方法:

  1. 使用1个黑框创建虚拟视频 foo.avi ,使用GUI选择编解码器。
  2. 使用cv::VideoCapture打开 foo.avi
  3. CAP_PROP_FOURCC实例获取cv::VideoCapture
  4. 解码并打印。
  5. [可选]仅使用1个黑框创建虚拟视频 bar.avi ,并使用您在步骤3中确定的FOURCC代码。比较 foo.avi 和< strong> bar.avi 以验证它们是否相同。
  6. 抱歉,我不使用C#/ EmguCV,所以我无法为您提供一个确切的示例,但以下内容应该很容易移植。

    C ++示例

    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    int main()
    {
        {
            cv::VideoWriter outputVideo;
            outputVideo.open("foo.avi", -1, 25.0, cv::Size(640, 480), true);
    
            cv::Mat frame(480, 640, CV_8UC3);
            outputVideo.write(frame);
        }
    
        cv::VideoCapture inputVideo("foo.avi");
        int fourcc = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC));
    
        char FOURCC_STR[] = {
            (char)(fourcc & 0XFF)
            , (char)((fourcc & 0XFF00) >> 8)
            , (char)((fourcc & 0XFF0000) >> 16)
            , (char)((fourcc & 0XFF000000) >> 24)
            , 0
        };
        std::cout << "FOURCC is '" << FOURCC_STR << "'\n";
    
        return 0;
    }
    

    控制台输出:

    FOURCC is 'DIB '
    

    Python示例

    import cv2
    import numpy as np
    import struct
    
    outputVideo = cv2.VideoWriter()
    outputVideo.open("foo.avi", -1, 25, (640,480), True)
    
    frame = np.zeros((480,640,3), dtype=np.uint8)
    outputVideo.write(frame)
    outputVideo.release()
    
    inputVideo = cv2.VideoCapture("foo.avi")
    fourcc = int(inputVideo.get(cv2.cv.CV_CAP_PROP_FOURCC))
    
    print "FOURCC is '%s'" % struct.pack("<I", fourcc)
    

    控制台输出:

    FOURCC is 'DIB '
    

答案 1 :(得分:1)

来自Opencv参考

提示:

- &gt;使用一些后端,4cc = -1会弹出系统中的编解码器选择对话框。

- &gt;要保存图像序列,请使用正确的文件名(例如img_%02d.jpg)和fourcc = 0或fps = 0。使用未压缩的图像格式(例如img_%02d.BMP)来保存原始帧。

- &gt;大多数编解码器都是有损的。如果你想要无损视频文件,你需要使用无损编解码器(例如FFMPEG FFV1,Huffman HFYU,Lagarith LAGS等......)

- &gt;如果启用了FFMPEG,则使用codec = 0; FPS = 0;你可以创建一个未压缩的(原始)视频文件。

http://docs.opencv.org/trunk/dd/d9e/classcv_1_1VideoWriter.html#afec93f94dc6c0b3e28f4dd153bc5a7f0

答案 2 :(得分:0)

非常感谢你。

我想到了类似的方法,但错过了emgu中的函数(VideoWriter和Capture得到了一个get(CAP_PROB)函数,但多亏了你我搜索了一下,找到了CvInvoke.cveVideoCaptureGet函数。

现在我可以像使用Capture类读取视频文件之前那样编写视频并使用上面的功能。

//record the Videofile with VideoWriter to "myVideoColor.avi"
capture = new Capture("myVieoColor.avi");
System.Diagnostics.Debug.WriteLine(CvInvoke.cveVideoCaptureGet(capture, Emgu.CV.CvEnum.CapProp.FourCC));

到目前为止一切顺利。 当我使用LAGS作为编解码器时,一切正常,我得到1397178700,所以我可以用这个值来调用构造函数。

VideoWriter myVideoWriter = new VideoWriter ("myVieoColor.avi", 1397178700 , 15, videoSize, true);
//works great with 1397178700 == LAGS codec

但是当我传递-1并从下拉菜单中选择未压缩时,它返回0作为4CC编解码器值,但当使用0作为构造函数参数时,它不会记录并打印808596553作为使用的编解码器的值

VideoWriter myVideoWriter = new VideoWriter ("myVieoColor.avi", 0 , 15, videoSize, true);
//dont work and CapProb.FourCC returns 808596553

从drop中选择Lagarith Lossless Codec给了我应有的1397178700并且可以工作。 那么任何想法?

PS:再次感谢你帮助DanMašek