由于老猿以前没接触过图像处理,在阅读moviepy代码时,对类的有些处理方法代码看不懂是什么含义,为此花了4天时间查阅了大量资料,并加以自己的理解和消化,终于明白了相关处理概念,整理成文供大家参考。
在图像处理过程中,图像的合成操作是使用频率最高的,如图像显示、图像拷贝、图像拼接以及的图层拼合叠加等。 图像合成,其实也就是图像像素颜色的混合。
大多数电脑处理图像都是使用 RGB来表示像素,RGB代表红、绿、蓝三个通道的颜色混合,电脑屏幕上的所有颜色,都由这红色绿色蓝色三种色光按照不同的比例混合而成的。屏幕上的任何一个颜色都可以由一组RGB值来记录和表达。
在电脑中,RGB的所谓“多少”就是指亮度,并使用整数来表示。通常情况下,RGB各有256级亮度,用数字表示为从0、1、2…直到255,因此RGB的总体取值为256³个。
图像的灰度可以认为就是亮度,也就是色彩的深浅程度。所谓灰度色,就是指纯白、纯黑以及两者中的一系列从黑到白的过渡色。在RGB模式中三原色光各有256个级别,灰度是在像素的RGB数值相等的情况下形成的。而RGB数值相等的排列组合是256个,灰度的数量就是256级。其中除了纯白和纯黑以外,还有254种中间过渡色。处理示意256级的表示方法外,灰度也可通过百分比表示,范围从0%到100%。注意这个百分比是以纯黑为基准的百分比。与RGB正好相反,百分比越高颜色越偏黑,百分比越低颜色越偏白。
由于灰度色不包含色相,属于“中立”色,因此它常被用来表示颜色以外的其它信息。比如图像的通道,灰度在其中已经不是作为一种色彩模式存在,而是作为判断通道饱和度的标准。而在图像的蒙板中,灰度又被用作判断透明度的标准。
以下公式中最大值、最小值、中间值等都是以像素的RGB各自的取值为基准的集合来计算的:
色相/色度计算公式
:
色相(单位:°)=原色色相(RGB最大值色相)+(-)(中间值-最小值)*60/(最大值-最小值)
上述公式中,原色色相(RGB最大值色相)是指基色通道最大值色相,R为0°,G为120°,B为240°。正负号取值方法是看中间值色相在最大值的色相基础上,按中间值的定位,顺时针为负、逆时针为正。如RGB分别为150、 40、 80,色相=0°-40*60/110= -338°,实际上就是22°,这是因为R的值最大(150),则原色色相=0°,而中间值为80对应蓝色的色相为240°,从0到240是顺时针,因此为减法。
饱和度计算公式:
饱和度=[(最大值-最小值)/最大值]*100%
亮度计算公式
:
Lightness=(最大值 /255)*100%
明度计算公式
:
明度 = 30%*R+59%*G+11%*B
灰度计算公式
:
灰度=(最大值+最小值)/2
RGBA和ARGB都是RGB(Alpha,Red,Green,Blue)色彩模式附加上Alpha(透明度)通道,常见于32位位图(也即四通道图像)的存储结构,PNG图像是一种典型的4通道图像。RGBA全称是Red Green Blue Alpha,ARGB全称是Alpha Red Green Blue ,二者本质上是一样的,只是存储和编码时,Alpha通道值放在代表像素颜色的4字节前面还是后面的区别,ARGB的Alpha通道值放在前面,RGBA的Alpha通道值放在后面。
Alpha叫A通道,或者叫阿尔法通道,表示每个像素的透明度或不透明度,255表示完全不透明,0表示完全透明,也有些地方使用0到1之间的之间的浮点数值来表示,0代表透明、1代表不透明。对于图像来说,透明就是图像本身不可见,当两个图像文件合成时,透明的文件放置在不透明文件上方时,下面的文件完全没有遮挡而可见。
当一个四通道图像显示时,其最终显示图像的像素RGB是将RGB值和Alpha值(此处值为0-1,如果是0-255,应该除以255)各自相乘的结果RGB值。
当一个带alpha通道的透明图像和一个不带alpha通道的不透明图像进行合成时,可以实现一种半透明效果,它们的处理过程称为阿尔法混色。假设一不透明图像的某个像素颜色是A,另一种透明图像的对应位置颜色是B,那么透过B去看A,看上去的颜色C就是B和A的混合颜色。设B物体的透明度为alpha(取值为0-1,0为完全透明,1为完全不透明),则合成后图像C对应位置像素的RGB值计算公式如下:
R( C )=alpha*R(B)+(1-alpha)*R(A)
G( C )=alpha*G(B)+(1-alpha)*G(A)
B( C )=alpha*B(B)+(1-alpha)*B(A)
两张图像合成时,带alpha通道的图像一般称为源图像(前景),不带alpha通道的图像为背景图像。上面公式即表示:
合成图像的像素显示颜色 =源图像像素颜色 X alpha + 背景图像像素颜色 X (1- alpha)
一般来说四通道图像数据保存的都是ARGB或RGBA,其R、G、B值还没有进行任何透明化处理,但这种格式在图像合成时会存在两个问题:
由于对有Alpha通道的图片进行合成处理时,先要获取原始图像RGB的值,这个原始图像真正的RGB值必须考虑Alpha通道,因此会进行一次计算:源图像像素颜色 X alpha。如果这种计算都在合成时进行处理,性能处理压力就会集中在合成阶段;
在图像合成时,有时需要进行插值处理,即根据两个图像的差异,采用插值计算来生成一个或多个中间图像,这种插值一般都是以RGB值进行插值计算,但带Alpha通道的图像RGB并不是最终显示颜色的RGB,因此这种插值可能效果不理想。
为了解决这个问题,在图像处理过程中引入了预乘 (premultiplied)这个概念,经过预乘处理的图像格式就称为PRGBA。预乘的算式是NewR=OldR*Alpha,Alpha取值为0-1(如果为0-255,除以255即可),保存的数据通常称为(ar,ag,ab,a),这样PRGBA格式的像素四通道值保存了真正展现时的像素RGB值,又保存了Alpha通道的值,既解决了前面说的两个问题,又可以还原原始RGBA数据。
PRGBA这个表示方法,由于预乘后保存的值是整数,会丢失小数点后的数值,很大可能引入误差,特别是RGB值本身很小Alpha很大的情况下,这个误差可能会比较大。