1.人脸检测原理框图

整体思路是寻找图片中最大的连通域,将其认定为人脸。

第一个环节均值滤波,是为了减弱图像的相关细节部分,以免毛刺影响后期连通域的形成,二值化方便形态学处理,减少运算量。考虑到人脸有黑人和白人黄种人,黑人肤色较深,在二值化之后面部区域不容易形成较大的连通域,如果采取形态学边界提取的办法,就可以避免这个问题,形态学边界提取,只要结构元素够大,也可以形成较大的封闭连通域。

然后就是纵向闭合操作,这一步我选择采用竖向长条状的结构元素进行闭合运算,因为人的脸部和颈部以及头发和衣物等等都是纵向分布的,在进行形态学边界提取的时候,容易将这些靠近的成分割裂开来,这对连通域的判断极为不利,所以用竖向长条状的结构元素在在纵向进行闭合运算,将脸部上下部的区域重新连接起来。

紧接着我又用横向长条状结构元素进行横向腐蚀运算,这是因为,人的头部以下的身体部分存在有大量连通域的时候,容易对最大连通域的判决产生干扰,又因为下半部分,多半呈纵向分布,通过横向腐蚀可以将这些大块的连通域割裂开来,但是要注意的是,割裂程度不应太大,否则会使得上一步闭合操作丧失意义。

接着,由于背景杂物等因素,同样也会产生大量连通域,这会对最后结果的判决产生干扰,因此要予以剔除。

进行了层层筛选之后,在剩下的连通域里面挑一个最大的连通域,并且尺寸形状满足要求的用矩形框框起来作为人脸检测结果。

2 步骤

2.1 均值滤波

h = ones(9)/81;
I = uint8(conv2(I,h));
figure,imshow(I),title('线性均值滤波')

采用9x9模板进行线性均值滤波,因为后面调用gpuArray()函数转换对输入数据有要求,所以在进行了二维卷积之后重新将数据格式转换成8位无符号整形数据。

2.2 二值化

BW = imbinarize(I);
figure,imshow(BW),title('二值化')

直接调用imbinarize对图像进行二值化

2.3.形态学边界提取

B = ones(21);%结构元素
BW = -imerode(BW,B) + BW;
figure,imshow(BW),title('形态学边界提取')
BW = bwmorph(BW,'thicken');
figure,imshow(BW),title('加粗边界')
BW = not(bwareaopen(not(BW), 300));
figure,imshow(BW),title('把空洞填了')

结构元素采用21x21大小的全1矩阵,先调用imrode()进行腐蚀,再用原图减去腐蚀结果,得到边界。为了让边界更加明显,调用bmworph函数,传入’thicken’参数,意在将边界加粗加厚。最后为了把空洞就是连续的小黑色块填满,调用bwareaopen()函数,该函数是去除面积小于300的白块,为了去除黑块,先调用not(BW)给原来的二值图像取反,去掉取反后面积小于300的白块,再次取反,达到去掉面积小于300的黑块的目的。

2.4 纵向闭合与横向腐蚀

%进行形态学运算
B = strel('line',50,90);
BW = imdilate(BW,B);
BW = imerode(BW,B);
figure,imshow(BW),title('再闭操作之后')
B = strel('line',10,0);
BW = imerode(BW,B);
figure,imshow(BW),title('闭操作之后再腐蚀')
BW = gpuArray(BW);

调用strel()函数生成特定的结构元素,第一步调用strel(‘line’,50,90),意思是调用直线型结构元素,长度为50,角度90度,也就是竖直的长条形结构元素。接着利用B调用imdilate和imerode,先进行膨胀再进行腐蚀完成闭操作运算。下一步,继续生成横向长条形结构元素,进行腐蚀操作,注意这里的结构元素不宜面积太大,长度太长,否则会过度影响上一步的结果

最后为了循环过程中提升运算速度,将数据类型更改为gpuArray(),可以在GPU上进行计算,节省时间。

2.5 消除边界多余连通域

%最小化背景
%细分
div = 10;
r = floor(n1/div);%分成10块 行
c = floor(n2/div);%分成10块 列
x1 = 1;x2 = r;%对应行初始化
s = r*c;%块面积
%判断人脸是否处于图片四周,如果不是就全部弄黑
%figure
for i=1:divy1 = 1;y2 = c;%对应列初始化for j=1:divloc = find(BW(x1:x2,y1:y2)==0);%统计这一块黑色像素的位置num = length(loc);rate = num*100/s;%统计黑色像素占比if (y2<=0.2*div*c||y2>=0.8*div*c)||(x1<=r||x2>=r*div)if rate <=100BW(x1:x2,y1:y2) = 0;end%imshow(BW)elseif rate <=25BW(x1:x2,y1:y2) = 1;end%imshow(BW)end%下一列y1 = y1 + c;y2 = y2 + c;end%下一行x1 = x1 + r;x2 = x2 + r;
end

对于周围多余的杂物产生的连通域,我选择先将整幅图像划分为很多小块,对一部分在图像边缘的小块全部置成黑色,对不在边缘的通过计算其中黑色像素比例来判定是否应该全部给成白色。因为图片中央可能还会存在一些细小空洞,这些空洞在每一小块占比不是很大但有可能影响连通性,如果一个小块里面大部分是白色就全部给成白色,方便后期判定最大连通域。

Div是均分比例,我这里设置成10,也就是将整个图像划分成100个小块。r就是在行方向上一个小块占多少像素,c就是在列方向上一个小块有多少像素。用两层循环来遍历每个小块,通过find(x1:x2,y1:y2)==0返回所有满足要求的像素的索引,索引长度就是黑色像素的个数。

通过条件判断是否在边界。

2.6 寻找最大连通域并画框

figure
subplot(1,2,1)
imshow(BW)
title('最终处理')
L = bwlabel(BW,8);%利用belabel函数对8连通域区间进行标号
BB = regionprops(L,'BoundingBox');%得到矩形框,框柱每一个连通域
BB = cell2mat(struct2cell(BB));
[s1,s2] = size(BB);
BB = reshape(BB,4,s1*s2/4)';
pickshape = BB(:,3)./BB(:,4);%
shapeind = BB(0.3<pickshape&pickshape<3,:);%筛选掉尺寸比例不合格
[~,arealind] = max(shapeind(:,3).*shapeind(:,4));
subplot(1,2,2)
imshow(rgb)
hold on
rectangle('Position',[shapeind(arealind,1),shapeind(arealind,2),shapeind(arealind,3),shapeind(arealind,3)],...'EdgeColor','g','Linewidth',2)
title('人脸检测')

经过消除边界多余连通域后得到的BW中剩下的连通域内存在着我们需要的那个对应人脸的连通域。一般情况下,对应人脸的那个连通域会是最大的连通域。

调用bwlabel(BW,8)函数给所有连通域标记,其中邻域规则采用8邻域,返回一个被标记过连通域的图像,第k个被标记的连通域所有像素值为k。

调用regionprops(L,’BoundingBox’)函数,传入参数L和’BoundingBox’,该函数用于获取图像的各种属性,传入’BoundingBox’返回的是一个结构体,每一个结构体内都包含了一个能框柱其对应连通域的最小方框。一个方框,用一个序列来描述[x,y,width,height],这个序列包含了方框左上角像素的坐标以及长和宽。

这三条语句,第一条用来将结构体转换成矩阵向量,方便计算。第二行获取这个矩阵的维度。由于BB刚转换成向量的时候,是一个行向量,每4个元素1组对应一个方框。为了后续计算方便,使用reshape()函数,将BB重构成一个矩阵,这个矩阵有4列,每一列对应方框的一个参数,比如坐标,长宽等等。每一行对应一个方框。

第一行计算长宽比,得到的pickshape向量的每一行对应每个方框的长宽比。由于有的方框明显过于扁平或者过于狭长,这种方框应该是要扔掉的。

所以第二行,通过逻辑表达式从BB内筛选出尺寸比例合格的方框,存在shapeind里面。
剩下的尺寸符合要求的方框里面要选出面积最大的那个,最后一行,得到面积最大的方框对应的索引。

把方框画出来。

3 检测结果

图 15rgb图像转换成灰度图像                 图 16线性均值滤波结果

可以看到,均值滤波使得图像变模糊了细节减少

图 17二值化结果                                    图 18形态学边界提取结果

以看到边界被成功提取了出来,在人脸部形成了一个比较大的连通域

可以看到,进行边界加粗和空洞添补之后,眼睛部分的黑块被消除了,这使得脸部连通域更大了

注意观察图片左边的相分离的白块,在纵向闭操作之后连在了一起,同时脸部连通域进一步扩大,然后横向腐蚀在尽量维持脸部连通域大小的情况下减小了图片下方连通域。

可以看到效果还可以。还有其他的测试结果

图 24测试样例

图 25测试样例

图 26测试样例

图 27测试样例

图 28测试样例

图 29测试样例

图 30测试样例

这里注意到,黑人同样也被检测到了

---%%%完整代码
rgb = imread('f.jpg');
I = rgb2gray(rgb);
[n1,n2] = size(I);
%灰度图
figure,imshow(I),title('灰度图')
tic
h = ones(9)/81;
I = uint8(conv2(I,h));
figure,imshow(I),title('线性均值滤波')
BW = imbinarize(I);
figure,imshow(BW),title('二值化')
B = ones(21);%结构元素
BW = -imerode(BW,B) + BW;
figure,imshow(BW),title('形态学边界提取')
BW = bwmorph(BW,'thicken');
figure,imshow(BW),title('加粗边界')
BW = not(bwareaopen(not(BW), 300));
figure,imshow(BW),title('把空洞填了')
%进行形态学运算
B = strel('line',50,90);
BW = imdilate(BW,B);
BW = imerode(BW,B);
figure,imshow(BW),title('再闭操作之后')
B = strel('line',10,0);
BW = imerode(BW,B);
figure,imshow(BW),title('闭操作之后再腐蚀')
%%BW = gpuArray(BW);%%将数据载入gpu可以加速,电脑不一定支持%最小化背景
%细分
div = 10;
r = floor(n1/div);%分成10块 行
c = floor(n2/div);%分成10块 列
x1 = 1;x2 = r;%对应行初始化
s = r*c;%块面积
%判断人脸是否处于图片四周,如果不是就全部弄黑
%figure
for i=1:divy1 = 1;y2 = c;%对应列初始化for j=1:divloc = find(BW(x1:x2,y1:y2)==0);%统计这一块黑色像素的位置num = length(loc);rate = num*100/s;%统计黑色像素占比if (y2<=0.2*div*c||y2>=0.8*div*c)||(x1<=r||x2>=r*div)if rate <=100BW(x1:x2,y1:y2) = 0;end%imshow(BW)elseif rate <=25BW(x1:x2,y1:y2) = 1;end%imshow(BW)end%下一列y1 = y1 + c;y2 = y2 + c;end%下一行x1 = x1 + r;x2 = x2 + r;
endfigure
subplot(1,2,1)
imshow(BW)
title('最终处理')
L = bwlabel(BW,8);%利用belabel函数对8连通域区间进行标号
BB = regionprops(L,'BoundingBox');%得到矩形框,框柱每一个连通域
BB = cell2mat(struct2cell(BB));
[s1,s2] = size(BB);
BB = reshape(BB,4,s1*s2/4)';
pickshape = BB(:,3)./BB(:,4);%
shapeind = BB(0.3<pickshape&pickshape<3,:);%筛选掉尺寸比例不合格
[~,arealind] = max(shapeind(:,3).*shapeind(:,4));
subplot(1,2,2)
imshow(rgb)
hold on
rectangle('Position',[shapeind(arealind,1),shapeind(arealind,2),shapeind(arealind,3),shapeind(arealind,3)],...'EdgeColor','g','Linewidth',2)
title('人脸检测')
toc

MATLAB 图像处理 简单人脸检测(详细,你上你也行)相关推荐

  1. 人脸检测技术即matlab的实现,人脸检测研究及MATLAB实现.doc

    摘要:随着计算机视觉技术的不断发展,各种识别技术已经成功投入使用,服务于我们的日常生活中,其中对于人脸的识别技术应用最为广泛.人脸检测作为识别领域最为重要的一个分支,其应用领域十分广阔.人脸检测通过对 ...

  2. Java 图像处理教程(人脸检测,添加水印,图像颜色转换)

    Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 文章目录 Java 图像处理教程(人脸检测,添加水印,图像颜色转换) 1:图片的读和写 2:彩色图像转换成灰度图像 3:彩色图像转换成负图像 ...

  3. 人脸检测:史上最详细人脸检测libfacedetection讲解-网络详解--第二节

    以下是关于我个人对libfacedetection(人脸检测-pytorch)的所有见解,如有错误欢迎大家在评论区指出,我将会第一时间纠正.据说,人脸检测速度可以达到1000FPS,到底结果如何,我们 ...

  4. 基于matlab实现的人脸检测

    作为一个图像处理的初学者,一直想写一个人脸检测的程序,经过多次尝试,发现不管是在C站上找的开源代码,还是自己手撸的代码,总是那么不尽人意.后来经过查阅资料,发现matlab内置有一个人脸检测的检测器函 ...

  5. 图像处理------简单脸谱检测算法

    介绍基于皮肤检测之后的,寻找最大连通区域,完成脸谱检测的算法.大致的算法步骤如下: 原图如下: 每步处理以后的效果: 程序运行,加载选择图像以后的截屏如下: 截屏中显示图片,是适当放缩以后,代码如下: ...

  6. MATLAB学习笔记 人脸检测

    需要安装计算机视觉系统工具箱 Computer Vision Toolbox - MATLAB & Simulinkhttps://ww2.mathworks.cn/products/comp ...

  7. 一种用于人脸检测的设备上的深度神经网络

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 译者:QiqiHe 苹果公司开始在iOS 10中使用深度学习进行人脸检测.随着Vision框架的发布,开发人员现在可以在他们的应用程序中使用这种 ...

  8. 大小仅1MB,超轻量级通用人脸检测模型登上GitHub趋势榜

    机器之心报道 项目作者:Linzaer 近日,用户 Linzaer 在 Github 上推出了一款适用于边缘计算设备.移动端设备以及 PC 的超轻量级通用人脸检测模型,该模型文件大小仅 1MB,320 ...

  9. OpenCV实现简单人脸检测

    用OpenCV实现简单的人脸识别,基于静态图像. 1.材料准备:找到OpenCV提供的人脸训练模型文件.可以通过 https://github.com/opencv/opencv/tree/maste ...

  10. 2 找图像连通域_MATLAB--数字图像处理 简单人脸识别

    简单人脸识别 思路 找到图像中连通域面积最大的那块连通域. i=imread('face.jpg'); I=rgb2gray(i); BW=im2bw(I); %利用阈值值变换法将灰度图像转换成二进制 ...

最新文章

  1. Postgresql:删除及查询字段中包含单引号的数据
  2. 天下苦同行评审久矣,要不我们把它废除掉?
  3. linux鼠标触摸屏应用程序,在Ubuntu环境下实现插入鼠标自动关闭触摸板
  4. [RabbitMQ]工作队列原理_代码实现
  5. go https client
  6. Kubernetes知识体系-从入门到精通
  7. world: 对比两个文档
  8. 【渝粤教育】电大中专计算机职业素养 (6)作业 题库
  9. SQL动态配置,动态解析SQL
  10. IAR基础教程之函数跳转
  11. 珍藏的Android开发必备网站和工具(开发工具总结)
  12. unity学习笔记-Avpro和安卓结合
  13. 高等数学期末总复习DAY12.复合函数的链式求导、隐函数求导、
  14. java filer,java – Filer的原始元素是否有用?
  15. 笔记-Java基础语法-二进制
  16. stackoverflow愚人节彩蛋效果
  17. 打工与创业的有什么区别,丨国仁网络资讯
  18. Logstash 算术运算操作
  19. flink source 同步_网易云音乐基于 Flink + Kafka 的实时数仓建设实践
  20. 函数定义与调用,自己实现pow()函数对整数的运算

热门文章

  1. NI 视觉入门软件介绍
  2. nodejs下载文件到本地并命名 和 删除文件
  3. 基于LInuxc语言TCP聊天服务端程序实现私聊,以及群聊和私聊的转换
  4. linux信号量使用
  5. svnadmin dump导入导出命令
  6. KBQA-Bert学习记录-构建BERT-CRF模型
  7. fh 幅频特性曲线怎么画fl_测量rc带通滤波器的幅频特性和相频特性-电子科技大学.ppt...
  8. java实现杨辉三角
  9. python模块安装位置_查看python模块的安装路径
  10. Android studio创建Java测试类