2017-04-03 25 views
2

3通道垫我想使用其他地方分配的数据以创建一个OpenCV的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()功能每次的解决方案。

谢谢!

enter image description here

+0

'merge(channels,outputMat)'? –

+0

我已经尝试过,但似乎没有工作。正确的数据不会进入正确的渠道。它仍然是交错的。 – locke14

+0

你的问题对我来说并不清楚,你想从OpenCV mat获得'RGB'通道吗? – ZdaR

回答

3

您可以直接使用merge避免splitcopyTo

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); 
+0

'merge(channels,outputMat);'似乎没有使用与'rawData'相同的数据。例如,设置'outputMat.at (0,0)= Vec3b(128,128,128);'不反映在位置'RAWDATA [0]','RAWDATA [dimX * dimY]'的值和'rawData [2 * dimX * dimY]'。我检查,它看起来像'outputMat.ptr <无符号字符>(0)!= rawData' – locke14

+1

1)outputMat'不被反射回来在'rawData'的更改'。数据在使用merge时被深度复制。由于您使用的是与OpenCV不同的布局,因此如果要使用数据,则需要深度复制数据。 2)显然通过'outputMat'指出的数据是从'rawData' ......你需要_interleave_自己的原始数据在'Mat'使用它们不同。 – Miki

+0

这就是我所害怕的。对于我的应用程序,我使用OpenCV绘制一些内容并显示在另一个分配'rawData'的应用程序中。所以,似乎每当我更改'outputMat'的内容时,我都需要对更改进行深层复制以反映在'rawData'中。如果我有较高的刷新率,那么手动__交错数据会有很多开销。如果我理解正确的话,貌似是没有解决方案,我可以做到这一点只有一次,在我的OpenCV的后续变化'outputMat'将在'rawData'自动反映。谢谢回复。没错。@Miki – locke14