一、实验目的:
(1)进一步掌握图像处理工具Matlab,熟悉基于Matlab的图像处理函数。
(2)掌握图像分割方法,熟悉常用图像描述方法。
二、实验原理
1.肤色检测
肤色是人类皮肤重要特征之一,在检测人脸或手等目标时常采用肤色检测的方法,将相关区域从图像中分割出来。
肤色检测方法:
肤色检测方法有很多,但无论是基于不同的色彩空间还是不同的肤色模型,其根本出发点在于肤色分布的聚集性,即肤色的颜色分量一般聚集在某个范围内。通过大量的肤色样本进行统计,找出肤色颜色分量的聚集范围或用特殊的分布模型去模拟肤色分布,进而实现对任意像素颜色的判别。
不同彩色空间肤色分布范围:
① RGB彩色空间
据统计资料,肤色在RGB模型中的分布范围基本满足以下条件:
(1)在均匀光照下:R>95且G>40且B>20 且 max{R,G,B}一min{R,G,B}>15且|R一G|>15且R>G且R>B。
(2)在闪光或侧向照明环境下:R>220且G>210且B>170且|R一G≤15且R>B且G>B。
② YCbCr彩色空间
据统计资料,肤色在YCbCr空间的分布范围为77≤C,≤127,133≤C,≤173。
③ HSV彩色空间
HSV空间建立的肤色模型要求满足0°≤H≤25°或335°≤H≤360°且0.2≤S≤0.6且0.4V。
肤色模型
肤色模型是根据大量样本的统计数据建立以确定肤色的分布规律,进而判断像素的色彩是否属于肤色或与肤色相似程度的模型。常用的有阙值模型、高斯模型和椭圆模型。
1)阈值模型
國值模型是用数学表达式明确肤色分布范围的建模方法。这类方法依据肤色分布范围进行检测,判断简单、明确、快捷,但需要选择合适的颜色空间及合适的参数。
2)高斯肤色模型
利用高斯函数模拟肤色在CbCr色度空间的分布。
为色度向量的均值和协方差矩阵,可通过多种方式获取,数值略有区别。
2.图像平滑
图像平滑是指受传感器和大气等因素的影响,遥感图像上会出现某些亮度变化过大的区域,或出现一些亮点(也称噪声)。这种为了抑制噪声,使图像亮度趋于平缓的处理方法就是图像平滑。图像平滑实际上是低通滤波,平滑过程会导致图像边缘模糊化。
图像平滑的方法包括:插值方法,线性平滑方法,卷积法等等。这样的处理方法根据图像噪声的不同进行平滑,比如椒盐噪声,就采用线性平滑方法!
3.皮肤区域分割
所采取的肤色分割的方法为:首先根据肤色在RGB空间分布统计进行初略非肤色过滤,初步去除图像中的非肤色;然后根据肤色在CgCr空间分布范围统计,进行肤色的第二次分割,获取肤色分割图像;在对肤色区域进行中值滤波,提高肤色检测率。
⑴基于RGB空间非肤色像素的初步过滤
对于图像中一些非肤色的像素点,若呈现过红、过蓝、过绿等特征,可通过设置取值范围初步过滤这些非肤色像素点。具体操作过程如下:
①据统计,人眼的像素具有特征:R<70,G<40,B<20.这样使得眼睛更加容易提取像素,减少亮度低的像素被误判为肤色像素的概率。
②据统计,过红、过绿像素大多具有特征R+G>500,可剔除这些像素点。
③据统计,当R<160,G<160,B<160,过红、过绿像素大多数具有R>G>B,可剔除这些像素点。
⑵基于YCgCr空间的肤色分割
肤色YCbCr颜色空间是一种常用的肤色检测的色彩模型,其中Y代表亮度,Cr代表光源中的红色分量,Cb代表光源中的蓝色分量。人的肤色在外观上的差异是由色度引起的,不同人的肤色分布集中在较小的区域内。肤色的YCbCr颜色空间CbCr平面分布在近似的椭圆区域内,通过判断当前像素点的CbCr是否落在肤色分布的椭圆区域内,就可以很容易地确认当前像素点是否属于肤色。将图像转换到YCbCr空间并且在CbCr平面进行投影,可以采集到肤色的样本点。
将CbCr平面均分为许多小区域,将每个区域的中心点CbCr色度值作为当前区域的特征值,对肤色区域像素值进行遍历,如果当前像素值落在该区域内则替换当前区域特征值。
RGB转换为YCbCr
4.图像融合
图像融合(Image Fusion) 是指综合多幅输入图像的信息,以获得更高质量输出图 像的过程与融合前的多幅图像相比,融合后的图像应更加适于进一步的观察或处理。图像融合属于数字图像处理领域,在计算摄影学中,用于拍摄所得图像的后期处理。
5.图像锐化
图像锐化也称边缘增强。锐化技术用于加强图像中的边界和细节信息。由于边界和细节信息对应频域中的高频部分,所以在频域中通常对图像进行高通滤波,在空间域则进行微分处理。为增加细节信息,采用了拉普拉斯算子进行图像锐化。
Laplace算子
拉普拉斯(Laplace)是著名物理学家和数学家,laplace定义如下:
对于离散函数f(i,j),laplace算子定义为:
由此可得Laplace算子矩阵为:
三、实验步骤(包括分析、代码和波形)
首先来看看这个实验的内容。利用人物正面照,参考例7.15实现皮肤美化处理,要求:
(1)滤波、色彩空间、代数运算、锐化等技术实现美化
(2)加入皮肤的亮白处理
(3)尝试其他肤色检测处理。
要求:实验报告一份,源程序一份,实验效果对比图;
实验的思路是很明确的,结合原理中的讨论,我们只要按照题目的要求依据参考代码、查看运行并进行验证就可以了,不需要计算。
下面是第(1)小题的代码。滤波、色彩空间、代数运算、锐化等技术实现美化;
clear,clc,close all;
ImageOrigin=im2double(imread('face.jpg'));
figure,imshow(ImageOrigin),title('原图');
DBImage=DBfilt(ImageOrigin);
SkinImage1=FirstFilter(ImageOrigin); %%初步过滤
SkinArea=SecondFilter(SkinImage1); %%YCgCr空间范围肤色检测
SkinFuse=Fuse(ImageOrigin,DBImage,SkinArea);
SkinBeautify=Sharp(SkinFuse);
function Out=DBfilt(In)
[height,width,c] = size(In);
win=15; % 定义双边滤波窗口宽度
sigma_s=6; sigma_r=0.1; % 双边滤波的两个标准差参数
[X,Y] = meshgrid(-win:win,-win:win);
Gs = exp(-(X.^2+Y.^2)/(2*sigma_s^2));%计算邻域内的空间权值
Out=zeros(height,width,c);
for k=1:c
for j=1:height
for i=1:width
temp=In(max(j-win,1):min(j+win,height),max(i-win,1):min(i+win,width),k);
Gr = exp(-(temp-In(j,i,k)).^2/(2*sigma_r^2));%计算灰度邻近权值
% W为空间权值Gs和灰度权值Gr的乘积
W = Gr.*Gs((max(j-win,1):min(j+win,height))-j+win+1,(max(i-win,1):min(i+win,width))-i+win+1);
Out(j,i,k)=sum(W(:).*temp(:))/sum(W(:));
end
end
end
figure,imshow(Out),title('双边滤波');
end
function Out=FirstFilter(In)
Out=In;
[height,width,c] = size(In);
IR=In(:,:,1); IG=In(:,:,2);IB=In(:,:,3);
for j=1:height
for i=1:width
if (IR(j,i)<160/255 && IG(j,i)<160/255 && IB(j,i)<160) && (IR(j,i)>IG(j,i) && IG(j,i)>IB(j,i))
Out(j,i,:)=0;
end
if IR(j,i)+IG(j,i)>500/255
Out(j,i,:)=0;
end
if IR(j,i)<70/255 && IG(j,i)<40/255 && IB(j,i)<20/255
Out(j,i,:)=0;
end
end
end
figure,imshow(Out);title('非肤色初步过滤');
end
function Out=SecondFilter(In)
IR=In(:,:,1); IG=In(:,:,2);IB=In(:,:,3);
[height,width,c] = size(In);
Out=zeros(height,width);
for i=1:width
for j=1:height
R=IR(j,i); G=IG(j,i); B=IB(j,i);
Cg=(-81.085)*R+(112)*G+(-30.915)*B+128;
Cr=(112)*R+(-93.786)*G+(-18.214)*B+128;
if Cg>=85 && Cg<=135 && Cr>=-Cg+260 && Cr<=-Cg+280
Out(j,i)=1;
end
end
end
Out=medfilt2(Out,[3 3]);
figure,imshow(Out),title('YCgCr空间范围肤色检测');
end
function Out=Fuse(ImageOrigin,DBImage,SkinArea)
Skin=zeros(size(ImageOrigin));
Skin(:,:,1)=SkinArea;
Skin(:,:,2)=SkinArea;
Skin(:,:,3)=SkinArea;
Out=DBImage.*Skin+double(ImageOrigin).*(1-Skin);
figure,imshow(Out);title('肤色与背景图像融合');
end
function Out=Sharp(In)
H=[0 -1 0;-1 4 -1;0 -1 0]; %Laplacian锐化模板
Out(:,:,:)=imfilter(In(:,:,:),H);
Out=Out/3+In;
% imwrite(Out,'man4.jpg');
figure,imshow(Out),title('Laplacia锐化图像');
end
下面是第(2)小题的代码。加入皮肤的亮白处理;
rgb = imread('face.jpg');%读取图片
figure(1),subplot(2,2,1);imshow(rgb);title('原图像');
[m,n,k] = size(rgb); %读取图片大小
hsv = rgb2hsv(rgb); %颜色空间转换
H = hsv(:,:,1); % 色调
S = hsv(:,:,2); % 饱和度
V = hsv(:,:,3); % 亮度
for i = 1:m %遍历每一个像素点,可以根据需要选择自己需要处理的区域
for j = 1: n
hsv(i,j,3) =1.3* hsv(i,j,3); %1.3是需要增强的倍数,可以根据图片情况动态调整
end
end
rgb1 = hsv2rgb(hsv); %转为RGB,进行显示
figure(1),subplot(2,2,2);imshow(rgb1);title('加亮图像');
下面是第(3)小题的代码。尝试其他肤色检测处理;
clear,clc,close all;
Image=imread('face.jpg');
figure,imshow(Image),title('原图');
r=double(Image(:,:,1)); % 提取红色分量并转化为高精度
g=double(Image(:,:,2));
b=double(Image(:,:,3));
[N,M]=size(r); % 提取矩阵r的大小 NxM
miu=[117.4361 156.5599]'; % 高斯肤色模型均值
sigma=[160.1301 12.1430;12.1430 299.4574]; % 高斯肤色模型协方差矩阵
cbcr=zeros(2,1); % 生成 2x1矩阵
SkinCbCrG=zeros(N,M); % 生成所有值为0的 NxM矩阵用于存放处理后图像
SkinRGB=zeros(N,M);
SkinHSV=zeros(N,M);
SkinCbCr=zeros(N,M);
thresh=0.35; % 肤色概率二值化阙值
for i=1:M % 循环图像每一个像素点 列循环
for j=1:N % 行循环
R=r(j,i); % 将图像红色分量中(j,i)点值赋值给R
G=g(j,i);
B=b(j,i);
if (R>95 && G>40 && B>20 && (R-G)>15 && R-B>15) || ... % RGB空间肤色检测
(R>220 && G>210 && B>170 && R-B<=15 && R>B && G>B) % 符合RGB肤色检测条件的像素点值置1则为白色,其他不符合条件的像素点为0黑色
SkinRGB(j,i)=1;
end
maxRGB=max(max(R,G),B); % 取三分量中同一点最大值
minRGB=min(min(R,G),B); % 取三分量中同一点最小值
C=maxRGB-minRGB; % 取最大差值
V=maxRGB; % 最大值赋值给参数V
if V==0 % 比较最大值是否等于零
S=0;
else
S=C/V; % 最大值不等于零则 C最大差值/V最大值
end
if maxRGB==R % 如果该点最大值==红色分量值;作如下处理
H=60*mod((G-B)/C,6);
elseif maxRGB==G % 如果该点最大值==绿色分量值;作如下处理
H=60*((B-R)/C+2);
elseif maxRGB==B % 如果该点最大值==蓝色分量值;作如下处理
H=60*((R-G)/C+4);
end % 符合HSV肤色检测 将该点值置1
if ((H>=0 && H<=25) || (H>=335 && H<=360)) && (S>=0.2 && S<=0.6) && V>=0.4
SkinHSV(j,i)=1; % 优化 HSV 效果增强?如何改?为什么这样改?
end
R=R/255;G=G/255;B=B/255; % RGB 转 YCrCb 公式
Cb=224*(-0.1687*R-0.3313*G+0.5*B)+128;
Cr=224*(0.5*R-0.4187*G-0.0813*B)+128;
if Cb>=77 && Cb<=127 && Cr>=133 && Cr<=173 % 符合 YCrCb肤色检测 将该点值置1
SkinCbCr(j,i)=1;
end
cbcr= [Cb Cr]'; % YCbCr空间基于高斯模型的肤色检测
p=exp(-0.5*((cbcr-miu)')*(inv(sigma))*(cbcr-miu)); % 高斯模型函数
if p>thresh % p > 阙值0.35 值置1
SkinCbCrG(j,i)=1;
end
end
end
figure,imshow(SkinRGB),title('RGB空间肤色检测');
figure,imshow(SkinHSV),title('HSV空间肤色检测');
figure,imshow(SkinCbCr),title('YCbCr空间范围肤色检测');
figure,imshow(SkinCbCrG),title('YCbCr空间高斯模型肤色检测');
imwrite(SkinRGB,'skinrgb3.jpg');
imwrite(SkinHSV,'skinhsv3.jpg');
imwrite(SkinCbCr,'skincbcr3.jpg');
imwrite(SkinCbCrG,'skinCbCrG3.jpg');