【问题标题】:Converting data representation in OpenCV C++在 OpenCV C++ 中转换数据表示
【发布时间】:2014-04-30 07:55:16
【问题描述】:

我已加载图像 (cv::mat),所有像素似乎都存储为无符号字符。我需要将它们转换为 32 位浮点类型,以便执行一些数学运算。 我试过了:

Mat M;
M = imread("path\\to\\image", CV_LOAD_IMAGE_COLOR);   
cvtColor( M, M, CV_RGB2GRAY);       
M.convertTo(M,CV_32F); 

以及像这样初始化:

Mat test = Mat(100,100,CV_32F);

但他们似乎没有做任何事情,数据仍然表示为无符号字符。如何转换 cv::mat 数据表示?

【问题讨论】:

  • 请出示您的代码。
  • M 是否仅包含 1 个频道?如果为 3,请改用 CV_32FC3
  • 我已更新以显示我的代码。如何查看频道数量?
  • 您的代码应该可以正常工作。您如何确定仍然只存在 unsigned char 值??
  • 我猜数据数组总是无符号字符。你可以像.at<float>(row, column)一样访问它们,你应该得到正确的浮动结果。

标签: c++ opencv


【解决方案1】:

图像数据将始终由unsigned char* Mat::data 指向,即使它具有非uchar 格式。您的转换没​​问题,您需要记住的是,要访问您的float 数据,您需要从data 指针cast。一些例子:

1) 访问第i个数据行

float * row_i = M.ptr<float>(i);

2) 访问(i,j) 元素:

float x_ij = M.at<float>(i,j)

或(更有效):

float x_ij = (M.ptr<float>(i))[j]

顺便说一句,您应该在cvtColor 中使用BGR2GRAY 而不是RGB2GRAY

cvtColor( M, M, CV_BGR2GRAY);

【讨论】:

    【解决方案2】:

    我用来在 C++ 中加载灰度图像的代码是:

    cv::Mat matInput;
    {
        cv::Mat matTmp = cv::imread("path\\to\\image", CV_LOAD_IMAGE_GRAYSCALE);
        matTmp.convertTo(matInput, CV_32FC1, 1.0/0xff);
    }
    

    这会将图像加载为灰度,然后将结果转换为在 0.0 和 1.0 之间标准化的 32 位浮点格式(因为图像通常以 0 和 0xff 之间的值存储)。如果您正在使用浮点图像,您可能希望将值标准化为 0.0 和 1.0 之间,convertTo 本身只会更改类型。请记住在将图像写回文件之前乘以 0xff,否则您可能只会得到黑色图像。

    我添加了额外的括号以确保临时矩阵在转换完成后立即超出范围,从而释放内存。如果您在 x64 机器上,我还建议使用 double 代替 (CV_64FC1),我发现计算速度明显更快。

    例如,您还可以执行以下操作:

    double Fitness(cv::Mat& mat1, cv::Mat& mat2)
    {
      cv::Mat matImg1, matImg2;
      if (mat1.type() == CV_8UC1) mat1.convertTo(matImg1, CV_64FC1, 1.0/0xff);
      else matImg1 = mat1;
      if (mat2.type() == CV_8UC1) mat2.convertTo(matImg2, CV_64FC1, 1.0/0xff);
      else matImg2 = mat2;
    
      // Select the region of IMG2 the same size as IMG1
      cv::Mat matReg2(matImg2, cv::Rect(cv::Point(0, 0), matImg1.size()));
    
      // Compute the RMS value
      cv::pow(matImg1 - matReg2, 2.0, matImg1);
      return pow(cv::mean(matImg1)[0], 0.5);
    }
    

    或者只访问单个值(假设为 CV_64FC1):

    matInput.at<double>(0, 0) = 0.5;
    std::cout << matInput.at<double>(1, 2);
    

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多