我正在尝试在 opencv 中执行 RGB 颜色混合操作。我的图像包含在 MxNx3 垫子中。我想将其与 3x3 矩阵相乘。在 Matlab 中,我执行以下操作: *将图像从 MxNx3 展平为 MNx3 *将 MNx3 矩阵乘以 3x3 颜色混合矩阵 * reshape 回 MxNx3
在 Opencv 中我想做以下事情:
void RGBMixing::mixColors(Mat &imData, Mat &rgbMixData)
{
float rgbmix[] = {1.4237, -0.12364, -0.30003, -0.65221, 2.1936, -0.54141, -0.38854, -0.47458, 1.8631};
Mat rgbMixMat(3, 3, CV_32F, rgbmix);
// Scale the coefficents
multiply(rgbMixMat, 1, rgbMixMat, 256);
Mat temp = imData.reshape(0, 1);
temp = temp.t();
multiply(temp, rgbMixMat, rgbMixData);
}
这会编译但会产生异常:
OpenCV Error: Sizes of input arguments do not match (The operation is neither 'a rray op array' (where arrays have the same size and the same number of channels) , nor 'array op scalar', nor 'scalar op array') in arithm_op, file C:/slave/WinI nstallerMegaPack/src/opencv/modules/core/src/arithm.cpp, line 1253 terminate called after throwing an instance of 'cv::Exception'
what(): C:/slave/WinInstallerMegaPack/src/opencv/modules/core/src/arithm.cpp: 1253: error: (-209) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'sca lar op array' in function arithm_opThis application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
更新 1:
这是似乎有效的代码:
void RGBMixing::mixColors(Mat &imData, Mat&rgbMixData)
{
Size tempSize;
uint32_t channels;
float rgbmix[] = {1.4237, -0.12364, -0.30003, -0.65221, 2.1936, -0.54141, -0.38854, -0.47458, 1.8631};
Mat rgbMixMat(3, 3, CV_32F, rgbmix);
Mat flatImage = imData.reshape(1, 3);
tempSize = flatImage.size();
channels = flatImage.channels();
cout << "temp channels: " << channels << " Size: " << tempSize.width << " x " << tempSize.height << endl;
Mat flatFloatImage;
flatImage.convertTo(flatFloatImage, CV_32F);
Mat mixedImage = flatFloatImage.t() * rgbMixMat;
mixedImage = mixedImage.t();
rgbMixData = mixedImage.reshape(3, 1944);
channels = rgbMixData.channels();
tempSize = rgbMixData.size();
cout << "temp channels: " << channels << " Size: " << tempSize.width << " x " << tempSize.height << endl;
}
但是生成的图像失真了。如果我跳过两个矩阵的乘法而只是分配
mixedImage = flatFloatImage
生成的图像看起来不错(只是没有混色)。所以我一定是做错了什么,但我已经接近了。
最佳答案
我在这里看到了几件事:
为了缩放系数,OpenCV 支持标量乘法,因此您应该直接执行
multiply(rgbMixMat, 1, rgbMixMat, 256);
而不是rgbMixMat = 256 * rgbMixMat;
.如果这就是您的全部代码,则说明您没有正确初始化
imData
或为其赋值,因此行Mat temp = imData.reshape(0, 1);
可能会崩溃。假设
imData
是 MxNx3(3 channel 垫),您想要将其 reshape 为 MNx3(1 channel )。根据documentation ,当您编写Mat temp = imData.reshape(0, 1);
时,您是在说您希望 channel 数保持不变,并且该行应该为 1。相反,它应该是:Mat myData = Mat::ones(100, 100, CV_32FC3);//100x100x3 矩阵
Mat myDataReshaped = myData.reshape(1, myData.rows*myData.cols);//10000x3 矩阵
为什么要转置
temp = temp.t();
?当你写
multiply(temp, rgbMixMat, mixData);
时,这是per-element product .您需要矩阵乘积,因此只需执行mixData = myDataReshaped * rgbMixMat;
(然后对其进行整形)。
编辑:如果您不使用转置,它会崩溃,因为您执行的是 imData.reshape(1, 3);
而不是 imData.reshape (1, imData.rows);
尝试
void RGBMixing::mixColors(Mat &imData, Mat&rgbMixData)
{
Size tempSize;
uint32_t channels;
float rgbmix[] = {1.4237, -0.12364, -0.30003, -0.65221, 2.1936, -0.54141, -0.38854, -0.47458, 1.8631};
Mat rgbMixMat(3, 3, CV_32F, rgbmix);
Mat flatImage = imData.reshape(1, imData.rows*imData.cols);
Mat flatFloatImage;
flatImage.convertTo(flatFloatImage, CV_32F);
Mat mixedImage = flatFloatImage * rgbMixMat;
rgbMixData = mixedImage.reshape(3, imData.rows);
}
关于opencv - 用于 RGB 颜色混合的 opencv 中的 3D 矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12677188/