Fei
Fei

Reputation: 1207

Write 16-bit video with OpenCV

Maybe this is somehow obvious, but I'm still a newbie... ^^"

I use OpenCV to save some images to a video-file. I have 16-bit grayscale images and I found out that cvWriteFrame can only handle 8-bit images. Since I need to process the video later in another context and for that purpose I can't afford the information loss, I'm trying to find a way to save my 16-bit images to videos.

I tried every CV_FOURCC from this documentation. But I'm not sure if it's really a codec problem.

PS: I know it's possible to save them as separate 16-bit image-files, but I find the video solution cleaner.

Upvotes: 1

Views: 7672

Answers (5)

Daniel Konečný
Daniel Konečný

Reputation: 68

Since OpenCV 4.7.0, VideoWriter supports 16-bit grayscale videos.

Short C++ example of the VideoWriter definition with some typical parameters:

#include <opencv2/videoio.hpp>

cv::VideoWriter video;
Size frameSize = cv::Size(1920, 1080);
double fps = 25.0;
video.open(
    "video.mkv", 
    cv::CAP_FFMPEG, 
    cv::VideoWriter::fourcc('F', 'F', 'V', '1'), 
    fps, 
    frameSize, 
    {
        cv::VideoWriterProperties::VIDEOWRITER_PROP_DEPTH, CV_16UC1, 
        cv::VideoWriterProperties::VIDEOWRITER_PROP_IS_COLOR, false
    }
);

If you're looking for a Python alternative with a little bit more explanation, see this answer.

Upvotes: 1

David
David

Reputation: 1

A work around could be to record two 8-bit grayscale videos at the same time. The first one can use the first 8 bits of the 16-bit number as pixels and the other use the last 8 bits.

Another option would be to record a colored image and in a similar fashion set the blue channel to be the first 8-bits and the green channel to the last 8-bits. You can just ignore the red channel maybe set it to 0.

You can then play back the two or single color videos in synch and manipulate them back into your original 16-bit video.

Upvotes: 0

shawndfernandes
shawndfernandes

Reputation: 117

OPencv should support 16 bit FFMPEG as part of #12284.

https://github.com/opencv/opencv/pull/12284

Mat frame, frame_split[3];
VideoWriter 8_bit_vid,16_bit_vid;


//for lossless, use 'F''F''V''1', for lossy with good compression, //'X''2''6''4' 

//For 8bit writing

8_bit_vid.open("8_bit_video.avi",('F','F','V','1'),30,[rows,cols],true);

frame_split[0]= Mat Red_channel([rows,cols],CV8_UC1);
frame_split[1]= Mat Green_channel([rows,cols],CV8_UC1);
frame_split[2]= Mat Blue_channel([rows,cols],CV8_UC1);

merge(frame_split,3,frame);

8_bit_vid.write(frame);
8_bit_vid.release();



//For 16bit writing

16_bit_vid.open("16_bit_video.avi",('F','F','V','1'),30,[rows,cols],true);

frame_split[0]= Mat Red_channel([rows,cols],CV16_UC1);
frame_split[1]= Mat Green_channel([rows,cols],CV16_UC1);
frame_split[2]= Mat Blue_channel([rows,cols],CV16_UC1);

merge(frame_split,3,frame);

16_bit_vid.write(frame);
16_bit_vid.release();

Hope this helps

Upvotes: 2

james
james

Reputation: 1155

How about writing the raw image data without compression or formatting using simple file I/O operations? I'm sure this will give you whatever bits image file you want:)

Upvotes: 0

Michal Kottman
Michal Kottman

Reputation: 16753

I am not aware of a codec which supports 16-bit grayscale images, but I only use OpenCV ffmpeg support, so I could be wrong. This thread seems to support my theory that ffmpeg does not do 16-bit video (there is one message stating it does, but is inaccessible).

Upvotes: 0

Related Questions