sábado, 15 de novembro de 2008

Técnicas clássicas de segmentação de pele humana

Enfim algum tempo livre... Vou aproveitar e fazer um post sobre uma das etapas do meu mestrado a segmentação da pele.

Vou apenas apresentar 3 formas de segmentação de pele e alguns resultados obtidos.

A imagem de teste é apresentada a seguir.



Espaço de cores RGB:

Um pixel pertence a pele se satisfizer as condições abaixo:

R > 95
G > 40
B > 20
max {R, G, B} − min {R, G, B} > 15
|R − G| > 15
R>G
R>B

Resultado da segmentação:



Espaço de cores YCbCr:

Um pixel pertence a pele se satisfizer as condições abaixo:

77 ≤ Cb ≤ 127
133 ≤ Cr ≤ 173

Resultado da segmentação:



Espaço de cores HSV:

Um pixel pertence a pele se satisfizer as condições abaixo:

0° ≤ H ≤ 50°
0, 23 ≤ S ≤ 0, 68

Resultado da segmentação:


Antes que alguém saia por aí dizendo que um método é melhor que outro, eu digo que depende da imagem a ser segmentada.

Os algoritmos apresentados são muito dependentes da iluminação do ambiente.

Para fechar, seguem os códigos do Scilab para segmentar imagens conforme apresentado.

/////////////////////////////////////////////////////////////////////////////////////////
// Algoritmos de segmentacao de pele em imagens baseados em limiarizacao
// Universidade Federal do Ceara
// Eng. Alex
//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//

//// parametros das imagens

Y = 2;
Cb = 1;
Cr = 3;

H = 1;
S = 2;
V = 3;

nL = 480; // numero de linhas da imagem
nC = 640; // numero de colunas da imagem


img = im2double(imread("imagem.jpg"));

////////////////////////////////////////
//parametros em RGB //
//////////////////////////////////////

img_s = zeros(nL, nC);

for l = 1:nL,
for c = 1:nC,
p = img(l,c,:);

ps = (p(1)>95/255).*(p(2)>40/255).*(p(3)>20/255).*(max(p) - min(p)>15/255).*(abs(p(1) - p(2))>15/255).*(p(1)==max(p));
img_s(l,c) = ps;
end;
end;

imwrite(img_s, "rgb-imagem.jpg");

///////////////////////////////////
//limiares em CbCr //
/////////////////////////////////

imgYCbCr = rgb2ycbcr(img);

img_s = double(((imgYCbCr(:,:,Cb)>76/255) .* (imgYCbCr(:,:,Cb)<128/255)).*((imgycbcr(:,:,cr)>132/255) .* (imgYCbCr(:,:,Cr)<174/255)));

imwrite(img_s, "cbcr-imagem.jpg");

///////////////////////////////
//limiares em HS //
/////////////////////////////

imgHSV = rgb2hsv(img);

img_s = double((imgHSV(:,:,H)<50/360).*((imghsv(:,:,s)>0.23) .* (imgHSV(:,:,S)<0.68)));

imwrite(img_s, "hs-imagem.jpg");

3 comentários:

jacky disse...

Hi, i am interested in the neural hand segmentation you posted in the youtube, would you mind to share the codes ?
Thank you.

Please contact me on leec0036@ntu.edu.sg

Alex Carneiro disse...

Hi Jacky, the ideia is too simple and is described here (in the blog).
But, if you want, I can post the code without any problem.

Thanks for the contact.

Anônimo disse...

This site has a interesting example for segmentation - gradient flood fill.

http://www.omatrix.com/iptgallery.html