Álgebra Linear Aplicada A Reconhecimento Facial
Álgebra Linear Aplicada A Reconhecimento Facial
Álgebra Linear Aplicada A Reconhecimento Facial
2o ANO
Lista de ilustraes
Figura 1 Converso da foto original (750x500) para escala de cinza (470x336) . . 10 Figura 2 Foto aps translao e o primeiro autovetor da covarincia . . . . . . . 11 Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura Figura 3 Imagem 4 Imagem 5 Imagem 6 Imagem 7 Imagem 8 Imagem 9 Imagem 10 Imagem 11 Imagem 12 Imagem 13 Imagem 14 Imagem 15 Imagem 16 Imagem 17 Imagem 18 Imagem 19 Imagem 20 Imagem 21 Imagem 22 Imagem alvo e sua translao (ash) . . . . . . descomprimida e imagem mais prxima alvo e sua translao (bronzeado) . . . descomprimida e imagem mais prxima alvo e sua translao (zoom) . . . . . . descomprimida e imagem mais prxima alvo e sua translao (cabelo) . . . . . descomprimida e imagem mais prxima alvo e sua translao (foco) . . . . . . descomprimida e imagem mais prxima alvo e sua translao (altura) . . . . . descomprimida e imagem mais prxima alvo e sua translao (rotao) . . . . . descomprimida e imagem mais prxima alvo e sua translao (sujeira) . . . . . descomprimida e imagem mais prxima alvo e sua translao (tapa olho) . . . descomprimida e imagem mais prxima alvo e sua translao (combinado) . . . descomprimida e imagem mais prxima . . . . . . . . (ash) . . . . . . . . . . . . (bronzeado) . . . . . . . . . (zoom) . . . . . . . . . . . (cabelo) . . . . . . . . . . . (foco) . . . . . . . . . . . . (altura) . . . . . . . . . . . (rotao) . . . . . . . . . . (sujeira) . . . . . . . . . . . (tapa olho) . . . . . . . . . (combinado) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 14 14 15 15 16 16 17 17 17 18 18 19 19 19 20 20 21 21
Sumrio
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Introduo . . . . . . . . . . . . 1.1 lgebra Linear . . . . . . . 1.1.1 Projeo de Vetores . 1.1.2 Operador Linear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 2 2
1.2
1.1.3 Teorema Espectral . 1.1.4 Busca de Autovetores Estatstica . . . . . . . . . . 1.2.1 Valor Esperado . . . 1.2.2 Varincia . . . . . . 1.2.3 Covarincia . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
3 3 4 4 4 4 6 6 6 7 7
2 Anlise das Componentes Principais 2.1 Translao . . . . . . . . . . . . . 2.2 Diagonalizao . . . . . . . . . . 2.3 Projeo . . . . . . . . . . . . . . 2.4 Descompresso . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 Reconhecimento Facial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.1 Treinamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2 Reconhecimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4 Discusso 4.1 Teste 4.2 Teste 4.3 Teste 4.4 Teste 4.5 Teste 4.6 Teste 4.7 Teste 4.8 Teste 4.9 Teste 4.10 Teste . . . . . . . . . . do Flash . . . . . . do Bronzeado . . . do Zoom . . . . . do Cabelo . . . . . do Foco . . . . . . da Altura . . . . . da rotao . . . . da Sujeira . . . . . do Tapa Olho . . . Combinado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 14 15 15 16 17 18 19 20 21
Resumo
Ao transportar faces para um espao vetorial, podemos identicar um subespao que possua dimenso reduzida e preserve uma quantidade suciente de informao para manter a distino entre as faces. Com o mtodo da anlise das componentes principais (PCA - Principal Component Analysis), alm de comprimir os dados, destacamos o subespao que contm as caractersticas mais distintas de cada face, maximizando a preservao de informao. Aps introduzir a modelagem terica do PCA, feito um estudo de caso com uma implementao simples do algoritmo em linguagem C++ com o auxlio da biblioteca OpenCV. No estudo de caso so utilizadas 75 fotos em condies ideais para testes e 10 experimentos de tentativa de reconhecimento. Os testes tiveram os resultados mais diversos possveis, indicando a necessidade de outros algoritmos de processamento serem empregados antes de comear o PCA, entre eles deteco de rosto e deteco de bordas. A modelagem matemtica do algoritmo resultou uma resistncia a erros por parte de poluio visual aleatria no rosto dos indivduos, sendo uma consequncia de importante interpretao em termos de lgebra linear e estatstica.
1 Introduo
1.1 lgebra Linear
1.1.1 Projeo de Vetores
Sejam dois vetores u, v Rn , denimos a projeo ortogonal de v sobre u como: pru (v) = uv ||u|| (1.1)
A interpretao geomtrica desta projeo ortogonal a componente de v na direo de u. Ao denirmos uma base ortonormal U = {u1 , ..., un }, podemos escrever o vetor v nesta base usando as projees, conforme a equao: v=
n k=1
(1.2)
(v uk )uk
(1.3)
k=1
Portanto, podemos representar unicamente v na base U com o vetor vU = (u1 v, ..., un v). De forma semelhante, possvel expandir o conceito de projeo ortogonal para subespaos. Seja uma base ortonormal U = {u1 , ..., um } de um subespao F de Rn . A projeo de um vetor v em F : vF =
m
(v uk )uk
(1.4)
k=1
Qualquer transformao A : Rn Rn pode ser representada na forma de um produto matricial. Em particular, mudanas de base e projees so transformaes lineares.
Captulo 1. Introduo
Por exemplo, seja a matriz Fnm tal que seu i-simo vetor coluna ui denido para a equao (1.4). Podemos reescrever (1.4) na seguinte equao matricial: vF = F T v
(1.6)
Onde F T a matriz transposta de F . Dizemos que F T a representao matricial do operador linear de projeo sobre F .
Observando a equao (1.9), percebe-se que ela possui a forma AAT (Av) = (Av). Comparando com a equao (1.7), podemos enunciar o teorema:
Captulo 1. Introduo
Teorema 2 (Busca de Autovetores). Se v autovetor de AT A associado ao autovalor , Av autovetor de AAT associado ao mesmo autovalor . O teorema (2) mostra que embora a busca dos autovetores de AAT possa ser invivel computacionalmente, possvel realizar essa busca em AT A e a partir da, encontrar alguns autovetores de AAT . Quanto mais prximo k de n, mais autovetores podem ser encontrados desta forma.
1.2 Estatstica
1.2.1 Valor Esperado
O valor esperado de uma distribuio discreta uniforme dado por:
k 1 X= xi k i=1
(1.10)
Podemos denir o valor esperado sobre um conjunto de vetores X = {x1 , x2 , ..., xk } Rn de forma anloga: k 1 = xi (1.11) x k i=1 O nome valor esperado ou esperana vem do fato de que se os vetores representam dados obtidos experimentalmente, ao reproduzir o experimento esperamos que os novos dados estejam prximos a esse valor. No caso de distribuies discretas e uniformes, o valor esperado assume a forma de mdia aritmtica.
1.2.2 Varincia
A varincia de uma amostra uma medida da sua disperso estatstica, indicando a proximidade da distribuio de dados em relao ao valor esperado. , a varincia da distriDado o conjunto amostral discreto X de valor esperado X buio uniforme dada pela equao:
k 1 )2 (xi X var(X ) = k i=1
(1.12)
Uma amostra com alta varincia indica distribuies afastadas do valor mdio, enquanto uma varincia pequena indica um espao amostral pouco disperso.
1.2.3 Covarincia
A covarincia uma medida da correlao entre duas amostras. A covarincia pode indicar quando duas grandezas no esto correlacionadas, se tem crescimentos relacionados ou se possuem relao inversa.
Captulo 1. Introduo
Dados dois conjuntos amostrais de igual cardinalidade A e B , a covarincia de A e B de uma distribuio conjunta uniforme : cov (A, B ) =
k 1 )(bi B ) (ai A k i=1
(1.13)
Observando a equao (1.12), nota-se que cov (X, X ) = var(X ). Se a covarincia de duas variveis positiva, singica que seus valres crescem e decrescem juntos. Se a covarincia for negativa, o crescimento de uma varivel est associado a um decrescimento na outra. Se a covarincia zero, as variveis so descorrelacionadas. Ao lidar com objetos multidimensionais, para analisar a relao entre as dimenses comum utilizar a matriz de covarincia. Essa matriz sumariza as covarincias entre todas as dimenses e se mostra til em algoritmos de anlise estatstica de distribuies conjuntas. Deniremos a matriz de covarincia de um conjunto X de espaos amostrais Xi : i,j (X ) = cov (Xi , Xj ) (1.14)
A simetria da equao (1.14) indica que simtrica, mas possvel garantir mais do que isso, conforme o teorema a seguir: Teorema 3 (Positividade). A matriz de covarincia no-negativa: ela simtrica e todos seus autovalores so no-negativos. O teorema (3) juntamente com o teorema (1) garante que ao diagonalizar , todos os elementos da diagonal so maiores ou iguais a zero. A importncia (e uma justicativa intuitiva) deste fato se torna clara ao interpretar a diagonalizao da matriz de covarincia.
2.1 Translao
aplicando a equao (1.11); Clculo do vetor mdio x . construo de uma nova matriz Y onde yi = xi x Uma equao matricial que dene Y dada por Y =X X a matriz onde todas as colunas so iguais a x . onde X = 0. Isso signica que os dados Essa nova matriz Y possui mdia das colunas y foram transladados no espao de forma que o centride (vetor mdio) da distribuio esteja na origem. A justicativa para esse procedimento que para identicar as componentes principais na distino dos objetos, preciso analisar as diferenas entre um vetor e todo o conjunto. O vetor mdio rene as semelhanas entre os objetos da lista e, portanto, a diferena entre um vetor e o centride uma medida da distino desse objeto em relao ao espao amostral. (2.1)
2.2 Diagonalizao
Construo da matriz de covarincia (X );
busca dos autovetores e autovalores de . A matriz de covarincia nos informa as dependncias entre as dimenses que compem os vetores e pelo teorema (3), ela uma matriz diagonalizvel. Podemos ento encontrar uma base U de autovetores de que gera Rn . Pelo teorema (1), sabemos que a base U diagonaliza , ento ao mudarmos a representao dos vetores da base cannica para a base U, encontramos um conjunto de componentes que se usadas para decompor os vetores, geram uma matriz de covarincia diagonalizada. Como os elementos fora da diagonal na matriz de covarincia sero nulos, as novas dimenses componentes dos vetores passam a ser descorrelacionadas. Alm disso, os autovalores indicam as varincias das componentes geradas pelo autovetor associado. Isso signica que pelos autovalores podemos identicar quais autovetores abrangem dimenses com maior variao entre os vetores. Autovalores maiores esto associados a componentes de maior relevncia para distinguir os objetos.
2.3 Projeo
Escolha da base reduzida U = {u1 , ..., um }; projeo dos vetores de Y no subespao F = S (U ), conforme a equao (1.6). Escolhendo um subconjunto U U que contenha os autovetores associados aos maiores autovalores de , o subespao F ir conservar a maior parte da informao (e a capacidade de distinguir os objetos iniciais). Quanto menor a dimenso m de F , mais informao perdida. Porm, como essa perda minimizada pela escolha das componentes principais, F poder ter dimenso m n e descrever sucientemente bem a diferena entre os objetos e o centride. Aps projetar os vetores yi em F , obtemos uma nova matriz ZmN onde zi = yiF . Podemos resumir a aplicao da equao (1.6) na seguinte equao matricial: Z = FTY (2.2)
2.4 Descompresso
Para descomprimir os dados projetados no subespao F , basta notar que como F possui vetores coluna ortonormais e se o vetor projetado estava prximo ao subespao F (quer dizer, perdeu pouca informao ao ser projetado), acontecer F F T Inn .
Da, se multiplicamos a equao (2.2) por F esquerda, podemos predizer a seguinte aproximao: Y FZ (2.3) Relembrando a equao (2.1), a equao (2.3) pode ser reescrita como: X FZ + X Ou de forma equivalente: xi F zi + x (2.5) (2.4)
3 Reconhecimento Facial
O algoritmo de reconhecimento facial baseado no PCA se divide em dois mecanismos principais: preparao e reconhecimento. A execuo da preparao o nico momento onde o PCA efetivamente executado, enquanto no mecanismo de reconhecimento ocorre a tentativa de identicar uma imagem de entrada como uma das imagens armazenadas no banco de dados. Caso o reconhecimento falhe ou a identicao no tenha sido precisa, possvel um mecanismo de aprendizado: a imagem que falhou nos testes de reconhecimento pode ser adicionada como novo objeto no banco de dados (cadastro) sem necessitar realizar o PCA novamente. Para isso, basta projetar a nova imagem no subespao escolhido e adicionar este caso de testes. O mecanismo de aprendizado acessrio, pois em sistemas com baixa rotatividade de dados vivel adicionar as novas imagens manualmente no banco de dados e refazer a etapa de preparao. No apndice A consta uma implementao das etapas do software de reconhecimento facial em C++ com auxlio da biblioteca OpenCV, cujos comentrios indicam cada um dos procedimentos descritos. Nas sees a seguir, feito um estudo de caso com 75 imagens obtidas de alunos do Instituto Militar de Engenharia durante o primeiro ano do ciclo bsico. A qualidade das imagens para o estudo de caso ideal (posio do rosto padronizada para fotos 3x4 e cortes de cabelo padronizados pelo Exrcito Brasileiro). O aspecto positivo destas circunstncias que o algoritmo ter sua modelagem terica testada em condies timas, dando conabilidade aos resultados. O aspecto negativo que os resultados no reetem diretamente o esperado em aplicaes reais. Para analisar o comportamento do algoritmo em outras situaes, so feitos testes com diferentes luminosidades e posicionamentos. Embora a qualidade das imagens seja ideal, seria necessrio um pr-processamento demasiado complexo para garantir a real aplicabilidade do PCA que no condiz com a realidade de uma curta implementao. Todas as imagens deveriam passar por um algoritmo de deteco de contornos para eliminar todas as informaes visuais que no sejam da face (cabelo, fundo, pescoo etc.) e um algoritmo de posicionamento que centralizasse um ponto em comum a todas as imagens, como a ponta do nariz em um lugar especco. Como tais recursos no foram implementados por sua complexidade e por estarem fora do escopo do trabalho, so analisados 10 testes onde diferentes fontes de erro no reco-
10
nhecimento so propositalmente inseridos em uma imagem usada como caso de controle. Sendo esta imagem parte do prprio banco de treinamento do algoritmo, ela consiste no melhor caso possvel para facilidade de acerto pelo algoritmo. A etapa de treinamento do algoritmo cria os objetos necessrios durante a etapa reconhecimento. Com uma quantidade inicial de faces armazenadas, realiza-se o PCA sobre este espao amostral conhecido. So xados ento o vetor mdio, a matriz de projeo F T conforme as equaes (1.11) e (1.6) e tambm os autovalores correspondentes. Alm do pr-processamento das imagens, a etapa de diagonalizao no PCA ser otimizada computacionalmente com o uso do teorema (2), viabilizando a execuo do algoritmo em qualquer computador pessoal. A etapa de preparao crtica em termos de custo computacional, principalmente pelo custo de processamento para fazer produtos matriciais e resolver o autosistema.
3.1 Treinamento
Ao carregar as imagens do banco de dados, elas so convertidas para escala de cinza. mais fcil trabalhar com imagens de um s canal de cores para que cada pixel necessite de apenas um nmero (e portanto seja representado por uma matriz). Para melhorar a eccia do PCA, as fotos tambm foram cortadas para focar na regio do rosto e eliminar a inuncia das roupas.
No cdigo apresentado no apndice A est implementada a funo CarregarImagensTreinamento() que l as imagens de uma pasta com o auxlio da biblioteca OpenCV e as converte para matrizes j na forma de escala de cinza. As imagens so vetorizadas
11
e armazenadas nas colunas de uma matriz X . Esta funo chamada na rotina Treinamento(), que logo aps o carregamento chama a funo FazerPCA(). Em seguida calculado o vetor mdio xM ed e criada a matriz Y dos vetores de 1 X transladados. Como a matriz covarincia de X dada por n Y Y T e teria dimenso 157920 157920, utiliza-se o teorema (2) para calcular os autovetores de Y T Y , chamando esta matriz de CovAux. A funo eigen() da biblioteca OpenCV retorna os autovetores nas linhas de aV ec e os autovalores respectivos nas linhas de aV al. Em seguida, a matriz aV ac transposta e multiplicada por Y para obtermos a matriz F cujos vetores coluna so os autovetores da matriz da covarincia. Os autovetores so em seguida normalizados para que as colunas de F sejam uma base ortornomal do subespao gerado pelas fotos iniciais. Como essa busca alternativa para autovetores permite que sejam encontrados apenas 75, nenhum deles foi descartado para maximizar a qualidade da compresso.
Em seguida, a matriz de projeo F t construda como a transposta de F e projetamos as imagens transladadas na matriz Z . A funo ArmazenarDadosTreinamento() executada e a matriz de projeo, o vetor mdio, os vetores do espao amostral e os autovalores so armazenados num arquivo binrio chamado "resultados".
3.2 Reconhecimento
Ao iniciar o programa no modo de reconhecimento, a imagem alvo carregada em escala de cinza e as informaes do arquivo "resultados"so lidas, construindo a matriz de projeo F t, o vetor mdio xM ed e o vetor dos autovalores aV al. A imagem alvo
12
vetorizada e chamada a rotina BuscaVizinhos(), que encontra os trs vetores do subespao F mais prximos do alvo projetado utilizando a funo Metrica() para calcular as distncias. Para calcular a distncia entre as imagens projetadas no subespao escolhido no utilizada a mtrica euclidiana. O trabalho de Moon (2001) sobre a aplicao do PCA em reconhecimento facial mostra uma maior ecincia utilizando a mtrica de Mahalanobis, dada por: x y )1 ( x y) d( x, y ) = ( onde a matriz de covarincia. Como a mudana de base diagonalizou , temos a chamada distncia euclidiana normalizada: d( x, y) =
n
(xi yi )2 2 i i=1
Esta mtrica se torna mais eciente por levar em considerao as varincias das componentes como uma forma de atribuio de pesos no clculo da distncia. Se uma componente tem varincia alta, um grande desvio nessa componente j era esperado e no relevante. Se uma componente tem varincia pequena, um desvio nessa componente um fator que deve ser evidenciado na mtrica de Malahanobis. Esta mtrica est implementada na funo Metrica().
13
4 Discusso
Como era de se esperar do algoritmo sem as etapas de pr-processamento exigidas, ele apresentou quase total impossibilidade de implementao. Para evidenciar os pontos positivos e negativos do algoritmo, foram escolhidos dez casos teste para representar possveis problemas a serem enfrentados.
O algoritmo respondeu corretamente. A distncia entre o alvo e a imagem correta foi de 9, 67.1016 e para a segunda imagem mais prxima foi 1, 99.1017 . Como a segunda
Captulo 4. Discusso
14
distncia mais que 200% da distncia para a imagem correta, pode-se considerar um bom acerto.
O algoritmo respondeu errado. Ele respondeu com uma pessoa que de fato mais morena que o alvo na vida real. Isso pode indicar que o algoritmo sensvel, mas mantm a delidade com a foto. De fato, a menor distncia encontrada foi 1, 88.1017 e a distncia para a resposta correta foi a segunda menor, 1, 94.1017 . Sendo a resposta correta o segundo palpite do reconhecimento, com um erro de apenas 3%, pode-se considerar um erro justo com a diculdade do teste.
Captulo 4. Discusso
15
O algoritmo respondeu errado. A mudana da distncia relativa entre as principais feies (olhos, nariz, boca, orelhas) fez com que o algoritmo nem sequer tenha colocado a imagem correta entre as trs principais candidatas no reconhecimento. A distncia entre o alvo e a imagem resposta foi de 6, 59.1016 , que menor que a distncia entre o alvo e a imagem correta no teste do bronzeado. Isso mostra que a posio relativa das feies determinante no reconhecimento.
Captulo 4. Discusso
16
da cabea do indivduo e cause um erro grande. A imagem de controle teve seu cabelo incrementado e foi submetida ao algoritmo de reconhecimento.
O algoritmo respondeu errado. Como era de se esperar, o algoritmo respondeu com um rosto de uma pessoa com mais cabelo e formato do crnio mais condizente com a imagem alvo. Esse teste mostra a dependncia do algoritmo de um pr-processamento que elimine feies mutveis como o cabelo ou o penteado de uma pessoa.
Captulo 4. Discusso
17
O algoritmo respondeu errado. A imagem dada como resposta pelo algoritmo est
Captulo 4. Discusso
18
de acordo com o posicionamento da imagem alvo, enquanto a imagem correta nem est entre os 3 melhores candidatos. Nota-se claramente que um pr-processamento que centralize uma informao nas imagens necessrio (como a ponta do nariz). Desse modo, o posicionamento deixa de ser um fator de desvio, j que de todo modo a posio das imagens foi padronizada.
O algoritmo respondeu corretamente. Este resultado contraintuitivo, j que contraria o resultado do teste da altura na relevncia da centralizao de uma feio. Entretanto, as fotos so muito mais propcias a grandes desvios de posicionamento vertical e horizontal do que as pessoas so propensas a um desvio angular no pescoo. Portanto, o acerto neste caso se depende ao baixo risco do caso e a baixa amplitude de incidncia de rotao.
Captulo 4. Discusso
19
O algoritmo respondeu corretamente. Como a imagem diferiu pouco da imagem controle do banco de dados e criou padres que nenhuma outra imagem do banco de
Captulo 4. Discusso
20
treinamento possua, as modicaes foram perdidas durante a projeo. Dessa forma, o mtodo se mostra resistente a padres anormais em imagens.
O algoritmo respondeu corretamente. A imagem controle sofreu uma grande interveno grca, diferentemente do teste do cabelo, o padro inserido na imagem no apresentado por nenhuma imagem do banco de dados. Isso fez com que essa informao fosse perdida, como no teste da sujeira. A distncia entre alvo e imagem correta foi de 1, 23.1016 e o segundo candidato estava a uma distncia de 9, 90.1016 , quase dez vezes maior.
Captulo 4. Discusso
21
O algoritmo respondeu errado. Inverter a imagem horizontalmente causou um efeito semelhante ao teste da altura, visto que a posio inicial do rosto do alvo estava ligeiramente para direita e depois de espelhada, foi jogada para a esquerda. Consequentemente o algoritmo respondeu com um rosto que estava mais pro lado esquerdo. Assim, ca ressaltada a grande relevncia do posicionamento das imagens como etapa de prprocessamento.
22
5 Concluso
O algoritmo possui um modelo matemtico multidisciplinar e pode ser compreendido por qualquer aluno do ciclo bsico de engenharia. Entretanto, para que funcione com preciso satisfatria, necessrio envolver outros algoritmos de processamento de imagens como deteco de rosto, contornos e centralizao de uma informao padronizada em todas as imagens. Os testes indicam que um bom controle do posicionamento das feies corporais essencial e dever melhorar signicativamente o desempenho do algoritmo, que no se mostrou to vulnervel a modicaes na imagem exceto no caso de crescimento de cabelo. Para esta situao, deve ser utilizado deteo de bordas para eliminar o cabelo e focar nas feies faciais. Um problema a considerar no caso de proximidade da cmera, resultando em ampliao da imagem. No h maneira priori de decidir se uma imagem est com escala condizente e portanto, seria ideal padronizar a distncia entre a cmera e o alvo, inclusive na gerao das imagens do banco de treinamento. Tendo se sado bem nos testes de brilho, foco, rotao e poluio visual, o algoritmo rendeu resultados satisfatrios. Sua implementao poderia ter sido muito menos custosa, pois a biblioteca OpenCV inclui a funo PCA totalmente pronta. Entretanto, para ns de aprendizado, houve um esforo de usar poucas funes prontas e implementou-se manualmente maior parte do cdigo presente no apndice A. Um dos testes mais signicativos foi o de poluio visual com um tapa olho. Neste teste ca evidente o conceito de projeo e a relevncia do desvio estatstico em um espao amostral. Aps a descompresso da imagem, no havia sinal especco de nenhum acessrio pirata.
23
APNDICE A
/ \ [ Algoritmo de Reconhecimento Facial baseado em PCA (Eigenfaces) ] \ /
5
10
" opencv2 / core / core . hpp " " opencv2 / highgui / highgui . hpp " " opencv2 / contrib / contrib . hpp " < iostream > < cstring > < cstdio > < fstream > < sstream >
15
20
25
30
/ [ Manual de Referenciasl ] / void Ajuda () ; / Imprime o modo de uso do programa (chamada e argumentos necessarios) / void PrintVec ( Mat * , Size , int , int , const char * , bool ) ; / Abre uma janela e mostra a kesima imagem (coluna k) de X usando WaitKey(s) / void Treinamento () ; / Primeiro modo de execucao do programa. Apos chamar CarregarImagensTreinamento() inicia a funcao FazerPCA() / int C a r r e g a r I m a g e n s T r e i n a m e n t o ( Mat * , Size *) ; / Carrega as imagens de data.txt e retorna a quantidade de imagens carregadas / void FazerPCA ( Mat * , Size , int ) ; / Calcula a media, autovalores e autovetores necessarios para a projecao e inicia a funcao ArmazenarDadosTreinamento / void A r m a z e n a r D a d o s T r e i n a m e n t o ( int , Size , Mat * , Mat * , Mat * , Mat *) ; / Armazena em um arquivo binario o numero de autovetores, dimensao das imagens, a matriz de projecao, os autovalores, o vetor madio e o banco de dados ja projetado no arquivo "resultados" /
Captulo 5. Concluso
24
35
40
45
void Reconhecimento ( char *) ; / Segundo modo de execucao do programa. Carrega a imagem com nome dado e itera Metrica pelos dados. / void O b t e r D a d o s T r e i n a m e n t o ( int * , Size * , Mat * , Mat * , Mat * , Mat *) ; / Le o numero de autovetores, dimensao das imagens, a matriz de projecao, os autovalores e o vetor madio do arquivo "resultados" / double Metrica ( Mat * , int , Mat * , Mat *) ; / Retorna a distancia entre o iasimo vetor coluna de Z e o vetor y utilizando a matrica de Malhanobis / int BuscaVizinhos ( Mat * , Mat * , Mat *) ; / Utiliza Metrica() para varrer o banco de dados projetado e imprime as 3 projecoes mais proximas do vetor dado / / [ Implementacao ] /
50
55
60
int main ( int argc , char ** argv ) { if ( argc < 2 ) { Ajuda () ; return -1; } if ( ! strcmp ( argv [1] , " treinar " ) ) Treinamento () ; else if ( ! strcmp ( argv [1] , " reconhecer " ) && argv [2]!= NULL ) Reconhecimento ( argv [2]) ; else { cout << " > Comando desconhecido : " << argv [1] << endl ; Ajuda () ; } return 0; } void Ajuda () { cout << " > Uso : facerec < comando >\ n Comandos validos :\ n treinar \ n reconhecer < arquivo > " << endl ; }
65
70
void PrintVec ( Mat *X , Size dimImg , int col , int time , const char * filename , bool save ) { Mat temp ; int i , j ; char exemplo [100]; FILE * data ; data = fopen ( " Data / data . txt " ," r " ) ; fscanf ( data , " % d %[^\ n ] " ,&i , exemplo ) ; temp = imread ( exemplo ,0) ; fclose ( data ) ; for ( i =0; i < dimImg . height ; i ++) for ( j =0; j < dimImg . width ; j ++)
Captulo 5. Concluso
25
75
80
temp . data [ i * temp . step + j ] = fabs (X - > at < double >( i * dimImg . width +j , col ) ) ; if ( time >=0) { namedWindow ( filename ) ; imshow ( filename , temp ) ; waitKey ( time ) ; destroyWindow ( filename ) ; } if ( save ) imwrite ( filename , temp ) ; }
85
90
void Treinamento () { int nFaces ; Size dimImg ; Mat X ; cout << " > Comecando treinamento do algoritmo ... " << endl ; nFaces = C a r r e g a r I m a g e n s T r e i n a m e n t o (& X , & dimImg ) ;
95
FazerPCA (& X , dimImg , nFaces ) ; cout << " < Treinamento completo , fim da execucao . " << endl ; }
100
int C a r r e g a r I m a g e n s T r e i n a m e n t o ( Mat * X , Size * dimImg ) { cout << " >> Carregando imagens do arquivo data . txt ... " << endl ; Mat tempImg ; FILE * listaTreino = 0 ; char nomeImg [100]; int i , j , k , ID , nFaces =0; if ( ( listaTreino = fopen ( " Data / data . txt " ," r " ) ) == NULL ) { cout << " >>> Arquivo data . txt nao encontrado ! " << endl ; exit (1) ;}
105
110
while ( fgets ( nomeImg ,100 , listaTreino ) ) nFaces ++; rewind ( listaTreino ) ; if ( nFaces < 2) { printf ( " >> Treinamento requer mais imagens .\ n encontradas % d \ n " , nFaces ) ; exit (1) ;
115
>>> Foram
Captulo 5. Concluso
26
}
120
fscanf ( listaTreino , " % d %[^\ n ] " ,& ID , nomeImg ) ; tempImg = imread ( nomeImg ,0) ; dimImg - > height = tempImg . rows ; dimImg - > width = tempImg . cols ; rewind ( listaTreino ) ; X - > create ( dimImg - > height * dimImg - > width , nFaces , CV_64FC1 ) ; namedWindow ( " Carregando ... " ) ; for ( i =0; i < nFaces ; i ++) { fscanf ( listaTreino , " % d %[^\ n ] " ,& ID , nomeImg ) ; tempImg = imread ( nomeImg ,0) ; imshow ( " Carregando ... " , tempImg ) ; waitKey (20) ; for ( j =0; j < dimImg - > height ; j ++) for ( k =0; k < dimImg - > width ; k ++) X - > at < double >( j * tempImg . step +k , i ) = tempImg . data [ j * tempImg . step + k ]; } destroyWindow ( " Carregando ... " ) ; fclose ( listaTreino ) ; printf ( " << Carregamento completo , % d imagens % dx % d obtidas .\ n " , nFaces , dimImg - > height , dimImg - > width ) ; PrintVec (X ,* dimImg ,0 , -1 , " rosto1 . png " , true ) ; PrintVec (X ,* dimImg ,1 , -1 , " rosto2 . png " , true ) ;
125
130
135
140
145
return nFaces ; } void FazerPCA ( Mat *X , Size dimImg , int nFaces ) { cout << " >> Comecando analise das componentes principais ... " << endl ; Mat F , Ft , Z , aVal , aVec , xMed , Y ; int i , j ; double norm ;
150
155
160
cout << " >>> Calculando rosto madio ... " ; xMed . create ( dimImg . height * dimImg . width , 1 , CV_64FC1 ) ; for ( i =0; i < dimImg . height * dimImg . width ; i ++) { xMed . at < double >( i ,0) = 0;
Captulo 5. Concluso
27
for ( j =0; j < nFaces ; j ++) xMed . at < double >( i ,0) += X - > at < double >( i , j ); xMed . at < double >( i ,0) /= nFaces ; } cout << " [ OK ] " << endl ; PrintVec (& xMed , dimImg ,0 ,0 , " rostomedio . png " , true ) ; cout << " >>> Calculando matriz transladada ... " ; Y . create ( dimImg . height * dimImg . width , nFaces , CV_64FC1 ) ; for ( i =0; i < dimImg . height * dimImg . width ; i ++) for ( j =0; j < nFaces ; j ++) Y . at < double >( i , j ) = X - > at < double >( i , j ) - xMed . at < double >( i ,0) ; cout << " [ OK ] " << endl ; PrintVec (& Y , dimImg ,0 ,0 , " rostotrans1 . png " , true ) ; PrintVec (& Y , dimImg ,1 ,0 , " rostotrans2 . png " , true ) ; cout << " >>> Calculando auxiliar da covariancia ... " ; Mat CovAux ; mulTransposed (Y , CovAux , true ,0 ,1 , -1) ; cout << " [ OK ] " << endl ; cout << " >>> Resolvendo o Autosistema ... " ; eigen ( CovAux , aVal , aVec ) ; transpose ( aVec , aVec ) ; F = Y * aVec ; PrintVec (& F , dimImg ,0 ,0 , " autovetor1 . png " , true ) ; PrintVec (& F , dimImg ,1 ,0 , " autovetor2 . png " , true ) ; cout << " [ OK ] " << endl ; cout << " >>> Normalizando a base de autovetores ... " ; for ( j =0; j < F . cols ; j ++) { for ( i =0 , norm =0; i < F . rows ; i ++) if ( fabs ( F . at < double >( i , j ) ) > norm ) norm = fabs ( F . at < double >( i , j ) ) ; for ( i =0; i < F . rows ; i ++) F . at < double >( i , j ) /= norm ; for ( i =0 , norm =0; i < F . rows ; i ++) norm += F . at < double >( i , j ) * F . at < double >( i , j ) ; for ( i =0 , norm = sqrt ( norm ) ;i < F . rows ; i ++) F . at < double >( i , j ) /= norm ; } cout << " [ OK ] " << endl ;
200
165
170
175
180
185
190
195
cout << " >>> Projetando as imagens de treinamento ... " ; transpose (F , Ft ) ; Z = Ft * Y ; cout << " [ OK ] " << endl ;
Captulo 5. Concluso
28
205
210
cout << " >>> Imagem para visualizacao da qualidade da compressao . " << endl ; Mat xbar ; xbar = F * Z ; for ( i =0; i < xbar . rows ; i ++) for ( j =0; j < xbar . cols ; j ++) { xbar . at < double >( i , j ) += xMed . at < double >( i ,0) ; if ( xbar . at < double >( i , j ) >255) xbar . at < double >( i , j ) = 255; if ( xbar . at < double >( i , j ) <0) xbar . at < double >( i , j ) = 0;} PrintVec (& xbar , dimImg ,0 ,0 , " descompress1 . png " , true ) ; PrintVec (& xbar , dimImg ,1 ,0 , " descompress2 . png " , true ) ; A r m a z e n a r D a d o s T r e i n a m e n t o ( nFaces , dimImg ,& Ft ,& aVal ,& xMed ,& Z ) ; cout << " << Fim do PCA " << endl ; } void A r m a z e n a r D a d o s T r e i n a m e n t o ( int nFaces , Size dimImg , Mat * Ft , Mat * aVal , Mat * xM , Mat * Z ) { cout <<" >>> Armazenando dados de treinamento ... " << endl ; FILE * dadosFinais ; int i , j ; if ( ( dadosFinais = fopen ( " resultados " ," wb " ) ) == NULL ) { cout << " >>>> Falha no arquivo resultados ! " << endl ; exit (1) ;} fwrite (& nFaces , sizeof ( nFaces ) ,1 , dadosFinais ) ; fwrite (& dimImg , sizeof ( Size ) ,1 , dadosFinais ) ; for ( i =0; i < Ft - > rows ; i ++) for ( j =0; j < Ft - > cols ; j ++) fwrite (& Ft - > at < double >( i , j ) , sizeof ( double ) ,1 , dadosFinais ) ; for ( i =0; i < nFaces ; i ++) fwrite (& aVal - > at < double >( i ,0) , sizeof ( double ) ,1 , dadosFinais ) ; for ( i =0; i < xM - > rows ; i ++) fwrite (& xM - > at < double >( i ,0) , sizeof ( double ) ,1 , dadosFinais ) ; for ( i =0; i <Z - > rows ; i ++) for ( j =0; j <Z - > cols ; j ++) fwrite (& Z - > at < double >( i , j ) , sizeof ( double ) ,1 , dadosFinais ) ; fclose ( dadosFinais ) ; cout << " <<< Dados armazenados em resultados ! " << endl ; } void O b t e r D a d o s T r e i n a m e n t o ( int * nFaces , Size * dimImg , Mat * Ft , Mat * aVal , Mat * xM , Mat * Z ) { cout << " >> Obtendo resultados do ultimo treinamento ... " << endl ; FILE * dados ; int i , j ;
215
220
225
230
235
240
Captulo 5. Concluso
29
245
if ( ( dados = fopen ( " resultados " ," rb " ) ) == NULL ) { cout << " Arquivo resultados nao encontrado ! " << endl ; exit (1) ;} fread ( nFaces , sizeof ( int ) ,1 , dados ) ; fread ( dimImg , sizeof ( Size ) ,1 , dados ) ; cout << " << " << * nFaces << " imagens " << * dimImg << " utilizadas no ultimo treinamento " << endl ;
>>>
250
Ft - > create (* nFaces , dimImg - > height * dimImg - > width , CV_64FC1 ) ; aVal - > create (* nFaces ,1 , CV_64FC1 ) ; xM - > create ( Ft - > cols ,1 , CV_64FC1 ) ; Z - > create (* nFaces ,* nFaces , CV_64FC1 ) ;
255
260
for ( i =0; i < Ft - > rows ; i ++) for ( j =0; j < Ft - > cols ; j ++) fread (& Ft - > at < double >( i , j ) , sizeof ( double ) ,1 , dados ) ; for ( i =0; i <* nFaces ; i ++) fread (& aVal - > at < double >( i ,0) , sizeof ( double ) ,1 , dados ) ; for ( i =0; i < xM - > rows ; i ++) fread (& xM - > at < double >( i ,0) , sizeof ( double ) ,1 , dados ) ; for ( i =0; i <Z - > rows ; i ++) for ( j =0; j <Z - > cols ; j ++) fread (& Z - > at < double >( i , j ) , sizeof ( double ) ,1 , dados ) ; fclose ( dados ) ; }
265
270
void Reconhecimento ( char * arquivo ) { cout << " > Iniciando funcao de reconhecimento ... " << endl ; int nFaces , i , j ; Size dimImg ; Mat Ft ,Z , xMed , aVal , alvo , proj ; alvo = imread ( arquivo ,0) ; dimImg . height = alvo . rows ; dimImg . width = alvo . cols ; if (! dimImg . height ) { cout << " >> Carregamento da imagem alvo falhou ! " << endl ; exit (1) ;} O b t e r D a d o s T r e i n a m e n t o (& nFaces ,& dimImg ,& Ft ,& aVal ,& xMed ,& Z ) ;
275
280
285
cout << " >> Projetando alvo ... " ; proj . create ( dimImg . width * dimImg . height ,1 , CV_64FC1 ) ; for ( i =0; i < dimImg . height ; i ++) for ( j =0; j < dimImg . width ; j ++) proj . at < double >( i * alvo . step + j ) = alvo . data [ i * alvo . step + j ]; PrintVec (& proj , dimImg ,0 ,0 , " alvo . png " , false ) ; proj = proj - xMed ; PrintVec (& proj , dimImg ,0 ,0 , " alvotrans . png " , true ) ;
Captulo 5. Concluso
30
295
Mat F , desc ; transpose ( Ft , F ) ; desc = F * proj ; PrintVec (& desc , dimImg ,0 ,0 , " alvodesproj . png " , false ) ; desc = desc + xMed ; for ( i =0; i < desc . rows ; i ++) { if ( desc . at < double >( i ,0) >255) desc . at < double >( i ,0) = 255; if ( desc . at < double >( i ,0) <0) desc . at < double >( i ,0) = 0;} PrintVec (& desc , dimImg ,0 ,0 , " alvodescomp . png " , true ) ; int rec ; Mat imrec ( proj . rows ,1 , CV_64FC1 ) ; rec = BuscaVizinhos (& Z ,& proj ,& aVal ) ; for ( i =0; i < imrec . rows ; i ++) imrec . at < double >( i ,0) = Z . at < double >( i , rec ) ; imrec = F * imrec + xMed ; for ( i =0; i < imrec . rows ; i ++) { if ( imrec . at < double >( i ,0) >255) imrec . at < double >( i ,0) = 255; if ( imrec . at < double >( i ,0) <0) imrec . at < double >( i ,0) = 0;} PrintVec (& imrec , dimImg ,0 ,0 , " alvorec . png " , true ) ;
300
305
310
cout << " > Reconhecimento concluido , fim da execucao . " << endl ; } int BuscaVizinhos ( Mat *Z , Mat * proj , Mat * aVal ) { cout << " >> Buscando imagens mais proximas ... " << endl ; int i , c1 =0 , c2 =1 , c3 =2; double d , min1 , min2 , min3 , aux ; min1 = Metrica (Z ,0 , proj , aVal ) ; min2 = Metrica (Z ,1 , proj , aVal ) ; min3 = Metrica (Z ,2 , proj , aVal ) ; for ( i =3; i <Z - > cols ; i ++) { d = Metrica (Z ,i , proj , aVal ) ; if (d < min1 ) { min3 = min2 ; min2 = min1 ; min1 = d ; c3 = c2 ; c2 = c1 ; c1 = i ;} else if (d < min2 ) { min3 = min2 ; min2 = d ; c3 = c2 ; c2 = i ;} else if (d < min3 ) { min3 = d ; c3 = i ;} } cout << " >>> Primeiro candidato : " << c1 << " ; Distancia : " << min1 << endl ;
315
320
325
330
Captulo 5. Concluso
31
cout << " >>> Segundo candidato : " << c2 << " ; Distancia : " << min2 << endl ; cout << " >>> Terceiro candidato : " << c3 << " ; Distancia : " << min3 << endl ; return c1 ; }
335
double Metrica ( Mat *X , int col , Mat *y , Mat * S ) { int i ; 340 double D =0; for ( i =0; i <X - > rows ; i ++) D += pow (X - > at < double >( i , col ) -y - > at < double >( i ,0) ,2) *S - > at < double >( i ,0) ; return D ; }
32
REFERNCIAS
LIMA, Elon Lages. lgebra Linear. 8. ed. Rio de Janeiro: IMPA, 2012. MAGALHES, Marco N. Probabilidade e Variveis Aleatrias. 3. ed. So Paulo: Editora da Universidade de So Paulo, 2013. MOON H., PHILLIPS P.J. Computational and Performance aspects of PCAbased Face Recognition Algorithms. Perception, Vol. 30, 2001, pp. 303-321 TURK, M., PENTLANDO A. Eigenfaces for Recognition. Journal of Cognitive Neurosicence, Vol. 3, No. 1, 1991, pp. 71-86