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

时间:2012-10-01 16:22:00

标签: opencv matrix

我正在尝试在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错误:输入参数的大小不匹配(操作是   既不是'rray op array'(其中数组具有相同的大小和   相同数量的通道),也不是'array op scalar',也不是'标量运算'   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中的'sca lar 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

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

1 个答案:

答案 0 :(得分:5)

我在这里看到了几件事:

  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通道)。根据{{​​3}},当您编写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);时,这是documentation。你想要矩阵产品,所以你只需做mixData = myDataReshaped * rgbMixMat;(然后重塑那个)。

  6. 修改:如果您不使用转置,则会崩溃,因为您执行了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); 
    }