【问题标题】:Normalize pixel values between 0 and 1标准化 0 到 1 之间的像素值
【发布时间】:2013-06-27 14:31:33
【问题描述】:

我希望使用 C++/OpenCV 将图像的像素值标准化为 [0..1] 范围。但是,当我使用 image *= 1./255 或 normalize 函数进行归一化时,像素值会向下舍入为零。我尝试将图像设置为输入CV_32FC3。

下面是我的代码:

  Mat image;
  image = imread(imageLoc, CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH);

  Mat tempImage;

  // (didn't work) tempImage *= 1./255;

  image.convertTo(tempImage, CV_32F, 3);
  normalize(image, tempImage, 0, 1, CV_MINMAX);

  int r = 100;
  int c = 150;

  uchar* ptr = (uchar*)(tempImage.data + r * tempImage.step);
  Vec3f tempVals;
  tempVals.val[0] =  ptr[3*c+1];
  tempVals.val[1] =  ptr[3*c+2];
  tempVals.val[2] =  ptr[3*c+3];
  cout<<" temp image - "<< tempVals << endl;

  uchar* ptr2 = (uchar*)(image.data + r * image.step);
  Vec3f imVals;
  imVals.val[0] =  ptr2[3*c+1];
  imVals.val[1] =  ptr2[3*c+2];
  imVals.val[2] =  ptr2[3*c+3];
  cout<<" image - "<< imVals << endl;

这会在控制台中产生以下输出:

temp image - [0, 0, 0]
image - [90, 78, 60]

【问题讨论】:

    标签: c++ opencv image-processing


    【解决方案1】:

    你可以让convertTo()为你做标准化:

    image.convertTo(tempImage, CV_32FC3, 1.f/255);
    

    您将3 传递给convertTo(),大概是作为通道计数,但那不是the correct signature。

    【讨论】:

    • 这也会产生一个整数输出
    • 你为什么这么说?请尝试使用cv::Mat::at&lt;float&gt;(row,col) 方法访问像素。
    • 我正在向控制台输出一些像素值,以尝试验证转换是否符合我的预期。使用 at(r,c) 访问值的方法给了我预期的结果。谢谢。
    • 255.5 是错字吗?
    • 是的 - 已修复。改为1.f/255
    【解决方案2】:

    我使用了normalize 函数并且它有效(Java):

    Core.normalize(src,dst,0.0,1.0,Core.NORM_MINMAX,CvType.CV_32FC1);
    

    您应该为目标图像使用 32F 深度。我相信这样做的原因是,由于您需要获取十进制值,因此您应该使用非整数 OpenCV 数据类型。根据这个table,浮点类型对应于32F深度。我选择通道数为 1 并且它起作用了; CV_32FC1

    还请记住,它不太可能在图像中发现任何视觉差异。 最后,由于您的图像中可能有数千个像素,您的控制台可能看起来只打印零。但是由于数据量很大,请尝试使用CTRL+F 看看发生了什么。希望这会有所帮助。

    【讨论】:

    • 请edit你的答案解释为什么“你应该使用CV_32FC1类型”。
    • 为什么不使用 float64?
    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 2017-04-10
    • 2018-07-19
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 2019-07-26
    相关资源
    最近更新 更多