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

*爱你&永不变心* 提交于 2019-12-12 09:43:49

问题


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


回答1:


If we break into debugger when this codec selection dialog box is open, we can see that it's the result of this call to AVISaveOptions(...). So, one way to find out what you picked would be to set a breakpoint on say line 799 and inspect the contents of fourcc.

However, there is even simpler way:

  1. Create a dummy video foo.avi with just 1 black frame, selecting the codec using the GUI.
  2. Open foo.avi using cv::VideoCapture.
  3. Get the CAP_PROP_FOURCC from the cv::VideoCapture instance.
  4. Decode and print it.
  5. [Optional] Create a dummy video bar.avi with just 1 black frame, and use the FOURCC code you determined in step 3. Compare foo.avi and bar.avi to verify they are the same.

Sorry, I don't use C#/EmguCV, so I can't provide you an exact example, but the following should be easy enough to port.

C++ Sample

#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;
}

Console output:

FOURCC is 'DIB '

Python Sample

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)

Console output:

FOURCC is 'DIB '



回答2:


From Opencv Reference

Tips:

->With some backends fourcc=-1 pops up the codec selection dialog from the system.

->To save image sequence use a proper filename (eg. img_%02d.jpg) and fourcc=0 OR fps=0. Use uncompressed image format (eg. img_%02d.BMP) to save raw frames.

->Most codecs are lossy. If you want lossless video file you need to use a lossless codecs (eg. FFMPEG FFV1, Huffman HFYU, Lagarith LAGS, etc...)

->If FFMPEG is enabled, using codec=0; fps=0; you can create an uncompressed (raw) video file.

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




回答3:


Well Thank you a lot.

I thought about a similar way but missed the functions in emgu ( the VideoWriter nor the Capture got a get(CAP_PROB) function, but thanks to you i searched a bit more around and found the CvInvoke.cveVideoCaptureGet function.

Now iam able to write the video as i did before read the Video file with the Capture class and use the functiion above.

//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));

So far so good. When i using LAGS as codec everything works just fine and i get 1397178700,so i can call the constructor with this value instead.

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

But when i pass -1 and choose uncompressed from drop down menu it gives me back 0 as fourCC codec value, but when using 0 as constructor param, it wont record and print 808596553 as value for the used codec

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

Choosing Lagarith Lossless Codec from drop gives me 1397178700 as it should and will work. So any ideas?

PS: Thanks again for your help so far Dan Mašek



来源:https://stackoverflow.com/questions/40821708/how-to-choose-full-frames-uncompressed-as-codec-for-videowriter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!