OpenCv creates a 3-channel matrix from a continuous array of data

I would like to create a 3 channel OpenCV Matrix using data allocated elsewhere, where the pixels of each channel are combined, as opposed to data for the OpenCV layout, where data from different channels is interleaved.

Mat outputMat = Mat(dimY, dimX, CV_8UC3, rawData); 
// This works only if rawData interleaves channel data like an OpenCv Mat

      

Is there a way to create an OpenCV Matrix without resorting to the below solution of splitting channels from a temporary mat and copying the correct channel data to the appropriate location?

void createMat(unsigned char *rawData, unsigned int dimX, unsigned int dimY)
{
    Mat outputMat = Mat(dimY, dimX, CV_8UC3);

    // use outputMat to draw some stuff

    Mat channelR = Mat(dimY, dimX, CV_8UC1, rawData);
    Mat channelG = Mat(dimY, dimX, CV_8UC1, rawData + dimX * dimY);
    Mat channelB = Mat(dimY, dimX, CV_8UC1, rawData + 2 * dimX * dimY);

    std::vector<Mat> channels(3);
    split(outputMat, channels);

    channels[2].copyTo(channelR);
    channels[1].copyTo(channelG);
    channels[0].copyTo(channelB);
}

      

I need to do this operation often, so I was wondering if there is a solution that does not require calling functions split()

and copyTo()

every time.

Thank!

enter image description here

+3


source to share


1 answer


You can avoid split

and copyTo

by using merge

directly.

Mat createMat(unsigned char *rawData, unsigned int dimX, unsigned int dimY)
{
    // No need to allocate outputMat here
    Mat outputMat;

    // Build headers on your raw data
    Mat channelR(dimY, dimX, CV_8UC1, rawData);
    Mat channelG(dimY, dimX, CV_8UC1, rawData + dimX * dimY);
    Mat channelB(dimY, dimX, CV_8UC1, rawData + 2 * dimX * dimY);

    // Invert channels, 
    // don't copy data, just the matrix headers
    std::vector<Mat> channels{ channelB, channelG, channelR };

    // Create the output matrix
    merge(channels, outputMat);

    return outputMat;
}

      




I tested several other approaches, but they turned out to be slower. For records only, I thought it would be faster, but the transposition is really heavy:

Mat outputMat(3, dimY*dimX, CV_8UC1, rawData);
Mat tmp = outputMat.t();
outputMat = tmp.reshape(3, dimY);
cvtColor(outputMat, outputMat, COLOR_RGB2BGR);

      

+3


source







All Articles