Обнаружение лиц на основе цвета
Существует большое количество задач, одной из составляющих которых является вопрос автоматического распознавания лиц на изображениях. Подходов к решению этого вопроса существует много, однако в рамках данного материала рассмотрим метод автоматического обнаружения лиц на изображениях на основе анализа цвета.
Считаем некоторое исходное изображение в рабочее пространство Matlab.
clear;
%Считывание исходного изображения
L=imread('im.jpg');
[N M s]=size(L);
L=double(L)./255;
figure, imshow(L);
title('Исходное изображение');
Далее необходимо на изображении лица выбрать пиксели с характерным цветом, определить среднее значение их интенсивности и среднеквадратическое отклонение.
[x,y,z]=impixel;
r=median(z(:,1)); std_r=std(z(:,1));
g=median(z(:,2)); std_g=std(z(:,2));
b=median(z(:,3)); std_b=std(z(:,3));
На основе знаний о значениях интенсивностей пикселей лица и их возможных вариациях проводится сегментация изображения.
%Сегментация на основе анализа цвета.
for i=1:N;
disp(i);
for j=1:M;
if (abs(L(i,j,1)-r)<std_r)&(abs(L(i,j,2)-g)<std_g)&(abs(L(i,j,3)-b)«std_b);
L1(i,j)=1;
else
L1(i,j)=0;
end;
end;
end;
figure, imshow(L1);title('Исходное изображение после сегментации');
Целью сегментации было выделение лица на изображении. Однако, вполне естественно, что на изображении присутствовали и другие объекты, значения интенсивностей пикселей которых совпали с интенсивностью пикселей лица. В результате на сегментированном изображении кроме лица выделились и другие объекты. Теперь на сегментированном изображении предстоит найти изображение нужного объекта, т.е. лица. Критерии поиска могут быть разными. Это может быть площадь, форма и др. В данном примере в качестве критерия для поиска лица выберем площадь. Исходя из выбранного ранее способа сегментации, можно предположить, что лицо занимает наибольшую площадь. Поэтому выбор критерия для поиска лица на основе площади позволит удалить другие объекты, которые меньше за площадью.
%Удаление объектов, площадь которых меньше некоторой заданной величины (для удаления шума)
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>750);
L1=ismember(mitka,idx);
figure,imshow(L1);title('После удаления шума (небольших объектов)');
Удалим также и другие объекты на сегментированном изображении лица.
L1=1-L1;
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>750);
L1=ismember(mitka,idx);
L1=1-L1;
figure,imshow(L1);
title('После удаления шума (небольших объектов)');
Здесь следует отметить, что выбранного нами критерия может быть недостаточно для достоверного определения объекта поиска, т.е. изображения лица. Такое может произойти в том случае, если на изображении присутствуют другие объекты с похожим цветом, лицо может быть в тени, быть под наклоном и т.п. Поэтому необходимо использовать также другие критерии для поиска изображения лица. Такие критерии могут базироваться на априорной информации о форме лица.
Таким образом, для повышения достоверности распознавания критерий поиска лица на изображении должен быть комплексным.
Далее проводим выделение выбранного лица, например, прямоугольником.
MIN_i=N;MIN_j=M;MAX_i=0;MAX_j=0;
for i=1:N;
disp(i);
for j=1:M;
if L1(i,j)==1;
if iMAX_i;
MAX_i=i;
end;
if j>MAX_j;
MAX_j=j;
end;
end;
end;
end;
figure, imshow(L);
line([MIN_j MAX_j],[MIN_i MIN_i]);hold on;
line([MAX_j MAX_j],[MIN_i MAX_i]);
line([MAX_j MIN_j],[MAX_i MAX_i]);
line([MIN_j MIN_j],[MIN_i MAX_i]);hold off;
Программа, реализующая приведенный выше метод:
%==========ОБНАРУЖЕНИЕ ЛИЦ НА ОСНОВЕ ЦВЕТА=======
clear;
%Считывание исходного изображения
L=imread('im.jpg');
[N M s]=size(L);
L=double(L)./255;
figure, imshow(L);title('Исходное изображение');
%Выбор пикселей лица с характерным цветом
[x,y,z]=impixel;
r=median(z(:,1)); std_r=std(z(:,1));
g=median(z(:,2)); std_g=std(z(:,2));
b=median(z(:,3)); std_b=std(z(:,3));
%Сегментация на основе анализа цвета
for i=1:N;
disp(i);
for j=1:M;
if (abs(L(i,j,1)-r)<std_r)&(abs(L(i,j,2)-g)<std_g)&(abs(L(i,j,3)-b)<std_b);
L1(i,j)=1;
else
L1(i,j)=0;
end;
end;
end;
figure, imshow(L1);title('Исходное изображение после сегментации');
%Удаление объектов, площадь которых меньше некоторой
заданной величины (для удаления шума)
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>750);
L1=ismember(mitka,idx);
figure,imshow(L1);title('После удаления шума (небольших объектов)');
L1=1-L1;
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>750);
L1=ismember(mitka,idx);
L1=1-L1;
figure,imshow(L1);title('После удаления шума (небольших объектов)');
%STATS = regionprops(L1,'Eccentricity');
MIN_i=N;MIN_j=M;MAX_i=0;MAX_j=0;
for i=1:N;
disp(i);
for j=1:M;
if L1(i,j)==1;
if iMAX_i;
MAX_i=i;
end;
if j>MAX_j;
MAX_j=j;
end;
end;
end;
end;
figure, imshow(L);
line([MIN_j MAX_j],[MIN_i MIN_i]);hold on;
line([MAX_j MAX_j],[MIN_i MAX_i]);
line([MAX_j MIN_j],[MAX_i MAX_i]);
line([MIN_j MIN_j],[MIN_i MAX_i]);hold off;
Если же на изображении присутствует несколько лиц одновременно, то рассмотренный выше метод необходимо модифицировать. Рассмотрим это более детально. Первые несколько шагов (считывание исходного изображения, выбор характерных пикселей, сегментация и фильтрация) аналогичны, как и в предыдущем методе, поэтому мы приведем только результаты выполнения этих операций.
Исходное изображение
Исходное изображение после сегментации
Изображение после фильтрации объектов, которые представлены пикселями со значениями равными 1.
Изображение после фильтрации объектов, которые представлены пикселями со значениями равными 0.
Далее необходимо проанализировать объекты на изображении. Сначала с помощью функции bwlabel определим общее количество объектов на изображении и отметим их.
Lmitky = bwlabel(L1,4);
figure,imshow(Lmitky);
Изображение меток
На основе анализа условий съемки и площадей отмеченных объектов определяем расположение лиц на изображении.
H=hist(Lmitky(:),max(max(Lmitky)));
Nomer=find(H>4000);
Конечно, для повышения достоверности определения лиц на изображении, нужно использовать также и другие критерии, которые могут базироваться на основе анализа формы изображения лица.
figure, imshow(L);
for r=2:length(Nomer);
MIN_i=N;MIN_j=M;MAX_i=0;MAX_j=0;
for i=1:N;
for j=1:M;
if Lmitky(i,j)==Nomer(r);
if iMAX_i;
MAX_i=i;
end;
if j>MAX_j;
MAX_j=j;
end;
end;
end;
end;
line([MIN_j MAX_j],[MIN_i MIN_i]);hold on;
line([MAX_j MAX_j],[MIN_i MAX_i]);
line([MAX_j MIN_j],[MAX_i MAX_i]);
line([MIN_j MIN_j],[MIN_i MAX_i]);hold off;
end;
Результат
Приведем еще один пример, подтверждающий то, что при распознавании лиц на изображения, нужно использовать более надежные критерии распознавания, нежели просто площадь. Доказательством тому служит изображение, которое приведено внизу. Распознавание изображения лица по яркости и площади привело к тому, что кроме лиц, выделились также и руки. Как уже было отмечено выше, для недопущения таких ошибок необходимо использовать также другие критерии, например, анализировать форму.
Модифицированная программа для обнаружения нескольких лиц на изображении:
%==========ОБНАРУЖЕНИЕ ЛИЦ НА ОСНОВЕ ЦВЕТА=======
clear;
%Считывание исходного изображения
L=imread('kids.bmp');
%L=imread('im.jpg');
[N M s]=size(L);
L=double(L)./255;
figure, imshow(L);title('Исходное изображение');
%Выбор пикселей лица с характерным цветом
[x,y,z]=impixel;
r=median(z(:,1)); std_r=std(z(:,1));
g=median(z(:,2)); std_g=std(z(:,2));
b=median(z(:,3)); std_b=std(z(:,3));
%Сегментация на основе анализа цвета
for i=1:N;
disp(i);
for j=1:M;
if (abs(L(i,j,1)-r)<std_r)&(abs(L(i,j,2)-g)<std_g)&(abs(L(i,j,3)-b)<std_b);
L1(i,j)=1;
else
L1(i,j)=0;
end;
end;
end;
figure, imshow(L1);title('Исходное изображение после сегментации');
imwrite(L1,'Исходное изображение после сегментации.jpg');
%Удаление объектов, площадь которых меньше
некоторой заданной величины (для удаления шума)
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>5750);
L1=ismember(mitka,idx);
figure,imshow(L1);title('После удаления шума (небольших объектов)');
L1=1-L1;
[mitka num]=bwlabel(L1,8);
feats=imfeature(mitka,'Area',8);
Areas=zeros(num);
for i=1:num;
Areas(i)=feats(i).Area;
end;
idx=find(Areas>5750);
L1=ismember(mitka,idx);
L1=1-L1;
figure,imshow(L1);title('После удаления шума (небольших объектов)');
%STATS = regionprops(L1,'Eccentricity');
Lmitky = bwlabel(L1,4);
figure,imshow(Lmitky);
imwrite(Lmitky,'Изображение меток.jpg');
figure, imshow(L);
H=hist(Lmitky(:),max(max(Lmitky)));
Nomer=find(H>4000);
for r=2:length(Nomer);
MIN_i=N;MIN_j=M;MAX_i=0;MAX_j=0;
for i=1:N;
for j=1:M;
if Lmitky(i,j)==Nomer(r);
if iMAX_i;
MAX_i=i;
end;
if j>MAX_j;
MAX_j=j;
end;
end;
end;
end;
line([MIN_j MAX_j],[MIN_i MIN_i]);hold on;
line([MAX_j MAX_j],[MIN_i MAX_i]);
line([MAX_j MIN_j],[MAX_i MAX_i]);
line([MIN_j MIN_j],[MIN_i MAX_i]);hold off;
end;
|