%-----------------------基于肤色的人脸检测定位-----------------------------
clc ; clear ; close all ;
%--------------------------------------------------
A = imread( 'a.jpg');
subplot(2,2,1);imshow(A);title('原图');
A = double(A);
%--------------------转换颜色空间------------------
%RGB图像的红绿蓝三个分量
R = A( :, :, 1);
G = A( :, :, 2);
B = A( :, :, 3);
%将 RGB 图像的红色R、绿色G和蓝色B 转换为 HSV 图像的色调H、饱和度S和亮度V
[H, S , V] = rgb2hsv( A );
%将 RGB 图像的红色、绿色和蓝色值转换为 YCbCr 图像的亮度 (Y) 和色度(Cb 和 Cr)值
Y = 0.257*R + 0.504*G + 0.098*B + 16;
Cb = 0.148*R - 0.291*G + 0.439*B + 128;
Cr = 0.439*R - 0.368*G - 0.071*B + 128;
%----------------------找出皮肤区域---------------------
[m, n] = size( R ); %求出单一维度值的矩阵大小
skin = zeros(m, n);
for i = 1 : m
for j = 1 : n
if 145<=Cr(i,j)&&Cr(i,j)<=165&&...
145<=Cb(i,j)&&Cb(i,j)<=180&&...
0.01<=H(i,j)&&H(i,j)<=0.15
skin( i, j ) = 1; %皮肤区域
end
end
end
subplot(2,2,2);imshow(skin);title('皮肤区域位置');
%-------------------增强皮肤区域-------------------
%BW2=bwareaopen(BW,P),从二值图像BW中删除少于 P 个像素的所有连通分量(对象)
%即使消除零散细碎的皮肤区域
skin = bwareaopen( skin ,round( m*n/900 ));
%SE = strel("disk",r) 创建一个盘形结构元素,其中 r 指定半径
se = strel( 'disk', 5 );
%使用结构元素 SE 膨胀图像,增强明亮区域
skin = imdilate( skin, se );
%将皮肤区域转为彩色
color( :, : , 1) = R.*skin;
color( :, : , 2) = G.*skin;
color( :, : , 3) = B.*skin;
subplot(2,2,3);imshow(uint8(color));title('显示皮肤区域');
%------------------定位人脸图像--------------------
%L=bwlabel(BW) 返回标签矩阵 L,其中包含在 BW 中找到的 8 连通对象的标签。
L = bwlabel (skin , 8);
%返回二值图像 BW 中每个 8 连通分量(对象)的属性集的测量值
B = regionprops( logical(L), 'BoundingBox' );
%将结构体转换为元胞数组
B1 = struct2cell(B);
%将元胞数组转换为基础数据类型的普通数组
B2 = cell2mat(B1);
subplot(2,2,4);imshow(uint8(A));title('定位人脸图像');
[s1, s2 ] = size(B2);
for k = 3 : 4 : s2-1;
if (B2(1,k)/B2(1,k+1))<1.8 &&...
(B2(1,k)/B2(1,k+1))>0.4 &&...
(B2(1,k)*B2(1,k+1))>1000
hold on; %hold on作用是保持原图并接受此后绘制的新的曲线,叠加绘图
%rectangle('Position',pos) 在二维坐标中创建一个矩形。
%将 pos 指定为 [x y w h] 形式的四元素向量(以数据单位表示)。
% x 和 y 元素确定位置,w 和 h 元素确定大小。
rectangle ( 'Position', [B2(1,k-2),B2(1,k-1),B2(1,k),B2(1,k+1)],'EdgeColor', 'r');
end
end
%-----------------------------方法二-----------------------------------
%使用CascadeObjectDetector提供的官方Model实现对人脸区域的检测和定位,
clc ; clear ; close all ;
img= imread('a.jpg');
%创建一个人脸检测对象
faceDetector = vision.CascadeObjectDetector;
%找到人脸区域
%step调用 System object并运行该算法。根据您的 System object,step 可以返回输出参数。
box = step(faceDetector,img);
%标注人脸区域
face = insertObjectAnnotation(img,'rectangle',box,'Face','color' , 'r');
figure;
imshow(face);
title('人脸定位');