OpenCv создает 3 канала Mat из непрерывного массива данных

Я хотел бы создать 3-канальный мат OpenCV, используя данные, расположенные в другом месте, где пиксели каждого канала находятся вместе, в отличие от данных для матов OpenCV, где данные из разных каналов чередуются.

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

Есть ли способ создать мат OpenCV, не прибегая к приведенному ниже решению разделения каналов от временного мата и копирования данных правого канала в соответствующее местоположение?

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);
}

Мне нужно часто делать эту операцию, поэтому мне было интересно, есть ли решение, которое не включает вызов split() а также copyTo() функционирует каждый раз.

Спасибо!

1 ответ

Решение

Вы можете избежать 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;
}

Я протестировал несколько других подходов, но они оказались медленнее. Просто для записей, я думал, что это будет быстрее, но транспонирование действительно тяжело:

Mat outputMat(3, dimY*dimX, CV_8UC1, rawData);
Mat tmp = outputMat.t();
outputMat = tmp.reshape(3, dimY);
cvtColor(outputMat, outputMat, COLOR_RGB2BGR);
Другие вопросы по тегам