• 一般情况下我们都是将RGB图像转化为灰色图,很少将灰色图又转化为RGB图像。... 都知道opencv中有一个函数cvtcolor()中有一个参数cv2.COLOR_GRAY2BGR,它能直接将灰色图变换成RGB图像吗? import nu

           一般情况下我们都是将RGB图像转化为灰色图,很少将灰色图又转化为RGB图像。如果有所需求,将灰色图转化为RGB图像,但是,又发现网上很少有这方面的解答,一下子就会觉得无从下手。我使用opencv-python来解决这个问题。

           都知道opencv中有一个函数cvtcolor()中有一个参数cv2.COLOR_GRAY2BGR,它能直接将灰色图变换成RGB图像吗?

    import numpy as np
    import cv2
    # 首先以灰色读取一张照片
    src = cv2.imread("demo.jpg", 0)
    # 然后用ctvcolor()函数,进行图像变换。
    src_RGB = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
    # 显示图片
    cv2.imshow("input", src)
    cv2.imshow("output", src_RGB)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    显示图片:


    可以看出并没有什么改变的,还是灰色图像。那么怎么办?

            RGB图像中有三个维度的信息,每种颜色相当于一个三维向量,表示法则相当于同一个向量在不同的坐标轴下(即不同的基下)的表示。而将其变为灰度后,只剩下一个维度,相当于将三维向量投影为一维标量一样,是不可能回复为原来的向量的。要想恢复,就必须储存另外两个维度的信息,合在一起就是原先的三维向量,这就是原理。

    那么怎么做?

           我们要将RGB表示转换为gGB表示,也就是用灰度分量g取代蓝色分量R,蓝色分量B和绿色分量G不变。我们可以从gGB计算出红色分量R,因为灰度g=p*R+q*G+t*B(其中p=0.2989,q=0.5870,t=0.1140),于是R=(g-q*G-t*B)/p。于是我们只要保留B和G两个颜色分量,再加上灰度图g,就可以回复原来的RGB图像。同样,我们这里的g是可以随便取代红绿蓝三种分量中的任一分量的。下面进行演示。

    from __future__ import division
    import numpy as np
    import cv2
    src = cv2.imread("C:/Users/12914/Pictures/messi.jpg")
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    # RGB在opencv中存储为BGR的顺序,数据结构为一个3D的numpy.array,索引的顺序是行,列,通道:
    B = src[:,:,0]
    G = src[:,:,1]
    R = src[:,:,2]
    # 灰度g=p*R+q*G+t*B(其中p=0.2989,q=0.5870,t=0.1140),于是B=(g-p*R-q*G)/t。于是我们只要保留R和G两个颜色分量,再加上灰度图g,就可以回复原来的RGB图像。
    g = src_gray[:]
    p = 0.2989; q = 0.5870; t = 0.1140
    B_new = (g-p*R-q*G)/t
    B_new = np.uint8(B_new)
    src_new = np.zeros((src.shape)).astype("uint8")
    src_new[:,:,0] = B_new
    src_new[:,:,1] = G
    src_new[:,:,2] = R
    # 显示图像
    cv2.imshow("input", src)
    cv2.imshow("output", src_gray)
    cv2.imshow("result", src_new)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    图像显示:



    现在就可以看出“result”与“input”图像是一致的了吧。所以,仅通过cvtcolor()函数是没有办法将灰色图直接转化为RGB图像的。


    展开全文
  • 图像处理RGB分离)

    2019-03-08 09:10:27
    图像处理技术(RGB分离) 最近学习了图像处理技术,第一个小工程做的事将一张图片的rgb分离,存为三张图片,就像PS中的RGB通道的三张图片一样。 我们先准备两张24位真彩色图片,一张宽度像素为4的倍数,一张则不是...

    图像处理技术(RGB分离)

    在这里插入图片描述
    最近学习了图像处理技术,第一个小工程做的事将一张图片的rgb分离,存为三张图片,就像PS中的RGB通道的三张图片一样。

    我们先准备两张24位真彩色图片,一张宽度像素为4的倍数,一张则不是。

    我们来看下它的文件头和信息头都储存了什么信息:

    位图文件头BITMAPFILEHEADER
    这是一个结构,其定义如下:

    typedef struct tagBITMAPFILEHEADER {
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
    } BITMAPFILEHEADER;

    这个结构的长度是固定的,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数),各个域的说明如下:
    bfType
    指定文件类型,必须是0x424D,即字符串“BM”,也就是说所有.bmp文件的头两个字节都是“BM”。
    bfSize
    指定文件大小,包括这14个字节。
    bfReserved1,bfReserved2
    为保留字,不用考虑
    bfOffBits
    为从文件头到实际的位图数据的偏移字节数

    位图信息头BITMAPINFOHEADER
    这也是一个结构,其定义如下:

    typedef struct tagBITMAPINFOHEADER{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
    } BITMAPINFOHEADER;

    这个结构的长度是固定的,为40个字节(LONG为32位整数),各个域的说明如下:
    biSize
    指定这个结构的长度,为40。
    biWidth
    指定图象的宽度,单位是像素。
    biHeight
    指定图象的高度,单位是像素。
    biPlanes
    必须是1,不用考虑。
    biBitCount
    指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)(新的.bmp格式支持32位色,这里就不做讨论了)。
    biCompression
    指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定义好的常量)。要说明的是,Windows位图可以采用RLE4,和RLE8的压缩格式,但用的不多。我们今后所讨论的只有第一种不压缩的情况,即biCompression为BI_RGB的情况。
    biSizeImage
    指定实际的位图数据占用的字节数,其实也可以从以下的公式中计算出来:
    biSizeImage=biWidth’ × biHeight
    要注意的是:上述公式中的biWidth’必须是4的整倍数(所以不是biWidth,而是biWidth’,表示大于或等于biWidth的,最接近4的整倍数。举个例子,如果biWidth=240,则biWidth’=240;如果biWidth=241,biWidth’=244)。
    如果biCompression为BI_RGB,则该项可能为零
    biXPelsPerMeter
    指定目标设备的水平分辨率,单位是每米的象素个数,关于分辨率的概念。
    biYPelsPerMeter
    指定目标设备的垂直分辨率,单位同上。
    biClrUsed
    指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2biBitCount。
    biClrImportant
    指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。

    一开始我想将原图的每个像素点取出来,然后将RGB分量取出来分别赋值,这样处理对于宽度为4的倍数的图片是没有问题的。但是到了不是4倍数的图片就出问题了。

    后来了解到图片的读取和储存都是按字节来进行,而且是必须要是4 的倍数,那我们的解决方案就明确了,把所有字节读出来后再赋值。

    那么我们怎么样读出所有的字节来呢?

    if (bmpWidth % 4 != 0) {
    		bmpWidth = (bmpWidth * infoHeader.biBitCount / 8 + 3) / 4 * 4;
    	}
    	else {
    		bmpWidth = bmpWidth * infoHeader.biBitCount / 8;
    	}
    

    利用这个公式转换宽度,再乘以高度就是所有字节的数量了。

    下面附上代码:

    #pragma once
    #include<iostream>
    #include<fstream>
    #include<Windows.h>
    
    using namespace std;
    
    
    
    bool readBmp(char *bmpName) {
    	FILE *fb = fopen(bmpName, "rb");
    	FILE* pfoutr = fopen("r.bmp", "wb");
    	FILE* pfoutg = fopen("g.bmp", "wb");
    	FILE* pfoutb = fopen("b.bmp", "wb");
    	if (fb == 0) {
    		return 0;
    	}
    	BITMAPFILEHEADER fileHeader;
    	BITMAPINFOHEADER infoHeader;
    	int bmpWidth =0;//图像的宽
    	int bmpHeight=0;//图像的高
    	int bmpOffset = 0;
    
    	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fb);
    	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fb);
    
    	bmpHeight = infoHeader.biHeight;
    	bmpWidth = infoHeader.biWidth;
    	bmpOffset = fileHeader.bfOffBits;
    	
    	if (bmpWidth % 4 != 0) {
    		bmpWidth = (bmpWidth * infoHeader.biBitCount / 8 + 3) / 4 * 4;
    	}
    	else {
    		bmpWidth = bmpWidth * infoHeader.biBitCount / 8;
    	}
    	
    	if (infoHeader.biBitCount >= 1) {
    		
    		int size1 = bmpHeight * bmpWidth;
    		BYTE *img = new BYTE[size1];
    		BYTE *img1 = new BYTE[size1];
    		BYTE *img2 = new BYTE[size1];
    		BYTE *img3 = new BYTE[size1];
    		
    		fseek(fb, bmpOffset, 0);
    		fread(img, sizeof(BYTE), size1, fb);
    
    		for (int i = 0;i < bmpHeight ;i++) {
    			for (int j = 0;j < bmpWidth;j++) {
    					switch (j % 3) {
    					case 0:
    						img1[i*bmpWidth + j] = 0;
    						img2[i*bmpWidth + j] = 0;
    						img3[i*bmpWidth + j] = img[i*bmpWidth + j];
    						break;
    					case 1:
    						img1[i*bmpWidth + j] = 0;
    						img2[i*bmpWidth + j] = img[i*bmpWidth + j];
    						img3[i*bmpWidth + j] = 0;
    						break;
    					case 2:
    						img1[i*bmpWidth + j] = img[i*bmpWidth + j];
    						img2[i*bmpWidth + j] = 0;
    						img3[i*bmpWidth + j] = 0;
    						break;
    					}
    				
    				
    			}
    		}
    		fwrite(&fileHeader, sizeof(fileHeader), 1, pfoutr);
    		fwrite(&infoHeader, sizeof(infoHeader), 1, pfoutr);
    		fwrite(img1, sizeof(BYTE), size1, pfoutr);
    		fwrite(&fileHeader, sizeof(fileHeader), 1, pfoutg);
    		fwrite(&infoHeader, sizeof(infoHeader), 1, pfoutg);
    		fwrite(img2, sizeof(BYTE), size1, pfoutg);
    		fwrite(&fileHeader, sizeof(fileHeader), 1, pfoutb);
    		fwrite(&infoHeader, sizeof(infoHeader), 1, pfoutb);
    		fwrite(img3, sizeof(BYTE), size1, pfoutb);
    	}
    
    
    	
    	fclose(fb);
    	fclose(pfoutr);
    	fclose(pfoutg);
    	fclose(pfoutb);
    	return 1;
    }
    
    int main() {
    	char bmpName[] = "sea.bmp";
    	readBmp(bmpName);
    	
    }
    
    
    

    这代码我就是测试用,写代码时要注意规范,提取函数哈!

    原图:
    在这里插入图片描述

    R通道:在这里插入图片描述

    G通道:
    在这里插入图片描述

    展开全文
  • RGB颜色空间 RGB(red,green,blue)颜色空间最常用的用途就是显示器系统,彩色阴极射线管,彩色光栅图形的显示器 都使用R、G、B数值来驱动R、G、B 电子枪发射电子,并分别激发荧光屏上的R、G、B三种颜色的荧光粉发出...

    RGB颜色空间

    RGB(red,green,blue)颜色空间最常用的用途就是显示器系统,彩色阴极射线管,彩色光栅图形的显示器 都使用R、G、B数值来驱动R、G、B 电子枪发射电子,并分别激发荧光屏上的R、G、B三种颜色的荧光粉发出不同亮度的光线,并通过相加混合产生各种颜色;扫描仪也是通过吸收原稿经反射或透射而发送来 的光线中的R、G、B成分,并用它来表示原稿的颜色。RGB色彩空间称为与设备相关的色彩空间,因为不同的扫描仪扫描同一幅图像,会得到不同色彩的图像数据;不同型号的显示器显示同一幅图像,也会有不同 的色彩显示结果。显示器和扫描仪使用的RGB空间与CIE 1931 RGB真实三原色表色系统空间是不同的,后者 是与设备无关的颜色空间。btw:Photoshop的色彩选取器(Color Picker)。可以显示HSB、RGB、LAB和CMYK 色彩空间的每一种颜色的色彩值。

    在计算机技术中使用最广泛的颜色空间是RGB颜色空间,它是一种与人的视觉系统结构密切相关的模型。根据人眼睛的结构,所有的颜色都可以看成三个基本颜色-红色(red)、绿色(green)和蓝色(blue)的不同组合,大部分显示器都采用这种颜色模型。对一幅三通道彩色数字图像对每个图像像素(x,y),需要指出三个矢量分量R、G、B;

    根据美国国家电视制式委员会NTSC制式的标准,当白色的亮度用Y来表示是,它和红基色(R)、绿基色(G)、蓝基色(B)的关系可用如下的方程等式描述:
    在这里插入图片描述

    图1 RGB彩色空间
    在这里插入图片描述

    图2 人视网膜中三种不同视锥细胞的光谱相对敏感性

    RGB对应到显示器的三个刺激值,组成三维正交坐标系统,该系统中任何颜色都落入RGB彩色立方体内,在RGB颜色模型中,黑色在原点处,白色位于离原点最远的角上,灰度级沿着这两点的连线分布,每一个分量图像都是其原色图像。

    RGB颜色空间最大的优点就是适合于显示系统,直观且容易理解。但是对彩色描述上的应用还有以下不足:

    (1) RGB颜色空间利用三个颜色分量的线性组合来表示颜色,因此不同的色彩难以用精确的数值来表示,定量分析困难。

    (2) 在RGB颜色系统中,三个颜色分量之间是高度相关的,即只要亮度改变,三个分量都会相应的改变,如果一个颜色的某一个分量发生了一定程度的改变,那么这颜色很可能也要发生改变。

    (3) RGB颜色空间是一种均匀性较差的颜色空间,人眼对于三个颜色分量的敏感程度是不一样的,如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。

    HSV颜色空间

    HIS(Hue-Intensity-Saturation)颜色空间是图像处理中另外一个常用的颜色空间,它从人的视觉系统出发,用色调(Hue)、饱和度(Saturation或Chroma)和亮度(Intensity或Brightness)来描述颜色。HIS颜色空间可以用图3的圆锥空间模型来描述。其中,色调H由角度表示,其取值范围是 ,其中表示红色,表示黄色,表示绿色,表示蓝色,表示品红色。饱和度S是HIS彩色空间中轴线到彩色点的半径长度,彩色点离轴线的距离越近,表示颜色的白光越多。强度I用轴线方向上的高度表示,圆锥体的轴线描述了灰度级,强度最小值时为黑色,强度最大值时为白色。每个和轴线正交的切面上的点,其强度值都是相等的。

    HSV(hue,saturation,value)颜色空间的模型对应于圆柱坐标系中的一个圆锥形子集,圆锥的顶面对应于V=1. 它包含RGB模型中的R=1,G=1,B=1 三个面,所代表的颜色较亮。色彩H由绕V轴的旋转角给定。红色对应于 角度0° ,绿色对应于角度120°,蓝色对应于角度240°。在HSV颜色模型中,每一种颜色和它的补色相差180° 。 饱和度S取值从0到1,所以圆锥顶面的半径为1。HSV颜色模型所代表的颜色域是CIE色度图的一个子集,这个 模型中饱和度为百分之百的颜色,其纯度一般小于百分之百。在圆锥的顶点(即原点)处,V=0,H和S无定义, 代表黑色。圆锥的顶面中心处S=0,V=1,H无定义,代表白色。从该点到原点代表亮度渐暗的灰色,即具有不同 灰度的灰色。对于这些点,S=0,H的值无定义。可以说,HSV模型中的V轴对应于RGB颜色空间中的主对角线。 在圆锥顶面的圆周上的颜色,V=1,S=1,这种颜色是纯色。HSV模型对应于画家配色的方法。画家用改变色浓和 色深的方法从某种纯色获得不同色调的颜色,在一种纯色中加入白色以改变色浓,加入黑色以改变色深,同时 加入不同比例的白色,黑色即可获得各种不同的色调。前面这一大段我相信看起来也比较费劲,虽然已经尽力准确的去解释了,但我还是建议具体使用请着重数学公式,结合图示理解 ,效果更佳。
    在这里插入图片描述
    在这里插入图片描述

    色相 (Hue):指物体传导或反射的波长。更常见的是以颜色如红色,橘色或绿色来辨识,取 0 到 360 度的数值来衡量。

    饱和度 (Saturation):又称色度,是指色彩的强度或纯度。饱和度代表灰色与色调的比例,并以 0% (灰色) 到 100% (完全饱和) 来衡量。

    亮度 (Intensity):是指颜色的相对明暗度,通常以 0% (黑色) 到 100% (白色) 的百分比来衡量。

    虽然这种描述HIS颜色空间的圆锥模型相当复杂,但却能把色调、亮度和饱和度的变化情形表现得很清楚。通常把色调和饱和度通称为色度,用来表示颜色的类别与深浅程度。由于人的视觉对亮度的敏感程度远强于对颜色浓淡的敏感程度,为了便于颜色处理和识别,经常采用HIS颜色空间,它比RGB颜色空间更符合人的视觉特性。在图像处理和计算机视觉中大量算法都可在HIS颜色空间上使用,它们可以分开处理而且是相互独立的。因此,在HIS颜色空间可以大大简化图像分析和处理的工作量。

    必须说明,HIS颜色空间和RGB颜色空间只是同一物理量的不同表示方法
    在这里插入图片描述

    图3 HIS/HSV彩色空间(一)
    在这里插入图片描述

    图4 HIS/HSV彩色空间(二)

    在HIS颜色空间中进行彩色图像分割有两个优点:

    (1) H和S分量与人感受彩色的方式相似,彩色图像中的每一个均匀性彩色区域都对应一个相一致的色度和饱和度,色度和饱和度能够被用来进行独立于亮度的彩色区域分割。

    (2) I分量与颜色信息无关。

    Lab 颜色空间

    Lab颜色空间是由CIE(国际照明委员会)制定的一种色彩模式。自然界中任何一点色都可以在Lab空间中表达出来,它的色彩空间比RGB空间还要大。另 外,这种模式是以数字化方式来描述人的视觉感应, 与设备无关,所以它弥补了RGB和CMYK模式必须依赖于设备色彩特性的不足。 由于Lab的色彩空间要比RGB模式和CMYK模式的色彩空间大。这就意味着,RGB、CMYK所能描述的色彩信息,在Lab颜色空间中都能得以影身寸。

    Lab颜色空间取坐标Lab,其中L亮度;a的正数代表红色,负端代表绿色;b的正数代表黄色, 负端代表兰色(a,b)有L=116f(y)-16, a=500[f(x/0.982)-f(y)], b=200[f(y)-f(z/1.183 )];其中: f(x)=7.787x+0.138, x〈0.008856; f(x)=(x)1/3,x〉0.008856

    CIE-lab/luv色彩空间

    CIE(Commission International del’Eclairage)国际标准照明委员会于1931年建立了一系列表示可见光谱的颜色空间标准。它有三个基本量,用X、Y、Z表示,通过X、Y、Z能够表示任何一种颜色,X、Y、Z的值能够利用R、G、B线性表示出来,相对于RGB颜色空间,XYZ颜色空间几乎能包含人类能够感觉到的所有颜色,但XYZ颜色空间仍然是一种不均匀的颜色空间。因此在CIE-XYZ颜色空间的基础上又有了CIE-Lab,CIE-Luv等颜色空间。国际照明委员会制定了Lab颜色空间,人类所能感觉到的任何颜色都可以在Lab颜色空间中表示出来,其颜色空间比RGB颜色空间还大,可以直接使用欧几里德距离来衡量两种颜色的差异性。这种模式是以数字化的方式来描述人的视觉感觉,它与显示器的色移、输出设备以及其他设备无关。Lab系统是一个优秀的亮度和彩色分离器,它在图像压缩方面很有用。其中L代表亮度,a的正方向代表红色,负方向代表绿色,b的正方向代表黄色,负方向代表蓝色。Lab颜色空间由XYZ转换而得
    在这里插入图片描述

    图5 CIE-Lab彩色空间

    YUV颜色空间

    在现代彩色电视系统中,通常采用三管彩色摄像机或彩色CCD(点耦合器件)摄像机,它把摄得的彩色图像 信号,经分色、分别放大校正得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y、B-Y, 最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这就是我们常用的YUV色彩空间。 采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量, 那么这样表示的图就是黑白灰度图。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机 的兼容问题,使黑白电视机也能接收彩色信号。根据美国国家电视制式委员会,NTSC制式的标准,当白光的 亮度用Y来表示时,它和红、绿、蓝三色光的关系可用如下式的方程描述:Y=0.3R+0.59G+0.11B 这就是常用 的亮度公式。色差U、V是由B-Y、R-Y按不同比例压缩而成的。如果要由YUV空间转化成RGB空间,只要进行 相反的逆运算即可。与YUV色彩空间类似的还有Lab色彩空间,它也是用亮度和色差来描述色彩分量,其中L为 亮度、a和b分别为各色差分量。

    YUV、YCbCr:该颜色空间主要是基于人眼对亮度比对色度敏感这一特性而来的,将颜色分量和亮度分量分离开来。早期的黑白电视机和彩色电视机的原理也是有此而来的,具体转换公式可以参照ITU标准公式。

    RGB三颜色分量转换为YUV422之后,图像的数据量便减少了1/3,如果是YUV420,则数据量便减少了一半。常用这种转换后的数据进行图像压缩编码。

    也有一些图像边缘增强的算法,在此颜色空间展开。主要是因为色彩信息和亮度信息分离开来了。

    CMYK颜色空间

    CMYK(cyan,magenta,yellow)颜色空间应用于印刷工业,印刷业通过青©、品(M)、黄(Y)三原色油墨的不同 网点面积率的叠印来表现丰富多彩的颜色和阶调,这便是三原色的CMY颜色空间。实际印刷中,一般采用青 ©、品(M)、黄(Y)、黑(BK)四色印刷,在印刷的中间调至暗调增加黑版。当红绿蓝三原色被混合时,会产生 白色,但是当混合蓝绿色、紫红色和黄色三原色时会产生黑色。既然实际用的墨水并不会产生纯正的颜色, 黑色是包括在分开的颜色,而这模型称之为CMYK。CMYK颜色空间是和设备或者是印刷过程相关的,则工艺方法、 油墨的特性、纸张的特性等,不同的条件有不同的印刷结果。所以CMYK颜色空间称为与设备有关的表色空间。 而且,CMYK具有多值性,也就是说对同一种具有相同绝对色度的颜色,在相同的印刷过程前提下,可以用分种 CMYK数字组合来表示和印刷出来。这种特性给颜色管理带来了很多麻烦,同样也给控制带来了很多的灵活性。 在印刷过程中,必然要经过一个分色的过程,所谓分色就是将计算机中使 用的RGB颜色转换成印刷使用的CMYK 颜色。在转换过程中存在着两个复杂的问题,其一是这两个颜色空间在表现颜色的范围上不完全一样,RGB的 色域较大而CMYK则较小,因此就要进行色域压缩;其二是这两个颜色都是和具体的设备相关的,颜色本身没有 绝对性。因此就需要通过一个与设备无关的颜色空间来进行转换,即可以通过以上介绍的XYZ或LAB色空间来 进行转换。

    CMY颜色空间

    CMY是一种颜料混合配色体系

    RGB是一种光混合配色体系C - Cyan青 〈互补色〉 R - Red 红 M - Magenta 品红 〈互补色〉 G - Green 绿 Y - Yellow 黄 〈互补色〉 B - Blue 蓝

    工业印刷中用前一种配色体系(因为是用颜料印刷),但是如果用CMY来配黑色的话很难,往往配出的是一种灰黑色,所以实际应用时还单独有黑色,即K - 黑色,故而工业中实用的印刷使用CMYK体系。

    ·C和R相反,M和G相反,Y和B相反

    其他颜色模型:

    HSL颜色空间HSL(hue,saturation,lightness)颜色空间,这个颜色空间都是用户台式机图形程序的颜色表示, 用六角形锥体表示自己的颜色模型。

    HSB颜色空间HSB(hue,saturation,brightness)颜色空间,这个颜色空间都是用户台式机图形程序的颜色表示, 用六角形锥体表示自己的颜色模型。

    Ycc颜色空间 柯达发明的颜色空间,由于PhotoCd在存储图像的时候要经过一种模式压缩,所以 PhotoCd采用了 Ycc颜色空间,Ycc空间将亮度作由它的主要组件,具有两个 单独的颜色通道,采用Ycc颜色空间 来保存图像,可以节约存储空间。

    XYZ颜色空间国际照明委员会(CIE)在进行了大量正常人视觉测量和统计,1931年建立了"标准色度观察者", 从而奠定了现代CIE标准色度学的定量基础。由于"标准色度观察者"用来标定光谱色时出现负刺激值,计算不便,也不易理解,因此1931年CIE在RGB 系统基础上,改用三个假想的原色X、Y、 Z建立了一个新的色度系统。将它匹配等能光谱的三刺激值,定名为"CIE1931 标准色度观察者 光谱三刺激值",简称为"CIE1931标准色度观察者"。这一系统叫做"CIE1931标准色度系统"或称为" 2° 视场XYZ色度系统"。CIEXYZ颜色空间稍加变换就可得到Yxy色彩空间,其中Y取三刺激值中Y的值, 表示亮度,x、y反映颜色的色度特性。定义如下:在色彩管理中,选择与设备无关的颜色空间是 十分重要的,与设备无关的颜色空间由国际照明委员会(CIE)制定,包括CIEXYZ和CIELAB两个标准。 它们包含了人眼所能辨别的全部颜色。而且,CIEYxy测色制的建立给定量的确定颜色创造了条件。 但是,在这一空间中,两种不同颜色之间的距离值并不能正确地反映人们色彩感觉差别的大小, 也就是说在CIEYxy色厦图中,在 不同的位置不同方向上颜色的宽容量是不同的,这就是Yxy颜色空间 的不均匀性。这一缺陷的存在,使得在Yxy及XYZ空间不能直观地评价颜色。
    红包+折扣,阿里云上云大礼包!
    https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=5wzgtzow
    【全民云计算】 云主机低至4折
    https://promotion.aliyun.com/ntms/act/qwbk.html?userCode=5wzgtzow
    【阿里云新用户】 云通信专享8折
    https://www.aliyun.com/acts/alicomcloud/new-discount?userCode=5wzgtzow
    【商标注册服务】 低至680
    https://tm.aliyun.com/?userCode=5wzgtzow

    展开全文
  • java:读取图像RGB信息

    2016-12-10 10:04:41
    File file=new File(ImageFilePaht);//图片路径 BufferedImage bufIma=ImageIO.read(file);// int width=bufIma.getWidth(); int height=bufIma.getHeight(); int imaRGB[][]=new int...//存放RGB信息数组,重点 //
    File file=new File(ImageFilePaht);//图片路径
    BufferedImage bufIma=ImageIO.read(file);//
    int width=bufIma.getWidth();
    int height=bufIma.getHeight();
    int imaRGB[][]=new int[widht][height];//存放RGB信息数组,重点
    
    //从bufIma读取RGB到数组中
    for(int i=0;i<widht;i++)
        for(int j=0;j<height;j++)
             imaRGB[i][j]=BufIma.getRGB(i,j)&0xFFFFF;//不太懂
    补充:BufferedImage.getRGB(width,height)&0xFFFFF;==>>返回值为  默认 RGB 颜色模型和默认 sRGB 颜色空间中的整数像素

    展开全文
  • RGB数据处理

    2018-08-08 09:27:45
    RGB数据处理 基本概念 分辨率为640*480的图像,其像素点的个数为 widthxheight,即为640x480 = 307200 二值图像 每个像素通过一位来存储即为二值图,取值只有0和1。 灰度图像 在二值图像中加入许多介于黑色...

    RGB数据的处理

    基本概念

    分辨率为640*480的图像,其像素点的个数为 widthxheight,即为640x480 = 307200

    1. 二值图像
      每个像素通过一位来存储即为二值图,取值只有0和1。
    2. 灰度图像
      在二值图像中加入许多介于黑色与白色之间的颜色深度,就构成了灰度图像,就典型的就是256色图,像素取值可以是0到255之间的整数值,那么每个像素占一个字节即8位,灰度图反映的是该图像的亮度信息,灰度级为0~255。占用内存的大小为widthxheight。
    3. RGB24图像
      每个像素占三个字节,对应于Red,Green,Blue三原色值,每个原色的取值是0到 255间的整数。这样的图也称为rgb24,24位真彩色。占用内存的大小为widthxheightx3

    数字图像的表示

    为了表述像素之间的相对和绝对位置,可以把图像看一个原点在左上角的二维坐标系。如下图
    这里写图片描述

    那么一副物理图像就被转化成了数字矩阵,成为了计算机能够处理的对象。
    这里写图片描述

    为M行N列的矩阵,对应的就是Height行width列的矩阵。

    rgb图像在程序中的表示

    • 二维矩阵在C++中映射的就是二维数组。对分辨率为w*h的图像,可以在程序中定义
    unsigned char imag[Height][width]

    来表示。这里的imag是表示指向元素个数为width类型为unsigned char的数组的指针,unsigned char (*img)[width]。

    • 动态分配存放图像数据的二维数组的代码示例如下:
    //指针的指针
    unsigned char** pRGBData = NULL;
    
    //元素个数为Height的unsigned char*数组
    pRGBData = new unsigned char*[Height];
    for (int i=0; i<Height; ++i)
    {
        pRGBData[i] = new unsigned char[width];
    }

    内存结构示意:
    这里写图片描述

    rgb内存存储顺序

    不同于字面的顺序,rgb数据实际的存储顺序为 BGR,BGR

    bmp格式

    windows有一种bmp的图像文件格式,它的图像数据就rgb数据,将rgb封装成bmp格式后可以很方便的进行预览。
    bmp格式介绍

    处理bmp数据涉及到如下两个问题:
    1. 在图像处理中的坐标系的原点是在左上角,而bmp数据坐标的原点在左下角。这里涉及到坐标的转换。
    2. bmp的数据是需要4字节对齐的,如果不为4字节的整数倍,则是会填充数据的,所以计算图像数据大小时就不能简单的通过width*height*像素字节数来计算,可以通过如下宏计算

    // 在计算图像大小时,采用公式:biSizeImage = biWidth' × biHeight。
    // 是biWidth',而不是biWidth,这里的biWidth'必须是4的整倍数,表示
    // 大于或等于biWidth的,离4最近的整倍数。WIDTHBYTES就是用来计算
    // biWidth'
    #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
    //这里计算的是rgb24的行说占的字节数
    int nWidthBytes = WIDTHBYTES(iWidth*24);

    示例程序

    下面实现了一个rgb24处理类,包含如下功能:
    1. 加载rgb24数据文件,这里的rgb数据文件并非指bmp文件,而指只有rgb数据的文件。
    2. 获取/设置指定像素的值。
    3. 获取指定像素的灰度值。
    4. 将rgb24数据文件存成bmp格式文件。
    5. 在rgb24图像上画线。

    #include <stdio.h>
    #include <string>
    #include <Windows.h>
    //#define RGB(r,g,b) ((unsigned long)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
    #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
    
    class CProcessRGB
    {
    public:
        CProcessRGB() :m_pRGBFile(NULL), m_iHeight(0),m_iWidth(0), m_pRGBData(NULL),m_pBmpFile(NULL)
        {
    
        }
    
        ~CProcessRGB()
        {
            if (NULL != m_pRGBFile)
            {
                fclose(m_pRGBFile);
                m_pRGBFile = NULL;
            }
    
            if (NULL != m_pRGBData)
            {
                for (int i = 0; i < m_iHeight; ++i)
                {
                    if (NULL != m_pRGBData[i])
                    {
                        delete[] m_pRGBData[i];
                        m_pRGBData[i] = NULL;
                    }
                }
            }
    
            m_pRGBData = NULL;
        }
    
        int Init(int iWidth,int iHeight,const std::string& strRGBFile)
        {
            m_iWidth = iWidth;
            m_iHeight = iHeight;
            m_pRGBFile = fopen(strRGBFile.c_str(), "rb");
            m_pRGBData = new unsigned char*[iHeight];
    
            // 读取图像数据,WIDTHBYTES宏用于生成每行字节数
            int nWidthBytes = WIDTHBYTES(iWidth*24);
    
            for (int i = 0; i < iHeight; ++i)
            {
                m_pRGBData[i] = new unsigned char[nWidthBytes];
                fread(m_pRGBData[i], nWidthBytes, 1, m_pRGBFile);
            }
    
            return 0;
        }
    
        //获取指定像素点的颜色值
        unsigned long GetPixel(int x, int y)
        {
            unsigned long color = RGB(m_pRGBData[m_iHeight - y - 1][x * 3 + 2],
                m_pRGBData[m_iHeight - y - 1][x * 3 + 1],
                m_pRGBData[m_iHeight - y - 1][x * 3]);
    
            return color;
        }
    
        //设置指定像素的颜色值
        void SetPixel(int x, int y, unsigned long color,unsigned char** pData)
        {
            pData[m_iHeight - y - 1][x * 3] = color;
            pData[m_iHeight - y - 1][x * 3 + 1] = color >> 8;
            pData[m_iHeight - y - 1][x * 3 + 2] = color >> 16;
        }
    
        //计算指定像素点的灰度值
        unsigned char GetGray(int x, int y)
        {
            unsigned long ref = GetPixel(x, y);
            unsigned char r, g, b, byte;
            r = ref;
            g = ref >> 8;
            b = ref >> 16;
    
            if (r == g && r == b)
                return r;
    
            double dGray = (0.30*r + 0.59*g + 0.11*b);
    
            // 灰度化
            byte = (int)dGray;
    
            return byte;
        }
    
        void SaveToBmpFile(const std::string& strBmpFile)
        {
            if (NULL != m_pBmpFile)
            {
                fclose(m_pBmpFile);
                m_pBmpFile = NULL;
            }
    
            m_pBmpFile = fopen(strBmpFile.c_str(), "wb");
    
            BITMAPINFOHEADER InfoHeader = { 0 };
            BuildInfoHeader(m_iWidth, m_iHeight, 24, InfoHeader);
    
            BITMAPFILEHEADER bmfHeader = { 0 };
            BuildFileHeader(m_iWidth, m_iHeight, 24, bmfHeader);
    
            int nWidthBytes = WIDTHBYTES((m_iWidth)*24);
            int iSize = nWidthBytes*m_iHeight;
    
            fwrite(&bmfHeader, sizeof(BITMAPFILEHEADER), 1, m_pBmpFile);
            fwrite(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, m_pBmpFile);
    
            //坐标转换
            for (int i = m_iHeight - 1; i>=0 ; --i)
            {
                fwrite(m_pRGBData[i], nWidthBytes, 1, m_pBmpFile);
            }
        }
    
        //画线 ptStart表示起始点,nLen表示线的长度,nWide表示线的宽度,bHor是横线还是竖线
        void Line(POINT ptStart, int nLen, int nWide, BOOL bHor)
        {
            int i, j;
            DWORD dw = RGB(0, 0, 255);
            if (bHor)
            {
                for (i = ptStart.x; i <= nLen + ptStart.x; i++)
                {
                    for (j = 0; j<nWide; j++)
                    {
                        SetPixel(i, ptStart.y + j, dw, m_pRGBData);
                    }
                }
            }
            else
            {
                for (j = ptStart.y; j <= nLen + ptStart.y; j++)
                {
                    for (i = 0; i<nWide; i++)
                    {
                        SetPixel(ptStart.x + i, j, dw, m_pRGBData);
                    }
                }
            }
        }
    
    
    private:
        void BuildInfoHeader(LONG lWidth, LONG lHeight, WORD wBitCount, BITMAPINFOHEADER &bitmapInfoHeader)
        {
            LONG lWidthStep = (((lWidth * wBitCount) + 31) & (~31)) / 8;
    
            bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
            bitmapInfoHeader.biWidth = lWidth;
            bitmapInfoHeader.biHeight = lHeight;
            bitmapInfoHeader.biPlanes = 0;
            bitmapInfoHeader.biBitCount = wBitCount;
            bitmapInfoHeader.biCompression = BI_RGB;
            bitmapInfoHeader.biSizeImage = lWidthStep * lHeight;
            bitmapInfoHeader.biXPelsPerMeter = 0;
            bitmapInfoHeader.biYPelsPerMeter = 0;
            bitmapInfoHeader.biClrUsed = 0;
            bitmapInfoHeader.biClrImportant = 0;
        }
    
        void BuildFileHeader(LONG lWidth, LONG lHeight, WORD wBitCount, BITMAPFILEHEADER &bitmapFileHeader)
        {
            LONG lWidthStep = (((lWidth * wBitCount) + 31) & (~31)) / 8;
    
            bitmapFileHeader.bfType = ((WORD)('M' << 8) | 'B');  //'BM'
            bitmapFileHeader.bfSize = (DWORD) sizeof(BITMAPFILEHEADER) + (DWORD) sizeof(BITMAPINFOHEADER) + lWidthStep * lHeight;
            bitmapFileHeader.bfReserved1 = 0;
            bitmapFileHeader.bfReserved2 = 0;
            bitmapFileHeader.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + (DWORD) sizeof(BITMAPINFOHEADER);
        }
    
    private:
        //存储RGB内存数据的指针
        unsigned char** m_pRGBData;
        FILE *m_pRGBFile;
        FILE *m_pBmpFile;
        int m_iHeight;
        int m_iWidth;
    };
    
    int main()
    {
        CProcessRGB RGBProcess;
        //读取rgb24图像
        RGBProcess.Init(1280,720,"./preview_rgb24");
    
        //画一条横线
        POINT p1;
        p1.x = 0;
        p1.y = 359;
        RGBProcess.Line(p1, 1279, 3, true);
    
        //画一条竖线
        POINT p2;
        p2.x = 639;
        p2.y = 0;
        RGBProcess.Line(p2, 719, 3, false);
    
        //将rgb24数据存成bmp文件
        RGBProcess.SaveToBmpFile("./preview.bmp");
    }

    运行结果:
    这里写图片描述

    rgb原始数据文件下载
    https://download.csdn.net/download/mo4776/10589099

    展开全文
  • 版权声明:转载时请务必保留以下作者信息和链接作者:陈维(chenweionline@hotmail.com)作者的网站:http://www.chenwei.mobi /** *//** * 取得图像上指定位置像素的 rgb 颜色分量。 * @param image 源...
  • 图像处理笔记 —— 图像的读取及RGB分离等 源码运行平台:matlab2015 一. 图像的读取matlab中图像的读取主要是 **imread** 函数,imread 函数需要输入您要读取的图片的路径,返回一个图像矩阵,如果是彩色图返回一个...
  • RGB-D(深度图像)   深度图像 = 普通的RGB三通道彩色图像 + Depth Map   在3D计算机图形中,Depth Map(深度图)是包含与视点的场景对象的表面的距离有关的信息的图像图像通道。其中,Depth Map 类似于...
  • Bayer图像处理 Bayer是相机内部的原始图片, 一般后缀名为.raw. 很多软件都可以查看, 比如PS. 我们相机拍照下来存储在存储卡上的.jpeg或其它格式的图片, 都是从.raw格式转化 过来的. .raw格式内部的存储方式有...
  • 最近在学习图像处理,想到怎么样才能提一个图片的RGB分量呢?下面简述两种方法,方法一只能显示黑白的提取RGB图像,方法二,显示的是彩色提取RGB。 方法一: 首先通过函数对图片进行读取并显示。 image = ...
  • RAW图像数据RGB

    2017-10-08 20:32:12
    RAW图像数据RGB Bayer是相机内部的原始图片, 一般后缀名为.raw. 很多软件都可以查看, 比如PS. 我们相机拍照下来存储在存储卡上的.jpeg或其它格式的图片, 都是从.raw格式转化 过来的. .raw格式内部的...
  •  最近在arm板子上做一个项目,arm板上采集的图像是YUV格式的,在后续的图像处理中需要用到RGB格式的图像。在网上查了很多YUV转RGB的资料,由于每个人得到的YUV的数据排列格式不一样,所以要找到适合自己工程的代码...
  • 最近在做图像处理,需要将试验得到的数据转化RGB,再显示到界面 顺便学习了如下三个知识点: RGB数据生成BMP位图 YUV 格式与 RGB 格式的相互转换公式总结(C++版) 将RGB数组在内存中压缩JPEG文件 直接上Qt...
  • 采用阈值处理从灰度图像创建索引图像 gray2ind 从灰度图像创建索引图像 ind2gray 从索引图像创建灰度图像 rgb2ind 从RGB图像创建索引图像 ind2rgb 从索引图像创建RGB图像 rgb2gray 从RGB图像
  • 前言:近期有接触到YUV和RGB两种颜色编码格式,稍稍做了个...当我们采集到图像数据后,一般输出的就是YUV格式的数据流,然后再去进行压缩编码等其他步骤来进行数据传输或保存。而最终显示在我们屏幕面前,通常又是...
  • 最近在项目的过程中需要用到 YUV 的 Y通道数据,但是原始数据图像RGB格式,所以自己写了一个RGB2YUV的程序,并且进行优化,对此总结如下。RGB2YUV 原理RGB及YUV是两种不同的颜色空间,具体可以换算关系如下:根据...
  • 颜色空间也称彩色模型(又称彩色空间或彩色系统)它的用途是在某些标准下用通常可接受的方式对彩色加以说明。 本文讲解RGB与HSI、CMYK、YUV的基本概念及转换算法。
  • 为了方便记录,以下名词等价:  1、色彩空间==颜色空间==色域==表示颜色的模型或方法 2、采样方式==(图像)信息元素的记录方式==数据结构中信息的...从而,建模后图像了一堆数据结构(结构体)的集合,现在给这
  • Bayer Pattern to RGB(RAW数据转换成RGB图像的过程) Sensor3彩色数字相机需要3个单色sensor获得彩色图像的R,G,B分量,成本较高。单CCD获得彩色图像的方法是在 CCD表面覆盖1个只含红、绿、蓝3色的马赛克滤镜,对...
1 2 3 4 5 ... 20
收藏数 59,861
精华内容 23,944