opencv - 用于 RGB 颜色混合的 opencv 中的 3D 矩阵乘法

标签 opencv matrix

我正在尝试在 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_op

This 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

生成的图像看起来不错(只是没有混色)。所以我一定是做错了什么,但我已经接近了。

最佳答案

我在这里看到了几件事:

  1. 为了缩放系数,OpenCV 支持标量乘法,因此您应该直接执行 multiply(rgbMixMat, 1, rgbMixMat, 256); 而不是 rgbMixMat = 256 * rgbMixMat; .

  2. 如果这就是您的全部代码,则说明您没有正确初始化 imData 或为其赋值,因此行 Mat temp = imData.reshape(0, 1); 可能会崩溃。

  3. 假设 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 矩阵

  4. 为什么要转置 temp = temp.t();

  5. 当你写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/

相关文章:

opencv - 显示直方图图openCV

c++ - 没有 OpenGL 的重复 OpenGL 正交投影行为

WPF 矩形变换

python - 将图像转换为二进制文件后,无法在带有matplotlib的笔记本中显示图像

OpenCV 构建对从源构建的 protobuf 的 undefined reference

c++ - 带有 xcode 错误 : Undefined symbols for architecture x86_64: 的 OpenCV

r - 有没有办法在 R 中创建 LaTex 半矩阵?

使用BLAS对整数类型进行矩阵乘法

matlab条件矩阵赋值

c++ - 如何使用像 Farneback 那样的密集光流方法来跟踪稀疏特征?