【问题标题】:Multiplying Mat matrices using reshape, Mat type issue in OpenCV在 OpenCV 中使用 reshape、Mat 类型问题乘以 Mat 矩阵
【发布时间】:2018-07-09 19:11:26
【问题描述】:

我正在尝试实现从 RGB-LMS 和 LMS-RGB 返回的颜色转换,并使用 reshape 进行乘法矩阵,以下问题的答案:Fastest way to apply color matrix to RGB image using OpenCV 3.0?

我的 ori Mat 对象来自具有 3 通道 (RGB) 的图像,我需要将它们与 1 通道 (lms) 的矩阵相乘,看来我的矩阵类型有问题。我已阅读 reshape docs 以及与此问题相关的问题,例如 Issues multiplying Mat matrices,并且我相信我已按照说明进行操作。

这是我的代码:[已更新:转换为平面图像]

void test(const Mat &forreshape, Mat &output, Mat &pic, int rows, int cols)
{
    Mat lms(3, 3, CV_32FC3);
    Mat rgb(3, 3, CV_32FC3);
    Mat intolms(rows, cols, CV_32F);

    lms = (Mat_<float>(3, 3) << 1.4671, 0.1843, 0.0030,
                                3.8671, 27.1554, 3.4557,
                                4.1194, 45.5161 , 17.884 );
    /* switch the order of the matrix according to the BGR order of color on OpenCV */


    Mat transpose = (3, 3, CV_32F, lms).t();  // this will do transpose from matrix lms

    pic     = forreshape.reshape(1, rows*cols);
    Mat flatFloatImage;
    pic.convertTo(flatFloatImage, CV_32F);

    rgb         = flatFloatImag*transpose;
    output      = rgb.reshape(3, cols);
}

我定义了我的 Mat 对象,并使用 convertTo 将其转换为浮点数

Mat ori = imread("ori.png", CV_LOAD_IMAGE_COLOR);
int rows = ori.rows;
int cols = ori.cols;

Mat forreshape;
ori.convertTo(forreshape, CV_32F);

Mat pic(rows, cols, CV_32FC3);
Mat output(rows, cols, CV_32FC3);

错误是:

OpenCV Error: Assertion failed (type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)) , 

所以这是类型问题。

我尝试将所有类型更改为 32FC3 或 32FC1,但似乎不起作用。有什么建议吗?

【问题讨论】:

    标签: c++ opencv image-processing matrix reshape


    【解决方案1】:

    我相信您需要将输入转换为平面图像,然后将它们相乘

    float lms [] = {1.4671, 0.1843, 0.0030,
                                3.8671, 27.1554, 3.4557,
                                4.1194, 45.5161 , 17.884};
    Mat lmsMat(3, 3, CV_32F, lms );
    
    Mat flatImage = ori.reshape(1, ori.rows * ori.cols);
    Mat flatFloatImage;
    flatImage.convertTo(flatFloatImage, CV_32F);
    Mat mixedImage = flatFloatImage * lmsMat;
    Mat output = mixedImage.reshape(3, imData.rows); 
    

    我可能在那里搞砸了 lms 矩阵,但我想你会从这里赶上来的。

    另见3D matrix multiplication in opencv for RGB color mixing

    编辑: 失真的问题是浮点到 8U 转换后溢出。这样就可以了:

    rgb         = flatFloatImage*transpose;
    rgb.convertTo(pic, CV_32S);
    output      = pic.reshape(3, rows)
    

    输出: ;

    我也不确定,但快速的谷歌搜索给了我不同的 LMS see here 矩阵。另请注意,opencv 以 B-G-R 格式而不是 RGB 存储颜色,因此请记录更改您的混合 mtraixes。

    【讨论】:

    • 您好,谢谢!我已经更新了我的代码并看到了你推荐的问题。我想现在我面临着和他一样的问题(图像失真),这里是my result 所以我需要将我的源图像乘以矩阵 lms(转换 RGB-LMS),然后将结果乘以转置矩阵lms 以获取原始 RGB (LMS-RGB)。这就是为什么我需要使用转置。知道为什么会失真吗?
    • 您好,谢谢!是的..实际上从RGB到LMS有几种不同的转换矩阵,根据我们选择的参考。就我而言,我指的是this paper。当然,我知道 BGR 顺序,这就是我切换矩阵行的原因。我可以将我的图像转换为 RGB 并直接使用矩阵或切换矩阵以匹配 BGR 顺序。而且我的代码一定有问题。我无法得到我想要的图像,仍然试图弄清楚。但我知道你的答案是最好的方法。非常感谢!!
    猜你喜欢
    • 2014-01-01
    • 2021-08-11
    • 1970-01-01
    • 2012-02-12
    • 2012-09-04
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多