标准化 0 到 1 之间的像素值
Posted
技术标签:
【中文标题】标准化 0 到 1 之间的像素值【英文标题】:Normalize pixel values between 0 and 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]
【问题讨论】:
【参考方案1】:你可以让convertTo()
为你做标准化:
image.convertTo(tempImage, CV_32FC3, 1.f/255);
您将3
传递给convertTo()
,大概是作为通道计数,但那不是the correct signature。
【讨论】:
这也会产生一个整数输出 你为什么这么说?请尝试使用cv::Mat::at<float>(row,col)
方法访问像素。
我正在向控制台输出一些像素值,以尝试验证转换是否符合我的预期。使用 at1.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?以上是关于标准化 0 到 1 之间的像素值的主要内容,如果未能解决你的问题,请参考以下文章