c++opencv

Construct cv::Mat via C++ 1D array


I took over a program, which use 1d array to construct cv::Mat. I'm confuse about it, and I make a demo:

int main()
{
    short data[] = {
        11, 12, 13, 14,
        21, 22, 23, 24,
        31, 32, 33, 34,
        43, 42, 43, 44
    };

    cv::Mat m{ 4, 4, CV_8U, data};

    cv::imwrite("test.png", m);

    return 0;
}

I expect the output is

11 12 13 14
21 22 23 24
31 32 33 34
43 42 43 44

But I open the img in MATLAB:

11  0   12  0
13  0   14  0
21  0   22  0
23  0   24  0

Solution

  • The 3rd parameter in the constructor you used for cv::Mat (CV_8U) specifies the format of the data buffer.

    Your data is an array of short, i.e. each entry is 2 bytes. When you use values small values like you did, it means one of the bytes for each short will be 0.

    When you use this buffer to initialized a cv::Mat of type CV_8U you tell opencv to treat the buffer as containing unsigned chars (1 byte elements). So each short is interpreted as 2 unsigned char bytes.

    This is why you get the zeroes in the output.

    Eaither change the type of the data buffer to unsigned char [], or change the cv::Mat data type to e.g. CV_16S. The 2 should usually match.

    You can do it e.g. like this:

    unsigned char data[] = {
        11, 12, 13, 14,
        21, 22, 23, 24,
        31, 32, 33, 34,
        43, 42, 43, 44
    };
        
    cv::Mat m{ 4, 4, CV_8U, data };
    

    You can see the list of opencv data types here (in the Data types section).