Reconocimiento facial con Delphi


Hace unos días me pidieron que hiciese un programa de reconocimiento facial para identificar a los alumnos de una escuela.


Dándole vueltas al tema me di cuenta que tenía que dividirlo en dos partes, la primera sería la extracción de la cara del alumno de la imagen inicial eliminando el fondo y detalles innecesarios y la segunda la del tratamiento de esa imagen para identificar al alumno en cuestión utilizando técnicas de inteligencia artificial.


Inicialmente pensé en utilizar OpenCV (aquí tienen cómo instalarlo), pero por más intentos que hice  no conseguí que funcionase en mi equipo, me decía que no encontraba unas dlls, o que "no era una aplicación win32 válida", así que investigando en Google encontré que Android tiene incorporado un objeto llamado JFaceDetector para hacer reconocimiento facial, que lo podemos utilizar desde la unit Androidapi.JNI.Media.


Para utilizarlo se hace de la siguiente forma:


Desde nuestro Delphi Tokyo 10.2.2 accedo a File - Multi-Device Application y creo un nuevo proyecto.

En Tipo de proyecto seleccionamos Android








Desde la paleta de herramientas "Tool Palette" voy arrastrando hacia el form 3 objetos:  tButton, tLabel, tImage.






En el objeto tImage cargo una imagen de prueba (se hace clic sobre el componente tImage y desde Object Inspector, selecciono la propiedad Multiresbitmap)






para conseguir que quede de la siguiente forma:








En el componente Label1 mostraremos el número de caras que ha detectado el programa.


y dentro del tbutton en el evento Onclic colocaremos el siguiente código:

procedure TForm12.Button1Click(Sender: TObject);
var
LDetector: JFaceDetector;
LFaces: TJavaObjectArray;
LFace: JFaceDetector_Face;
LSurface: TBitmapSurface;
LBitmap: JBitmap;
LMidpoint: JPointF;
LFaceCount, I: Integer;
LRect: TRectF;
LHalfWidth: Single;

begin

LSurface := TBitmapSurface.Create;
try
LSurface.Assign(FaceImage.Bitmap);
LBitmap := TJBitmap.JavaClass.createBitmap(LSurface.Width, LSurface.Height,
TJBitmap_Config.JavaClass.ARGB_8888);
SurfaceToJBitmap(LSurface, LBitmap);
LMidpoint := TJPointF.Create;
LFaces := TJavaObjectArray.Create(10);
LDetector := TJFaceDetector.JavaClass.init(LBitmap.getWidth,
LBitmap.getHeight, 10);
LFaceCount := LDetector.findFaces
(LBitmap.copy(TJBitmap_Config.JavaClass.RGB_565, False), LFaces);
Label1.Text := LFaceCount.ToString + 'caras';
for I := 0 to LFaceCount - 1 do
begin
LFace := LFaces.Items[I];
LFace.getMidPoint(LMidpoint);
LHalfWidth := LFace.eyesDistance * 2;
LRect := RectF(LMidpoint.x - LHalfWidth, LMidpoint.y - LHalfWidth,
LMidpoint.x + LHalfWidth, LMidpoint.y + LHalfWidth);
FaceImage.Bitmap.Canvas.BeginScene;
try
FaceImage.Bitmap.Canvas.Stroke.Color := TAlphaColorRec.Red;
FaceImage.Bitmap.Canvas.Stroke.Thickness := 2;
FaceImage.Bitmap.Canvas.DrawRect(LRect,0,0,allcorners, 100);
finally
FaceImage.Bitmap.Canvas.EndScene;
end;
end;
finally
LSurface.Free;
end;
end;





y a continuación ejecutamos el código y veremos cómo nos ha creado un rectángulo rodeando los rostros que ha detectado:
















En un próximo post publicaré cómo utilizar redes neuronales para la identificación de imágenes.


Además me gustaría recordarles que si quieren iniciarse en la programación con Delphi pueden utilizar una versión gratuita para siempre llamada Delphi Starter Edition que la pueden descargar desde aquí o también pueden descargar la edición de prueba por 30 días totalmente funcional desde aquí.


Si les ha gustado y quieren compartir el post, pueden pulsar los iconos de twitter, facebook, google+ que tienen un poco más abajo




2 comentarios:

  1. Desconocía esta funcionalidad de Android, ¿que más cosas tendrá escondidas Android?

    ResponderEliminar
  2. Where I find the source code, for testing, and download

    ResponderEliminar

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...