HSV是对RGB色彩空间中点的两种有关系的表示,它们尝试描述比 RGB 更准确的感知颜色联系,并仍保持在计算上简单。
HSV表示hue(色度)、saturation(饱和度)、value(色调) 。
HSV 把颜色描述在圆柱体内的点,这个圆柱的中心轴取值为自底部的黑色到顶部的白色而在它们中间是的灰色,绕这个轴的角度对应于“色相”,到这个轴的距离对应于“饱和度”,而沿着这个轴的距离对应于“亮度”,“色调”或“明度”。
设 (r,g,b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设max等价于r,g和b中的最大者。设min等于这些值中的最小者。这里的h∈ [0, 360)是角度的色相角,而s,v∈ [0,1] 是饱和度和亮度,计算为:
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; // vdelta = max - min;if (max != 0)S = delta / max *100; // selse{// r = g = b = 0 // s = 0, v is undefinedS = 0;H = 0;return;}if (delta == 0) {H = 0;return;}else if (R == max){if (G >= B)H = (G - B) / delta; // between yellow & magentaelseH = (G - B) / delta + 6.0;}else if (G == max)H = 2.0 + (B - R) / delta; // between cyan & yellowelse if (B == max)H = 4.0 + (R - G) / delta; // between magenta & cyanH *= 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;}