%ycbcr模式下肤色提取
clear,clc,close all;
f=imread('hh.jpg');
figure,imshow(f);
ycbcr=rgb2ycbcr(f);
cr=ycbcr(:,:,3);
figure,imshow(cr);
cr(cr>140&cr<160)=255;
cr(cr~=255)=0;
figure,imshow(cr);
bw=im2bw(cr);
bw=imdilate(bw,strel('disk',1));
%腐蚀的原因是让手掌的轮廓粘连住,以便于填充小坑洞
bw=imfill(bw,'holes');
figure,imshow(bw);
bws=repmat(bw,[1,1,3]);
%矩阵重复函数,行一次,列一次,共三层
result=uint8(bws).*f;
figure,imshow(result);
clear,clc,close all;
r=1:255;
r=r';
%转置过后的r为一条从黑到白渐变的竖线
r=uint8(repmat(r,[1,300,3]));
%共255行,300列,前后三层
figure,imshow(r);
在这里略微讲一下rgb,ycbcr,yuv三种图像模式。
1)RGB(红绿蓝)
依据人眼识别的颜色定义出的空间;可以表示大部分颜色;细节难以进行数字化调整,所以不用于科研;将色调、色度、饱和度三者放在一起难以分开;用于彩色监视器和一大类夏色视频摄像。
- YUV
在YUV空间中,每一个颜色有一个亮度信号Y,两个色度信号U和V。亮度信号是强度,和色度信号分开,便于在不影响颜色的情况下改变强度;使用RGB的信息,从全色彩图像中产生一个黑白图像。Y通道描述luma信号(黑白电视能看见的信号),与亮度信号不同,介于亮暗之间;U(Cb)和V(Cr)从红和蓝中提取亮度值来减少颜色信息量、
- YCbCr是YUV经过缩放和偏移的翻版。在此不深究。Cr层是八位图。
实例三:截取邱启明同学的脸蛋
clc,clear,close all;
f=imread('qqm.jpg');
figure,imshow(f);
fycbcr=rgb2ycbcr(f);%将RGB图转换成YCbCr图
cr=fycbcr(:,:,3);%将cr层抽出来
figure,imshow(cr),title('cr层');
%为什么对Cr层进行操作?cr层的有什么特点
cr(cr>140&cr<160)=255;%在ycbcr中,肤色部分的范围是140-160
cr(cr~=255)=0;%非肤色部分置位0
figure,imshow(cr),title('对cr层肤色单独处理');
% bw=im2bw(cr);%将cr转换成二值图
% figure,imshow(bw),title('转换成二值图');
%在此次操作中没有将其转换成二值图依旧可以得到结果
bwao=bwareaopen(cr,500);
figure,imshow(bwao);
[r,c]=find(bwao);
result=f(min(r):max(r),min(c):max(c),:);
figure,imshow(result);
%将肤色部分在原图上显示步骤:rgb图像转化为ycbcr图像,抽取cr层,调整亮度,
%转化为二值图,稍作处理之后转化为八位图与原图进行点乘操作,完成 。
clear,clc,close all;
f=imread('hhh.jpg');
figure,imshow(f);
fycbcr=rgb2ycbcr(f);%将RGB图转换成YCbCr图
cr=fycbcr(:,:,3);%将cr层抽出来
cr(cr>140&cr<160)=255;%在ycbcr中,肤色部分的范围是140-160
cr(cr~=255)=0;%非肤色部分置位0
bw=im2bw(cr);%将cr转换成二值图
bwao=bwareaopen(bw,600);%去除小对象
bwao=imfill(bwao,'holes');
%bwao是一个逻辑图
%转成三层矩阵维度搞成相同
bwaos=repmat(bwao,[1,1,3]);
result=uint8(bwaos).*f;
figure,imshow(result);
[h,w]=size(bwao);%h为行数,w为列数
hs=sum(bwao);
figure,plot(hs),title('竖直投影');%竖直投影
a=1;b=1;i=1;
while(a<w)
while(hs(a)==0&&a<w)
a=a+1;
end
b=a;
while(hs(b)>0&&b<w)
b=b+1;
end
if(b-a)>2
hresult=bwao(:,a:b);%记录从左到右的列值c
[r,c]=find(hresult);%找出取值不为0的位置
result1=f(min(r):max(r),min(c+a):max(c+a),:);
subplot(3,1,i),imshow(result1);
i=i+1;
end
a=b;%最后b的值都是赋给a的所以上面是+a不是+b
end
%出错原因:a,b是原图的a,b,但是用hresult记录之后的c就和a,b不一样了!!!
%每次循环的时候都要把上次的列值加上。
以下截图为各个过程中的截图,以及对于一些问题的解答。
显然,头和两只手一共是三部分,采用竖直投影可以达到目的。
老子辛辛苦苦搞出来的东西啊,离目标还差一步!!!
问题:subplot函数
Subplot(m,n,p)代表m*n的矩阵,p是位置,排列顺序是从左到右从上到下。
那么问题来啦???!!!为什么我用subplot(1,3,i)显示出来如上图所示,用subplot(3,1,i)效果就如下图所示呢???
你知道我是怎么解决这个问题的吗??其实就是把窗口挤扁了。!、
---------------------------------------------------------------------------------------------------------------------------------同样的套路我们来拆散一对情侣
clc,clear,close all;
f=imread('hhhh.jpg');
figure,imshow(f);
ycbcr=rgb2ycbcr(f);%将彩色图转化为ycbcr模式
cr=ycbcr(:,:,3);%抽出来cr层
cr(cr>140&cr<160)=255;
cr(cr~=255)=0;
figure,imshow(cr);
bw=im2bw(cr);
figure,imshow(bw);
bwao=bwareaopen(bw,600);
figure,imshow(bwao);
%去除毛刺--先腐蚀后膨胀开运算
bwopen=imopen(bwao,strel('disk',5));%阔以很完美,把女人的脖子去掉了,嘻嘻
figure,imshow(bwopen);
[h,w]=size(bwopen);
hs=sum(bwopen);
%观察图像,竖直投影可以截取两颗人头
a=1;b=1;i=1;
while(a<w)
while(hs(a)==0&&a<w)
a=a+1;
end
b=a;
while(hs(b)>0&&b<w)
b=b+1;
end
if(b-a>0)
hresult=bwopen(:,a:b);
[r,c]=find(hresult);
result=f(min(r):max(r),min(c+a):max(c+a),:);
result=f(min(r):max(r),min(c)+a:max(c)+a,:);
%由于a每次迭代都是常数因此两行代码没有区别
subplot(1,2,i),imshow(result);
i=i+1;
end
a=b;
end
你看你看!!你看我是什么神仙!!我怎么这么厉害!嘻嘻!
Emmmmm-----忌讳方脸抱歉哈!
以上所有图片均为导师教学素材,若侵权,我道歉但不承担责任。嘻嘻。