zoukankan      html  css  js  c++  java
  • RGB HSI HSV HSB HSL

    HSI:色相(hue),饱和度(saturation),亮度(Intensity),这种模型完全对应于RGB模型转化而来,转化也有严格的公式推导得到,网上提供了几种转化公式的表示方法:

    HSV:色相(hue),饱和度(saturation),明度(value),也称HSB(brightness)。

    HSL:色相(hue),饱和度(saturation),亮度(luminance)。

    上面这两种模型各个意义也不完全一样,它们的意义对应于它们各自的建模方式。其中HSV/HSB来自于Lab建模方式并考虑了人眼的影响之后得到的。

    通用的RGB转HSV/HSB公式如下:详细的原理还未弄清楚

      R,G,B的取值范围是[0, Cmax],未作归一化的Cmax的值为255。Chigh = max(R,G,B),Clow = min(R,G,B),Crng = Chigh - Clow

    饱和度:

      if(Chigh > 0) S = Crng / Chigh else S = 0

    明度:

      V = Chigh / Cmax

    色调:

      if(Crng == 0)此时饱和度S == 0,为灰度图,色调因此无定义。

      else

      先将各分量归一化:R' = (Chigh - R) / Crng   G' = (Chigh - G) / Crng   B' = (Chigh - B) / Crng

      基于原始颜色分量中的最大值,计算出一个初步的色调H':

        if(R = Chigh) H' = B' - G' ; else if(G = Chigh) H' = R' - B' + 2; else if(B = Chigh) H' = G' - R' + 4;

      由上式可知H'的取值区间为[-1, 5],通过将其归一化到区间[0, 1]得到最终的色调值:

      if(H' < 0) H = 1/6 * (H' + 6) else H = 1/6 * H'

    三个分量值都位于区间[0, 1]。

    代码如下:来自于JDK java.awt.Color类

        public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
            float hue, saturation, brightness;
            if (hsbvals == null) {
                hsbvals = new float[3];
            }
            int cmax = (r > g) ? r : g;
            if (b > cmax) cmax = b;
            int cmin = (r < g) ? r : g;
            if (b < cmin) cmin = b;

            brightness = ((float) cmax) / 255.0f;
            if (cmax != 0)
                saturation = ((float) (cmax - cmin)) / ((float) cmax);
            else
                saturation = 0;
            if (saturation == 0)
                hue = 0;
            else {
                float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
                float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin));
                float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin));
                if (r == cmax)
                    hue = bluec - greenc;
                else if (g == cmax)
                    hue = 2.0f + redc - bluec;
                else
                    hue = 4.0f + greenc - redc;
                hue = hue / 6.0f;
                if (hue < 0)
                    hue = hue + 1.0f;
            }
            hsbvals[0] = hue;
            hsbvals[1] = saturation;
            hsbvals[2] = brightness;
            return hsbvals;
        }

     

    HSB/HSV转RGB的介绍不给出,直接给出java.awt.Color类中的转换代码

      public static int HSBtoRGB(float hue, float saturation, float brightness) {
            int r = 0, g = 0, b = 0;
            if (saturation == 0) {
                r = g = b = (int) (brightness * 255.0f + 0.5f);
            } else {
                float h = (hue - (float)Math.floor(hue)) * 6.0f;
                float f = h - (float)java.lang.Math.floor(h);
                float p = brightness * (1.0f - saturation);
                float q = brightness * (1.0f - saturation * f);
                float t = brightness * (1.0f - (saturation * (1.0f - f)));
                switch ((int) h) {
                case 0:
                    r = (int) (brightness * 255.0f + 0.5f);
                    g = (int) (t * 255.0f + 0.5f);
                    b = (int) (p * 255.0f + 0.5f);
                    break;
                case 1:
                    r = (int) (q * 255.0f + 0.5f);
                    g = (int) (brightness * 255.0f + 0.5f);
                    b = (int) (p * 255.0f + 0.5f);
                    break;
                case 2:
                    r = (int) (p * 255.0f + 0.5f);
                    g = (int) (brightness * 255.0f + 0.5f);
                    b = (int) (t * 255.0f + 0.5f);
                    break;
                case 3:
                    r = (int) (p * 255.0f + 0.5f);
                    g = (int) (q * 255.0f + 0.5f);
                    b = (int) (brightness * 255.0f + 0.5f);
                    break;
                case 4:
                    r = (int) (t * 255.0f + 0.5f);
                    g = (int) (p * 255.0f + 0.5f);
                    b = (int) (brightness * 255.0f + 0.5f);
                    break;
                case 5:
                    r = (int) (brightness * 255.0f + 0.5f);
                    g = (int) (p * 255.0f + 0.5f);
                    b = (int) (q * 255.0f + 0.5f);
                    break;
                }
            }
            return 0xff000000 | (r << 16) | (g << 8) | (b << 0);
        }
    

    RGB转HSL

    色调:

      同HSV

    亮度:

      L = (Chigh + Clow) / 2

    饱和度:

      if(L == 0) S = 0; else if( 0<L<=0.5 ) S = 0.5 * Crng / L; else if(0.5 < L < 1) S = 0.5 * Crng / (1 - L); else if(L == 1) S = 0;

    	static float[] RGBtoHLS(float R, float G, float B){
    		float cHi = Math.max(R, Math.max(G, B));
    		float cLo = Math.min(R, Math.min(G, B));
    		float cRng = cHi - cLo;
    		//计算亮度L
    		float L = (cHi + cLo) / 2;
    		//计算饱和度S
    		float S = 0;
    		if(0 < L && L < 1){
    			float d = (L <= 0.5f) ? L : (1 - L);
    			S = 0.5f * cRng / d;
    		}
    		
    		//计算色调H
    		float H = 0;
    		if(cRng > 0){
    			float rr = (float)((cHi - R) / cRng);
    			float gg = (float)((cHi - G) / cRng);
    			float bb = (float)((cHi - B) / cRng);
    			
    			float hh = 0;
    			if(R == cHi)hh = bb - gg;
    			else if(G == cHi)hh = rr - bb + 2;
    			else if(B == cHi)hh = gg - rr + 4;
    			if(hh < 0)hh = hh + 6;
    			H = hh / 6;
    		}
    		return new float[]{H, L, S};
    	}
    

     HSL转RGB代码如下:

    	static float[] HLStoRGB(float H, float S, float L){
    		//假设HSL在[0, 1]区间
    		float R = 0;
    		float G = 0;
    		float B = 0;
    		
    		if(L <= 0)R = G = B = 0;
    		else if(L >= 1) R = G = B = 1;
    		else{
    			float hh = (6 * H) % 6;
    			int c1 = (int)hh;
    			float c2 = hh - c1;
    			float d = (L <= 0.5f) ? (S * L) : (S * (1 - L));
    			float w = L + d;
    			float x = L - d;
    			float y = w - (w - x) * c2;
    			float z = w + (w - x) * c2;
    			switch(c1){
    			case 0: R = w; G = z; B = x; break;
    			case 1: R = y; G = w; B = x; break;
    			case 2: R = x; G = w; B = z; break;
    			case 3: R = x; G = y; B = w; break;
    			case 4:	R = z; G = x; B = w; break;
    			case 5: R = w; G = x; B = y; break;
    			}
    		}
    		return new float[]{R, G, B};
    	}
    
  • 相关阅读:
    windows cmd中查看某个命令所在的路径
    linux vi编辑器中,如何通过快捷键上下翻页?
    linux系统中,查看当前系统中,都在监听哪些端口
    下载mysql server安装包的时候,不登录oracle账号,实现下载
    plsql developer中,清除登录历史
    linux环境下,清空history中记录的历史命令
    Linux下搭建hadoop开发环境-超详细
    HDFS架构详解-非官档
    SSH免密码登录配置方法详解
    bin/hdfs dfs命令存在WARN util.NativeCodeLoader问题消除方法
  • 原文地址:https://www.cnblogs.com/fordreamxin/p/4616861.html
Copyright © 2011-2022 走看看