Convert a Blackmagic Intensity Shuttle USB 3.0 Frame (10bppYUV format) into an OpenCV Mat object

asked 2018-03-06 02:45:37 -0600

I have to work with a Blackmagic Intensity Shuttle USB 3.0 device. I am, therefore, using the DeckLink SDK in order to set up the device and grab frames. I do this with success, establishing the option that allows the device to set himself to its "preferred output mode", that happens to be 1080i59.94 (I don't really care so much about the framerate yet). I obtain properly the IDeckLinkVideoInputFrame object, but I haven't been able to find a proper way to convert it to a Mat object. There seem to be nice ways to create the Mat object from raw frame data when it is 8bpp YUV or RGBA data, but I haven't been able to do it when the frame comes in 10bpp. Any idea or hint?

I need to create a Mat object to incorporate the data grabbed from this device into a pipeline that was developed some time ago, so, unfortunately, stop using OpenCV is not an option. Also, I use OpenCV 3.4.0 on C++11.

Thanks.

edit retag flag offensive close merge delete

Comments

show us, how you grab your frame (code)

also, more information, what exactly is in your 10bit data, please !

berak gravatar imageberak ( 2018-03-06 02:48:51 -0600 )edit

I think you need to create a Mat with your raw data and convert mat object using cvtColor with one of this codes. You have to search YUV2 in last link.

LBerger gravatar imageLBerger ( 2018-03-06 02:54:54 -0600 )edit

The code is around 400 lines of C++, would it be useful? most of it deals with COM and the DeckLink SDK. I can access the raw data no problem, tried what LBerger said, but I can't find any suitable method for 10bpp YUV data. The format is what is given here:

https://imgur.com/6EXpABV

This packed stuff seems to be common in Television/Cinema formats. I don't know if I am confused, but I don't know which one in the list may seem suitable...

Does this one seem the correct one? COLOR_YUV2RGB_UYVY

Studiosi gravatar imageStudiosi ( 2018-03-06 03:45:08 -0600 )edit

ok, not your whole codebase, ofc. just the lines retrieving the data, and the w/h/c information.

berak gravatar imageberak ( 2018-03-06 04:11:12 -0600 )edit

Relevant piece of code (that does not work)

if (pixFmt == BMDPixelFormat::bmdFormat8BitYUV)
            {
                cout << "bmdFormat8BitYUV" << endl;
                void* data;
                if (FAILED(lastArrivedFrame->GetBytes(&data)))
                    return false;
                mat = Mat(lastArrivedFrame->GetHeight(), 
                    lastArrivedFrame->GetWidth(),
                    CV_8UC2, data, lastArrivedFrame->GetRowBytes());
                cvtColor(mat, mat, CV_YUV2BGR_UYVY);
            }
            else if (pixFmt == BMDPixelFormat::bmdFormat8BitBGRA)
            {
                cout << "bmdFormat8BitBGRA" << endl;
            }
            else
            {
                cout << "Other [" << pixFmt << "]" <<endl;
            }
Studiosi gravatar imageStudiosi ( 2018-03-06 06:47:16 -0600 )edit

As I said, it does not work out for two reasons, because it is 10BitYUV and also the conversion I dunno...

Studiosi gravatar imageStudiosi ( 2018-03-06 06:50:42 -0600 )edit

do you know, how many bytes you get ?

i can only guess, but maybe: use

mat = Mat(1, all_bytes_count, CV_8UC1, data);
cvtColor(mat, mat, CV_YUV2BGR_UYVY); // try out others, too, no idea here
mat = mat.reshape(3, lastArrivedFrame->GetHeight())

(also, next time, rather put your code / images into your question, not into comments ...)

berak gravatar imageberak ( 2018-03-06 06:54:35 -0600 )edit