c++实现RGB色彩空间转换到HSV色彩空间

 HSV是对RGB色彩空间中点的两种有关系的表示,它们尝试描述比 RGB 更准确的感知颜色联系,并仍保持在计算上简单。

HSV表示 hue(色度)、saturation(饱和度)、value(色调) 。

HSV 把颜色描述在圆柱体内的点,这个圆柱的中心轴取值为自底部的黑色到顶部的白色而在它们中间是的灰色,绕这个轴的角度对应于“色相”,到这个轴的距离对应于“饱和度”,而沿着这个轴的距离对应于“亮度”,“色调”或“明度”。

The conical representation of the HSV model; Wikipedia image.

设 (rgb) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 rg 和 b 中的最大者。设 min 等于这些值中的最小者。这里的 h ∈ [0, 360)是角度的色相角,而 s, v∈ [0,1] 是饱和度和亮度,计算为:

h =\begin{cases}0^\circ & \mbox{if } max = min \\60^\circ \times \frac{g - b}{max - min} + 0^\circ,   & \mbox{if } max = r \mbox{ and } g \ge b \\60^\circ \times \frac{g - b}{max - min} + 360^\circ,   & \mbox{if } max = r \mbox{ and } g < b \\60^\circ \times \frac{b - r}{max - min} + 120^\circ, & \mbox{if } max = g \\60^\circ \times \frac{r - g}{max - min} + 240^\circ, & \mbox{if } max = b\end{cases}

s = \begin{cases}0, & \mbox{if } max = 0 \\\frac{max - min}{max} = 1 - \frac{min}{max}, & \mbox{otherwise}\end{cases}

v = max \,
h 的值通常规范化到位于 0 到 360°之间。而 h = 0 用于 max = min 的(就是灰色)时候而不是留下 h 未定义。

#include<opencv2/opencv.hpp>
#include<iostream>
#include<time.h>
#include<string>
#include<vector>
using namespace std;
using namespace cv;

void Rgb2Hsv(float R, float G, float B, float& H, float& S, float&V)
{
	// r,g,b values are from 0 to 1
	// h = [0,360], s = [0,1], v = [0,1]
	// if s == 0, then h = -1 (undefined)
	float min, max, delta, tmp;
	tmp = R>G ? G : R;
	min = tmp>B ? B : tmp;
	tmp = R>G ? R : G;
	max = tmp>B ? tmp : B;
	V = max / 255 * 100; // v
	delta = max - min;
	if (max != 0)
		S = delta / max *100; // s
	else
	{
		// r = g = b = 0 // s = 0, v is undefined
		S = 0;
		H = 0;
		return;
	}
	if (delta == 0) 
	{
		H = 0;
		return;
	}
	else if (R == max)
	{
		if (G >= B)
			H = (G - B) / delta; // between yellow & magenta
		else
			H = (G - B) / delta + 6.0;
	}
	else if (G == max)
		H = 2.0 + (B - R) / delta; // between cyan & yellow
	else if (B == max)
		H = 4.0 + (R - G) / delta; // between magenta & cyan
	
	H *= 60.0; // degrees
	
}
int main()
{
	Mat srcImage = imread(imagename,1);
	
	if (!srcImage.data)
		return 0;
	
	int row = srcImage.rows;
	int col = srcImage.cols;
	Mat hsvimg= Mat(row, col ,CV_8UC3);

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			float b = srcImage.at<Vec3b>(i, j)[0];
			float g = srcImage.at<Vec3b>(i, j)[1];
			float r = srcImage.at<Vec3b>(i, j)[2];
			float h, s, v;
			
			Rgb2Hsv(r, g, b, h, s, v);
			hsvimg.at<Vec3b>(i, j)[0] = h;//h数值若大于255会自动减去255,推荐在ImageWatch模式下查看结果
			hsvimg.at<Vec3b>(i, j)[1] = s;
			hsvimg.at<Vec3b>(i, j)[2] = v;
		}
	}

	waitKey(0);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值