[计算机视觉]入门,光,RGB和HSV转换

我的博客:https://blog.csdn.net/qq_41806966

github地址:https://github.com/1711680493

点我进入github

进军 AI 界

什么是计算机视觉?

计算机视觉是一门研究如何使机器 "看" 的科学,进一步说, 就是指用摄影机和电脑代替人眼对目标进行识别,跟踪和测量等,并进一步做图形处理,使电脑处理成需要的东西.

光和电磁波谱

  • 1666年,牛顿发现,当一束太阳光通过一个玻璃棱镜后,显示的光束不再是白光,而是由一端为紫色而另一端为红色的连续色谱组成.
  • 我们感受到的可见光的彩色范围只占电磁波的一小部分,在波谱的一端是无线电波,其波长是可见波长的十几亿倍,另一端是伽马射线,波长比可见光小几百万倍,
  • 电磁波谱可由波长,频率或能量来描述
    • 波长(λ: lambda) 和频率(v)关系 λ=c/v
    • 其中c是光速(2.998*10^8m/8)
    • 电磁波谱各个分量的能量: E=hv
    • 其中h是普朗克常数

        电磁波谱: 可直接网上搜 "电磁波谱图来了解"
        <---------------------------------------------------------->
    伽马射线    X射线    紫外线    可见光谱    红外线    微波        无线电波
    能量与频率成正比,因此更改频率(更短波长)的电磁现象的每个光子携带更多的能量

彩色模型

  • RGB彩色模型(0-255)

    • 在RGB模型中,每种颜色出现在红(Red),绿(Green),蓝(Blue)的原色光谱成分中.
    • 该模型基于笛卡尔坐标系,在RGB彩色模型中表示的图像由三个分量图像组成,每种原色一幅分量图像,当送入RGB监视器时,这三幅图像在屏幕上混合生成一幅合成的彩色图像.
  • HSV彩色模型

    • 通常用以区别不同颜色特性的是明度,色调和饱和度,明度具体表达了亮度大小的概念;
    • 色调是光波混合中与主波长有关的属性,表示观察者感知的主要颜色,当我们说一个物体是红色,橙色时,指的是色调;
    • 饱和度指的是相对纯净度,或一种颜色混合白光的数量,所加白光越少,饱和度越高,色调与饱和度一起称为色度,因此,颜色可用其明度和色度来表征.
    • HSV(色调,饱和度,明度)彩色模型,正是由这三个分量组成的图像
  • HSV -> RGB 转换公式(转换结果有误差是没有问题的(可以自行四舍五入))

    • 注: hsv的范围 数字后面有°则代表度数
      • 因为hsv模型是一个 圆锥,rgb模型是 立方体
      • 0 <= H <= 360, 0 <= S <= 1, 0 <= V <= 1;
    • 定义参数
      • temp = (h / 60)
      • HH = temp < 0 ? -temp : temp % 6
      • F = (h / 60) - HH
      • P = V * (1 - S)
      • Q = V * (1 - F * S)
      • T = V * (1 - (1 - F) * S)
    • 公式: RR,GG,BB是R,G,B除以255后的结果
      • 格式 结果,条件

            (RR,GG,BB) = {
                (V,T,P),  HH = 0
                (Q,V,P), HH = 1
                (P,V,T),  HH = 2
                (P,Q,V), HH = 3
                (T,P,V),  HH = 4
                (V,P,Q), HH = 5
            }

            (R,G,B) = ((RR + m) * 255, (GG + m) * 255, (BB + m) * 255)

  • RGB -> HSV 转换公式(有一点误差是没问题的 比如少了一个1 或者多了一个1)

The R,G,B values are divided by 255 to change

翻译:这个RGB的值除以255来改变范围从0..255变为0..1(也就是 RGB 的值为 0 到 1)

先定义一些会用到的变量

RR = R / 255        将r,g,b转成 0-1 的形式
GG = G / 255
GG = B / 255
max = max(RR,GG,BB)    max为求括号为获取括号里几个数的最大值
min = min(RR,GG,BB)    min为获取括号里的最小值
△ = max - min    三角形代表差的意思,等于变量

公式:

注意:
△代表max-min,
°代表度数(有些测试工具 h 的值为0-1,所以需要除以360来得到h 的 0-1表示)
下面格式为 结果,条件

H(色调)的公式
                

H = {
    0,△ = 0;
    60° * ((GG - BB) / △) + 0°,max = R && G >= B
    60° * ((GG - BB) / △) + 360°,max = R && G < B
    60° * ((BB - RR) / △) + 120°,max = G;
        也等同于 60° * ((BB - RR) / △ + 2)
    60° * ((RR - GG) / △) + 240°,max = B;
        也等同于 60° * ((RR - GG) / △ + 2)
}

S(饱和度)

S = {
    0,max = 0
    △/max,max≠0
}

V(亮度)
    V = max

Java代码

public static void main(String[] args) {
		int r = 2,g = 223,b = 222;
		ColorType hsv = rgbSwitchHsv(r, g, b);
		System.out.println("rgb 转 hsv(" + hsv.h + "," + hsv.s + "," + hsv.v + ")");
		ColorType rgb = hsvSwitchRgb(hsv.h, hsv.s, hsv.v);
		System.out.println("hsv 转 rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")");
	}

	/**
	 * hsv 转 rgb
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @return
	 */
	private static ColorType hsvSwitchRgb(double h,double s,double v) {
		double temp = h / 60;
		int hh = (int)(temp < 0 ? -temp : temp % 6);
		double f = h / 60 - hh
				,p = v * (1 - s)
				,q = v * (1 - f * s)
				,t = v * (1 - (1 - f) * s);
		double rr = 0,gg = 0,bb = 0;
		switch (hh) {
		case 0:
			rr = v; gg = t; bb = p;
			break;
		case 1:
			rr = q; gg = v; bb = p;
			break;
		case 2:
			rr = p; gg = v; bb = t;
			break;
		case 3:
			rr = p; gg = q; bb = v;
			break;
		case 4:
			rr = t; gg = p; bb = v;
			break;
		case 5:
			rr = v; gg = p; bb = q;
			break;
		}
		rr *= 255;
		gg *= 255;
		bb *= 255;
		return new ColorType((int)rr, (int)gg, (int)bb);
	}
	
	/**
	 * rgb转hsv
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r
	 * @param g
	 * @param b
	 */
	private static ColorType rgbSwitchHsv(int r,int g,int b) {
		double rr = (double)r / 255,gg = (double)g / 255,bb = (double)b / 255;
		double max = rr > gg ? (rr > bb ? rr : bb) : (gg > bb ? gg : bb)
				,min = rr < gg ? (rr < bb ? rr : bb) : (gg < bb ? gg : bb);
		double center = max - min;
		double h = -1;
		if (center == 0) h = 0;
		else if (max == rr && g >= b) h = 60 * ((gg - bb) / center);
		else if (max == rr && g < b) h = 60 * ((gg - bb) / center) + 360;
		else if (max == gg) h = 60 * ((bb - rr) / center + 2);
		else if (max == bb) h = 60 * ((rr - gg) / center + 2);
		double s = max == 0 ? 0 : center / max;
		double v = max;
		return new ColorType(h, s, v);
	}
	public static class ColorType {
		public int r,g,b;
		public double h,s,v;
		public ColorType(int r,int g,int b) {
			this.r = r;
			this.g = g;
			this.b = b;
		}
		public ColorType(double h,double s,double v) {
			this.h = h;
			this.s = s;
			this.v = v;
		}
	}
原创文章 55 获赞 64 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41806966/article/details/105747526