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

3

6

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

Marchland answered 26/11, 2016 at 18:33 Comment(0)
S
5

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 '
Spiculate answered 26/11, 2016 at 20:53 Comment(1)
Feel free to add a C# sample to this answer.Daltondaltonism
D
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

Dagoba answered 5/9, 2017 at 18:58 Comment(0)
M
1

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

Marchland answered 27/11, 2016 at 21:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.