【问题标题】:Accessing elements in a multi-channel OpenCV Mat访问多通道 OpenCV Mat 中的元素
【发布时间】:2015-08-07 23:36:24
【问题描述】:

这是我在stackoverflow上的第一篇文章,所以我希望一切都正确,如果我不这样做,对不起。

我正在编写将单个 RGB 值转换为 CIE L*a*b* 颜色空间的函数的代码。该函数应该采用 3 个浮点数数组(RGB 通道的值在 [0-255] 中),并在输出中给出一个具有 L*a*b* 值的 3 个浮点数数组。为此,我使用了 OpenCV 提供的 cvtColor 函数。

正如the openCV website 所建议的那样,我正在由构造器创建 Mat 结构(cvtColor 需要)。

我的问题是,虽然我认为代码运行正常并执行了转换,但我无法取回 Mat 结构中包含的值。

这是我的代码:

float * rgb2lab(float rgb[3]) {
    // bring input in range [0,1]
    rgb[0] = rgb[0] / 255;
    rgb[1] = rgb[1] / 255;
    rgb[2] = rgb[2] / 255;

    // copy rgb in Mat data structure and check values
    cv::Mat rgb_m(1, 1, CV_32FC3, cv::Scalar(rgb[0], rgb[1], rgb[2]));
    std::cout << "rgb_m = " << std::endl << " " << rgb_m << std::endl;
    cv::Vec3f elem = rgb_m.at<cv::Vec3f>(1, 1);
    float R = elem[0];
    float G = elem[1];
    float B = elem[2];
    printf("RGB =\n [%f, %f, %f]\n", R, G, B);

    // create lab data structure and check values
    cv::Mat lab_m(1, 1, CV_32FC3, cv::Scalar(0, 0, 0));
    std::cout << "lab_m = " << std::endl << " " << lab_m << std::endl;

    // convert
    cv::cvtColor(rgb_m, lab_m, CV_RGB2Lab);

    // check lab value after conversion
    std::cout << "lab_m2 = " << std::endl << " " << lab_m << std::endl;
    cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(1, 1);
    float l = elem2[0];
    float a = elem2[1];
    float b = elem2[2];
    printf("lab =\n [%f, %f, %f]\n", l, a, b);

    // generate the output and return
    static float lab[] = { l, a, b };
    return lab;
}

如您所见,我通过 at 函数从 Mat 结构中提取所有通道,然后从向量中单独访问它们。这在许多地方被提议作为解决方案 (one of them)。

但是如果我运行这段代码(输入向量是 {123,10,200}),在cout 上,我正确地得到了 Mat 结构的输出(从中我得到算法正在正确转换),但正如你所见提取的值是错误的:

rgb_m = 
 [0.48235294, 0.039215688, 0.78431374]
RGB =
 [0.000000, 0.000000, -5758185472.000000]
lab_m = 
 [0, 0, 0]
lab_m2 = 
 [35.198029, 70.120964, -71.303688]
lab =
 [0.000000, 0.000000, 4822177514157213323960797626368.000000]

有人知道我做错了什么吗?

非常感谢您的帮助!

【问题讨论】:

  • 您访问权限正确,但索引错误。矩阵索引从 0 开始,因此要访问第一个元素,您需要类似 rgb_m.at&lt;cv::Vec3f&gt;(0, 0)
  • 问题好像是(1,1),Mat的第一个元素在(0,0),至于vector
  • 是的,你完全正确。我不敢相信我犯了这么愚蠢的错误。由于我看到的所有指南都使用 (1,1) 表示法,我认为这是使用关于索引的“Matlab”约定...谢谢您的回答。

标签: c++ opencv image-processing rgb cielab


【解决方案1】:

cv::Mat 的第一个元素始终位于 (0, 0),因此只需通过 cv::Vec3f elem = rgb_m.at&lt;cv::Vec3f&gt;(0, 0); 纠正 cv::Vec3f elem = rgb_m.at&lt;cv::Vec3f&gt;(1, 1); 和通过 cv::Vec3f elem2 = lab_m.at&lt;cv::Vec3f&gt;(0, 0); 纠正 cv::Vec3f elem2 = lab_m.at&lt;cv::Vec3f&gt;(1, 1);

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多