将像素值归一化到0和1之间

5

我想使用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]
2个回答

8
您可以使用convertTo()方法来进行规范化:
image.convertTo(tempImage, CV_32FC3, 1.f/255);

您正在将代码3传递给convertTo(),可能是作为通道数,但这不是正确的签名。请注意,标准格式与您提供的参数不匹配。

这也会产生一个整数输出。 - tjp
1
你为什么这么说?请尝试使用cv::Mat::at<float>(row,col)方法访问像素。 - Adi Shavit
我正在将一些像素值输出到控制台,以尝试验证转换是否按照我的意图进行。使用 at<float>(r,c) 方法访问这些值给了我期望的结果。谢谢。 - tjp
1
255.5 是打错了吗? - Prof
是的 - 已修正。更改为 1.f/255 - Adi Shavit

1

我使用了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查看发生了什么。希望这可以帮助到你。

1
请编辑您的答案,解释为什么“应该使用CV_32FC1类型”。 - anon
为什么不使用float64? - john k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接