OpenCv从连续数据数组创建3通道Mat

loc*_*e14 6 c++ opencv image-processing mat opencv-mat

我想使用分配给其他位置的数据(每个通道的像素在一起)来创建OpenCV 3通道Mat,这不同于OpenCV Mat的数据,其中来自不同通道的数据是交错的。

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

有没有一种方法可以创建OpenCV Mat,而不必采用以下从临时Mat分割通道并将正确的通道数据复制到相应位置的解决方案?

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);
}
Run Code Online (Sandbox Code Playgroud)

我需要经常执行此操作,因此我想知道是否有一种解决方案不涉及每次都调用split()and copyTo()函数。

谢谢!

在此处输入图片说明

Mik*_*iki 8

您可以避免split和直接copyTo使用merge

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;
}
Run Code Online (Sandbox Code Playgroud)

我测试了其他一些方法,但它们的速度较慢。只是为了记录,我认为这会更快,但转置真的很重:

Mat outputMat(3, dimY*dimX, CV_8UC1, rawData);
Mat tmp = outputMat.t();
outputMat = tmp.reshape(3, dimY);
cvtColor(outputMat, outputMat, COLOR_RGB2BGR);
Run Code Online (Sandbox Code Playgroud)