YCbCr色彩空间
色彩模型vs色彩空间 要解开YCbCr色彩空间这个结,色彩模型(color model)和色彩空间(color space)的区别必须要理解。简单来说两者的关系就像设计与实现之间的关系,针对同一种色彩模型可以有多种不同的实现。比如最常见的RGB色彩模型是根据人的眼睛是通过识别红绿蓝三元色来识别所有颜色的原理进行设计的,可是实际应用的时候我们需要把这个设计予以实现,于是就出现了Adobe RGB、sRGB、ProPhoto RGB等不同版本针对RGB色彩模型实现的色彩空间。
回到YCbCr色彩空间,既然说它是色彩空间那它肯定有一个对应的色彩模型,是什么呢?我想说RGB色彩模型。不要着急,可能这里有点儿颠覆你的三观,但是我这么说是有原因的。YCbCr其实是YUV的一个特例,Y表示的是亮度,U表示的蓝色分量的色差(color difference),V表示的是绿色分量的色差(听着有点儿像RGB不是吗)。YUV与RGB的关系其实就是一个线性转换的关系,所以说YUV其实是对RGB的一种再编码,也就是没有RGB就没有YUV,那显示(输出)的时候自然也需要对YUV进行解码生成RGB。
也许关于YUV是色彩模型的说法来源于习惯或者根本就是不理解,但色彩模型和色彩空间的混淆会对YUV和YCbCr的理解产生连带效应,以致于感觉无法理解透彻,对于一个工程师来说一个关键问题理解的模糊是致命的,还嫌坑不够多吗?
YUV vs YCbCr
YUV是基于RGB色彩模型的一种色彩空间,设计初衷是因为人对色彩的感知没有对亮度感知灵敏,所以在工业上为了减少图片的体积节省信息输送成本,有必要把亮度这一分量分离出来,再分离出两个颜色色差分量(蓝绿),进而形成了YUV色彩空间。另外YUV的一个好处是彩色电视信号对黑白电视的兼容,因为当两个色差分量值为0的时候(代表没有色差)输出的图像是黑白的。大家可以针对同一张图片调整手机屏幕亮度,你会发现亮度对你色彩的感知影响是相当大的,这是人眼的工作原理。所以我们可以减小两个色差分量的取样进而减少整个图片的体积。
既然YUV是基于RGB的编码,那二者之间必然需要转换公式或者说映射(mapping),而YCbCr只是众多映射中的一种,
可以看到Y值其实就是对RGB三个分量不同权重的取值构成的,可以说整个转换公式最关键的部分就是第一个等式的系数值,这也决定了整个转换公式的其他系数值。所以说系数值代表了这个转换公式,也就代表了YCbCr与RGB的映射关系,而且这一映射关系其实来源于标准ITU-R BT.601的定义,进一步阅读请看YCbCr–Wikipedia。
小结 YCbCr色彩空间是YUV色彩空间的特例,而YUV色彩空间是基于RGB色彩模型的一种实现,是对RGB的一种线性编码,并不是另外一种色彩空间。YUV的主要目的是在保证图像显示质量的前提下尽量缩小图像的体积,而且通过把亮度分量从RGB颜色分量中分离出来也能够使黑白显示设备能够兼容彩色信号。YCbCr是YUV家族中在工业领域使用最广泛的一种标准,这也是为什么JPEG内部编码采用YCbCr的原因。
文章来源于http://qtstack.com/colorspace-ycbcr/
研读上文,才理解了YCbCr。 Face detection in color images 文章里系统的讲解了人脸检测的相关算法。
调试通过的matlab程序:
%基于Ycbcr色彩空间肤色检测
close all;
clear;
clc;
%将RGB色彩空间转换为Ycbcr色彩空间
Image_RGB = imread('test.jpg');
Image_YCbCr = rgb2ycbcr(Image_RGB);%YCbCr変换
%得到图片的行数与列数
[row column dim] = size(Image_RGB);
for i = 1 : row
for j = 1 : column
Y = double(Image_YCbCr(i, j, 1));%Y成分 表示的是亮度
CbY = double(Image_YCbCr(i, j, 2));%Cb成分 指蓝色色度
CrY = double(Image_YCbCr(i, j, 3));%Cr成分 红色色度
%double去掉显示的就是灰度图像
if (Y < 125 || Y > 188)
if (Y < 125)
%获得Cb,Cr的均值
CbY_Average = 108 + (125 - Y) * (118 - 108) / (125 - 16);%公式(7)
CrY_Average = 154 - (125 - Y) * (154 - 144) / (125 - 16);%公式(8)
WCbY = 23 + (Y - 16) * (46.97 - 23) / (125 - 16);%公式(6) 为公式(5)做计算
WCrY = 20 + (Y - 16) * (38.76 - 20) / (125 - 16);
elseif (Y > 188)
CbY_Average = 108 + (Y - 188) * (118 - 108) / (235 - 188);
CrY_Average = 154 + (Y - 188) * (154 - 132) / (235 - 188);
WCbY = 14 + (235 - Y) * (46.97 - 14) / (235 - 188);
WCrY = 10 + (235 - Y) * (38.76 - 10) / (235 - 188);
end
%求Cb(Kh), Cr(Kh)的均值
CbKh_Anerage = 108 + (188 - 188) * (118 - 108) / (235 - 188);
CrKh_Average = 154 + (188 - 188) * (154 - 132) / (235 - 188);
Cb = (CbY - CbY_Average) * 46.97 / WCbY + CbKh_Anerage;%公式(5)
Cr = (CrY - CrY_Average) * 38.76 / WCbY + CrKh_Average;
elseif (Y >= 125 && Y <= 188)="" cb="CbY;%公式(5)" cr="CrY;" end="" %将cb,cr代入椭圆模型="" cx="109.38;" cy="152.02;" ecx="1.60;" ecy="2.41;" a="25.39;" b="14.03;" theta="2.53" pi="" *="" 180;%角度="" m="sin(Theta);" n="cos(Theta);" temp="[n," m;="" -m,="" n]="" [cb="" -="" cx;="" cy];="" x="temp(1," 1);="" y="temp(2," ellipse="(x" ecx)^2="" a^2="" +="" (y="" ecy)^2="" b^2;%椭圆方程="" %判断点(x,="" y)落在椭圆内部还是外部,落在椭圆内部的点认为是肤色区域,用白色标记。落在椭圆外部的点不是肤色区域,用黑色标记。="" %0黑255白="" if="" (ellipse="" <="1)" image_ycbcr(i,="" j,="" :)="255;" else="" figure;="" subplot(121);="" imshow(image_rgb);title('原图像');="" subplot(122);="" imshow(image_ycbcr);title('处理后图像');="" pre="">