【问题标题】:3D matrix multiplication in opencv for RGB color mixingopencv中用于RGB颜色混合的3D矩阵乘法
【发布时间】:2012-09-22 12:47:47
【问题描述】:

我正在尝试在 opencv 中执行 RGB 颜色混合操作。我的图像包含在 MxNx3 Mat 中。我想将它与 3x3 矩阵相乘。在 Matlab 中,我执行以下操作: *将图像从 MxNx3 展平为 MNx3 *将MNx3矩阵乘以3x3混色矩阵 *重新整形为 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 错误:输入参数的大小不匹配(操作是 既不是“阵列操作数组”(其中数组具有相同的大小和 相同数量的通道),也不是'array op scalar',也不是'scalar op array') 在 arithm_op,文件 C:/slave/WinI nstallerMegaPack/src/opencv/modules/core/src/arithm.cpp,第 1253 行 在抛出“cv::Exception”实例后调用终止
什么(): C:/slave/WinInstallerMegaPack/src/opencv/modules/core/src/arithm.cpp: 1253:错误:(-209)操作既不是“数组操作数组”(其中 数组具有相同的大小和相同的通道数),也不 'array op scalar',也不是函数 arithm_op 中的'scalar op array'

此应用程序已请求运行时终止它 不寻常的方式。请联系应用程序的支持团队了解更多信息 信息。


更新 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

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

【问题讨论】:

  • 这就是全部代码吗?我没有看到 imData 的任何初始化。
  • 我更新了,这段代码是几个类的一部分。

标签: opencv matrix


【解决方案1】:

我在这里看到了几件事:

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

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

  3. 假设 imData 是 MxNx3(3 通道 Mat),您希望将其重塑为 MNx3(1 通道)。根据documentation,当您编写Mat temp = imData.reshape(0, 1); 时,您是说您希望通道数保持不变,并且行数应该是1。相反,它应该是:

    Mat myData = Mat::ones(100, 100, CV_32FC3); // 100x100x3 matrix

    Mat myDataReshaped = myData.reshape(1, myData.rows*myData.cols); // 10000x3 matrix

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

【讨论】:

  • 感谢您的输入,当您进行 reshape 时,为什么要使用 rows * cols?在文档中,它将此字段列为您要重塑的行数。
  • 如果我不做转置,我会得到一个运行时异常。
  • 这是我不进行转置时遇到的异常:OpenCV 错误:Gemm 中的断言失败 (a_size.width == len),文件 C:/slave/WinI nstallerMegaPack/src/ opencv/modules/core/src/matmul.cpp,第 718 行在抛出 'cv::Exception' what() 实例后终止调用:C:/slave/WinInstallerMegaPack/src/opencv/modules/core/src/matmul。 cpp: 718: error: (-215) a_size.width == len in function gemm 此应用程序已请求运行时以不寻常的方式终止它。请联系应用程序的支持团队了解更多信息。
  • @user1712316 你做 rows * cols 因为你想从 rows x cols x 3(rows*cols) x 3。当您说“将 MxNx3 展平为 MNx3”时,就会发生这种情况。
猜你喜欢
  • 2016-05-12
  • 2013-01-25
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 2021-04-11
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多