BGR 到 HSV 转换中的意外量化
Accidental quantization in BGR to HSV conversion
我正在尝试将 BGR 图像转换为 HSV。当我写出转换的 H 通道时,它有一个奇怪的块状结构,我猜这意味着一些东西在过程中意外地被量化了。我尝试先将我的 BGR unsigned char 图像转换为 float,但结果是一样的。这是我的代码:
// STL
#include <iostream>
// OpenCV
#include <opencv2/opencv.hpp>
void Float(const std::string& inputFilename)
{
cv::Mat image = cv::imread(inputFilename, CV_LOAD_IMAGE_COLOR); // Loads as BGR
cv::Mat floatImage;
image.convertTo(floatImage, CV_32FC3);
cv::Mat hsvImage;
cv::cvtColor(floatImage, hsvImage, CV_BGR2HSV);
std::vector<cv::Mat> hsvChannels;
cv::split(hsvImage, hsvChannels);
cv::imwrite("h_float.png", hsvChannels[0]);
}
void Original(const std::string& inputFilename)
{
cv::Mat image = cv::imread(inputFilename, CV_LOAD_IMAGE_COLOR); // Loads as BGR
cv::Mat hsvImage;
cv::cvtColor(image, hsvImage, CV_BGR2HSV);
std::vector<cv::Mat> hsvChannels;
cv::split(hsvImage, hsvChannels);
cv::imwrite("h_original.png", hsvChannels[0]);
}
int main(int argc, char* argv[])
{
std::string inputFilename = argv[1];
Original(inputFilename);
Float(inputFilename);
return EXIT_SUCCESS;
}
这是输入:
和输出(h_original.png):
和输出(h_float.png):
关于我在这里做错了什么有什么建议吗?
你做的每件事都是正确的。我在我的机器上试过你的图像并得到了相同的结果。我认为这个结果是由于您的图像的颜色范围较低。这是 HSV 的 3 个通道的结果。 H 和 S 都遇到了这个问题。然而,V是光滑的,因为它是关于光线条件而不是颜色。
编辑:
为了使我的观点更清楚,请查看此图像和使用相同代码的输出:
另一个编辑(黑色问题):
在 HSV
中:if V=0 then it is black
不管其余的 S
和 H
是什么。
所以要检查颜色是否为黑色,您只需检查 V 组件,如果检查其他组件则没有任何意义。
数学证明:
C = V × S
X = C × (1 - |(H / 60º) mod 2 - 1|)
m = V - C
很明显,当 V=0
和 H,S
是什么时,我们将有:
C=0 , X=0
导致 R,G,B=(0,0,0)
我正在尝试将 BGR 图像转换为 HSV。当我写出转换的 H 通道时,它有一个奇怪的块状结构,我猜这意味着一些东西在过程中意外地被量化了。我尝试先将我的 BGR unsigned char 图像转换为 float,但结果是一样的。这是我的代码:
// STL
#include <iostream>
// OpenCV
#include <opencv2/opencv.hpp>
void Float(const std::string& inputFilename)
{
cv::Mat image = cv::imread(inputFilename, CV_LOAD_IMAGE_COLOR); // Loads as BGR
cv::Mat floatImage;
image.convertTo(floatImage, CV_32FC3);
cv::Mat hsvImage;
cv::cvtColor(floatImage, hsvImage, CV_BGR2HSV);
std::vector<cv::Mat> hsvChannels;
cv::split(hsvImage, hsvChannels);
cv::imwrite("h_float.png", hsvChannels[0]);
}
void Original(const std::string& inputFilename)
{
cv::Mat image = cv::imread(inputFilename, CV_LOAD_IMAGE_COLOR); // Loads as BGR
cv::Mat hsvImage;
cv::cvtColor(image, hsvImage, CV_BGR2HSV);
std::vector<cv::Mat> hsvChannels;
cv::split(hsvImage, hsvChannels);
cv::imwrite("h_original.png", hsvChannels[0]);
}
int main(int argc, char* argv[])
{
std::string inputFilename = argv[1];
Original(inputFilename);
Float(inputFilename);
return EXIT_SUCCESS;
}
这是输入:
和输出(h_original.png):
和输出(h_float.png):
关于我在这里做错了什么有什么建议吗?
你做的每件事都是正确的。我在我的机器上试过你的图像并得到了相同的结果。我认为这个结果是由于您的图像的颜色范围较低。这是 HSV 的 3 个通道的结果。 H 和 S 都遇到了这个问题。然而,V是光滑的,因为它是关于光线条件而不是颜色。
编辑:
为了使我的观点更清楚,请查看此图像和使用相同代码的输出:
另一个编辑(黑色问题):
在 HSV
中:if V=0 then it is black
不管其余的 S
和 H
是什么。
所以要检查颜色是否为黑色,您只需检查 V 组件,如果检查其他组件则没有任何意义。
数学证明:
C = V × S
X = C × (1 - |(H / 60º) mod 2 - 1|)
m = V - C
很明显,当 V=0
和 H,S
是什么时,我们将有:
C=0 , X=0
导致 R,G,B=(0,0,0)