OpenCV cvtColor CV_BGR2HSV CV_32FC3 饱和度范围
OpenCV cvtColor CV_BGR2HSV CV_32FC3 Saturation Range
我正在尝试在 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);
当您将图像从 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)
就是你想要的。
我正在尝试在 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);
当您将图像从 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)
就是你想要的。