Reconocimiento facial con los componentes MITOV en Delphi




He estado probando los componentes MITOV y he quedado asombrado con lo que pueden hacer, tienen un nivel de abstracción muy alto, con pocas instrucciones se pueden realizar programas complejos (algo parecido al Livebinding de Delphi) lo que a los programadores seguro nos facilitará mucho el desarrollo de software.

En palabras de Boian Mitov, propietario y CEO de Mitov. Software. "Estos componentes ofrecen una combinación única de compilación multiplataforma nativa y características avanzadas de lenguaje moderno como RTTI avanzado por esto Delphi ha permitido implementar componentes de inteligencia artificial multiplataforma potentes y de alto rendimiento".

Jim McKeeth, jefe de desarrollo e ingeniero de Embarcadero dijo "Me encanta que IntelligenceLab de Mitov Software tome algo tan complejo como las redes neuronales y la inteligencia artificial y lo haga accesible a través de componentes reutilizables, ahora todos nuestros desarrolladores pueden agregar redes neuronales avanzadas y otros clasificadores de IA a sus aplicaciones multiplataforma". 




La licencia es gratuita para uso educativo y no comercial.






Seguidamente les mostraré cómo se hace un programa de reconocimiento facial utilizando los componentes basados en inteligencia artificial de Mitov.

Primero tenemos que descargarnos el paquete "Intelligence lab" desde aquí  (IntelligenceLab_VCL_7.8.2.288.zip)

Lo guardamos en una carpeta, lo descomprimimos y ejecutamos el setup.exe, aquí hay que tener paciencia ya que es un archivo de casi 2 Gb.

Nos pedirá que tipo de licencia tenemos: free, comercial, with source code, etc...

Pulsamos aceptar y si no hay ningún problema en la instalación tendremos en el IDE los componentes de este pack.









 

Creamos un nuevo proyecto y añadimos el componente

ILRadialBasisFunctionNetwork

Del cual sólo tenemos que modificar la propiedad MaxInfluencefield = 300

En función de este valor tendremos una mayor o menor precisión en el reconocimiento de caras.

Las imágenes de prueba las guardamos en la carpeta "faces" y las dividimos en 2 grupos uno para hacer el entrenamiento de la red y otro para hacer un test en el que verificaremos la precisión del reconocimiento facial.


En total hay 40 personas distintas y de cada una de ellas se han hecho 9 fotos, como ven en la siguiente imagen las fotos destinadas a entrenar la red se llaman "Train_(1..9)_(1..40)" y las destinadas a test se llaman "Reco_(1..40)"





 



El código que entrena la red y que se pone en el evento Onclick es:



procedure TForm1.TrainButtonClick(Sender: TObject);
var
I : Integer;
J : Integer;
K : Integer;
ABitmap : TBitmap;
AFeaturesBuffer : ISLRealBuffer;
AInPtr : PByte;
AOutPtr : PReal;
AItem : TListItem;

begin
ABitmap := TBitmap.Create();
ProgressBar1.Max := 40;
AFeaturesBuffer := TSLRealBuffer.CreateSize( 32 * 32 );

ListView1.Items.BeginUpdate();
for I := 1 to 40 do
begin
for J := 1 to 9 do
begin
ABitmap.LoadFromFile( '.\Faces\Train_' + IntToStr( I ) + '_' + IntToStr( J ) + '.bmp' );
ImageList1.Add( ABitmap, NIL );
AItem := ListView1.Items.Add();
AItem.ImageIndex := ImageList1.Count - 1;
AItem.Caption := IntToStr( I );
AInPtr := ABitmap.ScanLine[ ABitmap.Height - 1 ];
AOutPtr := AFeaturesBuffer.Write();
for K := 0 to AFeaturesBuffer.Size - 1 do
begin
AOutPtr^ := AInPtr^ / 256;
Inc( AOutPtr );
Inc( AInPtr );
end;

ILRadialBasisFunctionNetwork1.Train( AFeaturesBuffer, I );
end;

ProgressBar1.Position := I;
end;

ListView1.Items.EndUpdate();
ABitmap.Free();
RecognizeButton.Enabled := True;
TrainButton.Enabled := False;
TrainLabel.Caption := IntToStr( ILRadialBasisFunctionNetwork1.Neurons.Count ) + ' Neurons used.';
ILRadialBasisFunctionNetwork1.SaveToFile('redneuronal1');
end;





Al final del entrenamiento se crea el fichero "redneuronal1" que contiene todas las características y pesos de la red.



ILRadialBasisFunctionNetwork1.SaveToFile('redneuronal1');



El siguiente paso es probar su fiabilidad, para ello colocamos otro botón en nuestro proyecto y en el evento OnClick lo primero que hacemos es cargar la red almacenada antes:



ILRadialBasisFunctionNetwork1.LoadFromFile('redneuronal1');

 

 

El código que reconoce las imágenes de test es el siguiente:


procedure TForm1.RecognizeButtonClick(Sender: TObject);
var
I : Integer;
K : Integer;
ABitmap : TBitmap;
AFeaturesBuffer : ISLRealBuffer;
AInPtr : PByte;
AOutPtr : PReal;
AItem : TListItem;

begin

ILRadialBasisFunctionNetwork1.LoadFromFile('redneuronal1');


FTotalCount := 0;
FErrorCount := 0;

ABitmap := TBitmap.Create();
ProgressBar1.Max := 40;
AFeaturesBuffer := TSLRealBuffer.CreateSize( 32 * 32 );

ListView2.Items.BeginUpdate();
for I := 1 to 40 do
begin
FExpectedID := I;
ABitmap.LoadFromFile( '.\Faces\Reco_' + IntToStr( I ) + '.bmp' );
ImageList1.Add( ABitmap, NIL );
AItem := ListView2.Items.Add();
AItem.ImageIndex := ImageList1.Count - 1;
AInPtr := ABitmap.ScanLine[ ABitmap.Height - 1 ];
AOutPtr := AFeaturesBuffer.Write();
for K := 0 to AFeaturesBuffer.Size - 1 do
begin
AOutPtr^ := AInPtr^ / 256;
Inc( AOutPtr );
Inc( AInPtr );
end;

ILRadialBasisFunctionNetwork1.Predict( AFeaturesBuffer );

if( FResultCathegory <> I ) then
begin
if( FResultCathegory = 0 ) then
AItem.Caption := 'Error - Can''t recognize'

else
AItem.Caption := 'Error - Expected:' + IntToStr( I ) +
' recognized as: ' + IntToStr( FResultCathegory ) + ' Distance: ' + FloatToStr( FDistance );

end

else
AItem.Caption := 'Correct: ' + IntToStr( I ) + ' Distance: ' + FloatToStr( FDistance );

ProgressBar1.Position := I;
end;

ListView2.Items.EndUpdate();
ABitmap.Free();

RecognizeLabel.Caption := IntToStr( FErrorCount ) + ' errors of ' + IntToStr( FTotalCount ) + ' faces - ' + FloatToStr( ( FTotalCount - FErrorCount ) * 100 / FTotalCount ) + '% correct';
end;







Al ejecutar el código anterior comprobamos que ha reconocido 35 caras de 40 lo que representa un 87,5% de fiabilidad, ¡no está nada mal!








Hay que saber que lo primero que hay que hacer es un preprocesamiento de las imágenes, ya que todas tienen que tener las mismas medidas, hay que convertirlas a b/n, tener el mismo formato, etc.. y que cuanto más imágenes se tengan de cada persona mejor...siempre dentro de un límite para no llegar al sobreentrenamiento de la red, ya que en ese caso se produciría una mayor tasa de error.

Como ven es sencillo hacer un reconocimiento facial con los componentes MITOV.

Espero que les haya gustado el post.



Código fuente y fotos de prueba
























No hay comentarios:

Publicar un comentario

Simulación del movimiento de los electrones en un campo electrico

Espectacular simulación realizada con OpenGL del movimiento de los electrones cuando atraviesan un campo eléctrico. Como muestra la image...