我试图在OpenCV 3.2中为材料构建直方图,但我对HSV范围感到困惑 - 它们似乎与文档不匹配,或者我接近错误。
// cv::Mat bgrPhoto contains a test image
cv::Mat3f hsvPhoto;
bgrPhoto.convertTo(hsvPhoto, CV_32FC3);
cv::cvtColor(hsvPhoto, hsvPhoto, CV_BGR2HSV, CV_32FC3);
std::vector<cv::Mat1f> hsvChannels;
cv::split(hsvPhoto, hsvChannels);
// Documentation [0.0, 1.0]: measured here Hue to 360.0, Sat to 1.0, Val to 255.0
double minHue, maxHue, minSat, maxSat, minVal, maxVal;
cv::minMaxIdx(hsvChannels[0], &minHue, &maxHue, 0, 0);
cv::minMaxIdx(hsvChannels[1], &minSat, &maxSat, 0, 0);
cv::minMaxIdx(hsvChannels[2], &minVal, &maxVal, 0, 0);
答案 0 :(得分:2)
将图像从8位转换为32位时,未将值从[0,255]缩放到[0,1]。 convertTo()
只是转换类型;它默认不重新调整值。这会影响您的输出,因为从docs for color conversion from BGR to HSV开始,V
只会设置为max(B, G, R)
(最多可达255个数字)。您会注意到,在cvtColor()
的文档中,它表示对于8位和16位图像,它们被缩放以适合[0,1]范围;但不适用于浮动图像。但是,H
频道和S
频道仍会缩放到正确的范围,因为它们使用V
来缩放图片。
执行bgrPhoto.convertTo(hsvPhoto, CV_32FC3)
时,需要除以255将值设置为[0,1]。如果您查看docs for convertTo()
,您会注意到可以设置第三个位置参数,这是一个比例因子。正如文档所述,简单地使用bgrPhoto.convertTo(hsvPhoto, CV_32FC3, 1.0/255.0)
将按该因子缩放每个像素值。
此外,Miki在对OP的评论中的观点完全由我滑落,但这是一个很好的收获;检查docs for cvtColor()
;第四个参数是目标渠道数的参数,而不是dtype
,因此cv::cvtColor(hsvPhoto, hsvPhoto, CV_BGR2HSV)
就是您想要的。