本文已参与「新人创作礼」活动,一起开启创作之路。

这是一个Matlab人脸检测算法详解

前语

目前主流的人脸检测与人脸辨认算法首要根据人工神经网络进行练习与检测,本文根据数字图画处理解析一个非人工神经网络的有趣人脸检测算法。图片与源码能够从下文获取或点击这儿获取:百度云下载资料点这儿,提取码2333

人脸检测成果

Matlab人脸检测算法详解
Matlab人脸检测算法详解
Matlab人脸检测算法详解

算法详解

该算法首要经过辨认二值图画下的最大连通区域来检测人脸,界说二值图画中宽长比小于1.8的最大连通区域(mx)为人脸区域。再将P的左上角坐标作为辨认框的左上角坐标,以mx在X轴的延伸长度作为辨认框在X与Y的延伸长度,然后制作出一个黄色2像素宽度的正方形辨认框。框中的区域即为该算法所辨认的人脸区域。

源代码解析

clear all  %铲除工作台中所有参数与数据
clc    %铲除界面
i=imread('5.jpg');         %读取所需猜测的图画
I=rgb2gray(i);             %将该图画转换为灰度图
BW=im2bw(I);             %将灰度图画转换为二值图画
figure(1);
imshow(BW);
%将布景最小化处理
[n1, n2]=size(BW);
r=floor(n1/10);  
c=floor(n2/10);
x1=1;x2=r;
s=r*c;
for i=1:10
    y1=1;y2=c;
    for j=1:10
        if(y2<=c || y2>=9*c) || (x1==1 || x2==r*10)
            loc=find(BW(x1:x2,y1:y2)==0);
            [o,p]=size(loc);
            pr=o*100/s;
            if pr<=100
                BW(x1:x2,y1:y2)=0;
                r1=x1;r2=x2;s1=y1;s2=y2;
                pr1=0;
            end
            imshow(BW);
        end
        y1=y1+c;
        y2=y2+c;
    end
    x1=x1+r;
    x2=x2+c;
end
figure(2)
subplot(1,2,1);
imshow(BW)
title('二值图画');
L=bwlabel(BW,8);   %找到连通区域,界说为8连通
BB=regionprops(L,'BoundingBox');%联通区用鸿沟框框取包括连通区域的最小矩形
BB1=struct2cell(BB);  %把结构体数组转换成元胞数组,每个元胞中含有4个数据
BB2=cell2mat(BB1);   %将元胞打开为行数为一的矩阵,BB2中元素的个数为BB1的4倍
[s1,s2]=size(BB2);
mx=0;     %mx为最大连通区域,初值为0
for k=3:4:s2-1    %k=3的取值为连通区域的X方向扩展长度,逐级加4,即遍历每个连通区域的X长度
    p=BB2(1,k)*BB2(1,k+1);  %p为连通区域的面积
    if p>mx && (BB2(1,k+1)/BB2(1,k))<1.8  %选区宽长比大于1.8的最大连通区域
        mx=p;
        j=k;
    end
end
subplot(1,2,2);
title('人脸检测');
imshow(I);
hold on;
rectangle('Position',[BB2(1,j-2),BB2(1,j-1),BB2(1,j),BB2(1,j)],'EdgeColor','y','LineWidth',2);
%rectangle各参数为:起点坐标,色彩,宽度

所调用函数解析

imread(‘5.jpg’); 读取图画

rgb2gray(i) 将该图画转换为灰度图,参数i为读取的图画

im2bw(I) 将灰度图画转换为二值图画,参数I为灰度图画

floor(n); 朝负无穷大方向取整,参数n为恣意数,关于复数,分别对实部和虚部取整

figure(1); 界说制作图画的称号

imshow(I); 制作图画,参数I为图画称号

subplot(m,n,p); 将多个图画到一个平面上的工具。其间,m表明是图排成m行,n表明图排成n列,p表明图地点的方位,p=1表明从左到右从上到下的第一个方位,p也能够为矩阵以表明其他队伍

bwlabel(BW,n)

L=bwlabel(BW,n);
界说一个与BW巨细相同的L矩阵,其间n的值为4或8,表明界说4连通或8连通 4连通:一个像素的上下左右4个方向有相邻的像素,则以为他们是衔接的,这些像素的组成区域为4连通区域。 8连通:一个像素的上下左右,上左上右下左下右8个方向有相邻的像素,则以为他们是衔接的,这些像素的组成区域为8连通区域。 例如: BW = 1 1 1 0 0  1 1  0 0 1 1 1 0 0  1 1  0 0 1 1 1 0 1  1 1  1 0 1 1 1 0 0  1 1  0 0 0 0 0 0 0  1 1  0 0 1 1 1 0 0  0 0  1 1 1 1 1 0 0  0 0  1 1 1 1 1 0 0  0 0  1 1 1 1 1 1 1  0 0  1 1 则L=bwlabel(BW,4)为(相同数字表明在同一个连通区域): L = 1 1 1 0 0  2 2  0 0 1 1 1 0 0  2 2  0 0 1 1 1 0 2  2 2  2 0 1 1 1 0 0  2 2  0 0 0 0 0 0 0  2 2  0 0 3 3 3 0 0  0 0  4 4 3 3 3 0 0  0 0  4 4 3 3 3 0 0  0 0  4 4 3 3 3 3 3  0 0  4 4

例如: L=bwlabel(BW,8)为(相同数字表明在同一个连通区域): L = 1 1 1 0 0  2 2  0 0 1 1 1 0 0  2 2  0 0 1 1 1 0 2  2 2  2 0 1 1 1 0 0  2 2  0 0 0 0 0 0 0  2 2  0 0 3 3 3 0 0  0 0  2 2 3 3 3 0 0  0 0  2 2 3 3 3 0 0  0 0  2 2 3 3 3 3 3  0 0  2 2

regionprops

BB=regionprops(L,’BoundingBox’); regionprops能够带有多种参数,BoundingBox表明为选区取包括连通区域的最小矩形 回来的成果为【x,y,w,h】,其间x与y为该矩形的左上角坐标,w与h为x与y方向上的延伸长度即矩形的长与宽。此外,其他参数及含义为: Area:各区域像素总和 Centroid: 各区域重心 ConvexHull:包括该区域的最小凸多边形 EquivDiameter:与该区域具有相同面积的圆的直径

Image:与某区域具有相同巨细的逻辑矩阵 FilledImage:与某区域具有相同巨细的填充逻辑矩阵 FilledArea:填充区域图画中的on像素个数

ConvexArea: 填充区域凸多边形图画中的on像素个数 EulerNumber:几许拓扑中的一个拓扑不变量——欧拉数 Extrema:八方向区域极值点’

Solidity: 一起在区域和其最小凸多边形中的像素份额’ Extent:一起在区域和其最小鸿沟矩形中的像素份额 PixelIdxList: 存储区域像素的索引下标 PixelList: 存储上述索引对应的像素坐标

BB1=struct2cell(BB);
把结构体数组转换成元胞数组,每个元胞元胞的元素为【x,y,w,h】

BB2=cell2mat(BB1);
将元胞打开为行数为一的矩阵,BB2中元素的个数为BB1的4倍

rectangle

rectangle(‘Position’,[x,y,w,h],’EdgeColor’,’y’,’LineWidth’,2) 该函数为选取框制作函数,【x,y,w,h】与上述参数含义相同 EdgeColor为色彩参数 LineWidth为边框线宽度参数 ‘Curvature’,[1,1]表明x,y方向上的曲率都为1,即为圆弧 Facecolor为内填充色彩参数 等等

总结

这个算法尽管仅仅经过玩弄这些像从来完成人脸检测,精度有限,但是如果想要进行后续的人脸辨认,这或许的一个减少手艺标注数据集的好办法