Obtención de coordenadas de cuadro delimitador y orientación de imagen - Amazon Rekognition

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Obtención de coordenadas de cuadro delimitador y orientación de imagen

Las aplicaciones que utilizan Amazon Rekognition Image habitualmente tienen que mostrar las imágenes detectadas por las operaciones de Amazon Rekognition Image y los cuadros alrededor de rostros detectados. Para visualizar una imagen correctamente en la aplicación, tiene que conocer la orientación. Tal vez tenga que corregir esta orientación. Para algunos archivos .jpg, la orientación de la imagen está contenida en los metadatos de formato de archivo de imagen intercambiable (EXIF) de la imagen.

Para mostrar un cuadro alrededor de un rostro, necesita las coordenadas del cuadro delimitador del rostro. Si el cuadro no está orientado correctamente, es posible que tenga que ajustar esas coordenadas. Las operaciones de detección de rostros de Amazon Rekognition Image devuelven las coordenadas del cuadro delimitador de cada rostro detectado, pero no estiman las coordenadas de los archivos.jpg sin metadatos Exif.

Los siguientes ejemplos muestran cómo obtener las coordenadas del cuadro delimitador para los rostros detectados en una imagen.

Utilice la información de este ejemplo para garantizar que sus imágenes están correctamente orientadas y que los cuadros delimitadores se muestran en la ubicación correcta en su aplicación.

Dado que el código que se utiliza para girar y mostrar imágenes y cuadros delimitadores depende del lenguaje y del entorno que utilice, no se explica cómo mostrar imágenes y cuadros delimitadores en el código o cómo obtener la información de orientación a partir de los metadatos Exif.

Búsqueda de la orientación de una imagen

Para mostrar una imagen correctamente en su aplicación, es posible que tenga que girarla. La siguiente imagen está orientada a 0 grados y se muestra correctamente.

Icono de perfil genérico que representa una cuenta de usuario o una imagen de perfil.

Sin embargo, la siguiente imagen está girada 90 grados en sentido contrario a las agujas del reloj. Para mostrarla correctamente, tiene que encontrar la orientación de la imagen y utilizar dicha información en su código para girar la imagen a 0 grados.

Icono de perfil genérico que representa una cuenta de usuario o una imagen de perfil, girado 90 grados en sentido contrario a las agujas del reloj.

Algunas imágenes en formato .jpg contienen información de orientación en metadatos Exif. Si están disponibles, los metadatos Exif de la imagen contienen la orientación. En los metadatos Exif, puede encontrar la orientación de la imagen en el campo orientation. Aunque Amazon Rekognition Image identifica la presencia de información de orientación de imagen en los metadatos Exif, no proporciona acceso a la misma. Para acceder a los metadatos Exif en una imagen, utilice una biblioteca de terceros o escriba su propio código. Para obtener más información, consulte Exif Version 2.32.

Cuando se conoce la orientación de una imagen, puede escribir código para girarla y mostrarla correctamente.

Visualización de cuadros delimitadores

Las operaciones de Amazon Rekognition Image que analizan rostros en una imagen devuelven además las coordenadas de los cuadros delimitadores que rodean los rostros. Para obtener más información, consulte. BoundingBox

Para mostrar un cuadro delimitador alrededor de un rostro similar al cuadro mostrado en la imagen siguiente en su aplicación, utilice las coordenadas de cuadro delimitador en su código. Las coordenadas del cuadro delimitador devueltas por una operación reflejan la orientación de la imagen. Si tiene que girar la imagen para mostrarla correctamente, es posible que tenga que traducir las coordenadas del cuadro delimitador.

Icono de perfil con la cara resaltada en un cuadrado rojo.

Mostrar cuadros delimitadores cuando la información de orientación está presente en los metadatos Exif

Si la orientación de una imagen está incluida en metadatos Exif, las operaciones de Amazon Rekognition Image hacen lo siguiente:

  • Devolver nulo en el campo de corrección de orientación en la respuesta de la operación. Para girar la imagen, utilice la orientación proporcionada en los metadatos Exif en el código.

  • Devuelva las coordenadas del cuadro delimitador ya orientadas a 0 grados. Para mostrar el cuadro delimitador en la posición correcta, utilice las coordenadas que se devolvieron. No tiene que traducirlas.

Ejemplo: obtención de coordenadas de cuadro delimitador y orientación de imagen para una imagen

En los siguientes ejemplos se muestra cómo se utiliza el SDK de AWS con el fin de obtener los datos de orientación de una imagen Exif y las coordenadas de los cuadros delimitadores para los famosos detectados mediante la operación RecognizeCelebrities.

nota

El soporte para estimar la orientación de la imagen mediante el campo OrientationCorrection cesó en agosto de 2021. Todos los valores devueltos para este campo incluidos en una respuesta de la API siempre serán NULL.

Java

Este ejemplo carga una imagen del sistema de archivos local, llama a la operación RecognizeCelebrities, determina la altura y la anchura de la imagen y calcula las coordenadas del cuadro delimitador del rostro para la imagen girada. El ejemplo no muestra cómo procesar la información de orientación que hay almacenada en los metadatos Exif.

En la función main, cambie el valor de photo por el nombre y la ruta de una imagen que esté almacenada localmente en formato .png o .jpg.

//Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. //PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) package com.amazonaws.samples; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.List; import javax.imageio.ImageIO; import com.amazonaws.services.rekognition.AmazonRekognition; import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder; import com.amazonaws.services.rekognition.model.Image; import com.amazonaws.services.rekognition.model.RecognizeCelebritiesRequest; import com.amazonaws.services.rekognition.model.RecognizeCelebritiesResult; import com.amazonaws.util.IOUtils; import com.amazonaws.services.rekognition.model.AmazonRekognitionException; import com.amazonaws.services.rekognition.model.BoundingBox; import com.amazonaws.services.rekognition.model.Celebrity; import com.amazonaws.services.rekognition.model.ComparedFace; public class RotateImage { public static void main(String[] args) throws Exception { String photo = "photo.png"; //Get Rekognition client AmazonRekognition amazonRekognition = AmazonRekognitionClientBuilder.defaultClient(); // Load image ByteBuffer imageBytes=null; BufferedImage image = null; try (InputStream inputStream = new FileInputStream(new File(photo))) { imageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream)); } catch(Exception e) { System.out.println("Failed to load file " + photo); System.exit(1); } //Get image width and height InputStream imageBytesStream; imageBytesStream = new ByteArrayInputStream(imageBytes.array()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); image=ImageIO.read(imageBytesStream); ImageIO.write(image, "jpg", baos); int height = image.getHeight(); int width = image.getWidth(); System.out.println("Image Information:"); System.out.println(photo); System.out.println("Image Height: " + Integer.toString(height)); System.out.println("Image Width: " + Integer.toString(width)); //Call GetCelebrities try{ RecognizeCelebritiesRequest request = new RecognizeCelebritiesRequest() .withImage(new Image() .withBytes((imageBytes))); RecognizeCelebritiesResult result = amazonRekognition.recognizeCelebrities(request); // The returned value of OrientationCorrection will always be null System.out.println("Orientation: " + result.getOrientationCorrection() + "\n"); List <Celebrity> celebs = result.getCelebrityFaces(); for (Celebrity celebrity: celebs) { System.out.println("Celebrity recognized: " + celebrity.getName()); System.out.println("Celebrity ID: " + celebrity.getId()); ComparedFace face = celebrity.getFace() ; ShowBoundingBoxPositions(height, width, face.getBoundingBox(), result.getOrientationCorrection()); System.out.println(); } } catch (AmazonRekognitionException e) { e.printStackTrace(); } } public static void ShowBoundingBoxPositions(int imageHeight, int imageWidth, BoundingBox box, String rotation) { float left = 0; float top = 0; if(rotation==null){ System.out.println("No estimated estimated orientation. Check Exif data."); return; } //Calculate face position based on image orientation. switch (rotation) { case "ROTATE_0": left = imageWidth * box.getLeft(); top = imageHeight * box.getTop(); break; case "ROTATE_90": left = imageHeight * (1 - (box.getTop() + box.getHeight())); top = imageWidth * box.getLeft(); break; case "ROTATE_180": left = imageWidth - (imageWidth * (box.getLeft() + box.getWidth())); top = imageHeight * (1 - (box.getTop() + box.getHeight())); break; case "ROTATE_270": left = imageHeight * box.getTop(); top = imageWidth * (1 - box.getLeft() - box.getWidth()); break; default: System.out.println("No estimated orientation information. Check Exif data."); return; } //Display face location information. System.out.println("Left: " + String.valueOf((int) left)); System.out.println("Top: " + String.valueOf((int) top)); System.out.println("Face Width: " + String.valueOf((int)(imageWidth * box.getWidth()))); System.out.println("Face Height: " + String.valueOf((int)(imageHeight * box.getHeight()))); } }
Python

En este ejemplo se utiliza la Biblioteca de imágenes PIL/Pillow para obtener la anchura y altura de la imagen. Para obtener más información, consulte Pillow. En este ejemplo se conservan los metadatos exif porque los puede necesitar en otra parte de la aplicación.

En la función main, cambie el valor de photo por el nombre y la ruta de una imagen que esté almacenada localmente en formato .png o .jpg.

#Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. #PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) import boto3 import io from PIL import Image # Calculate positions from from estimated rotation def show_bounding_box_positions(imageHeight, imageWidth, box): left = 0 top = 0 print('Left: ' + '{0:.0f}'.format(left)) print('Top: ' + '{0:.0f}'.format(top)) print('Face Width: ' + "{0:.0f}".format(imageWidth * box['Width'])) print('Face Height: ' + "{0:.0f}".format(imageHeight * box['Height'])) def celebrity_image_information(photo): client = boto3.client('rekognition') # Get image width and height image = Image.open(open(photo, 'rb')) width, height = image.size print('Image information: ') print(photo) print('Image Height: ' + str(height)) print('Image Width: ' + str(width)) # call detect faces and show face age and placement # if found, preserve exif info stream = io.BytesIO() if 'exif' in image.info: exif = image.info['exif'] image.save(stream, format=image.format, exif=exif) else: image.save(stream, format=image.format) image_binary = stream.getvalue() response = client.recognize_celebrities(Image={'Bytes': image_binary}) print() print('Detected celebrities for ' + photo) for celebrity in response['CelebrityFaces']: print('Name: ' + celebrity['Name']) print('Id: ' + celebrity['Id']) # Value of "orientation correction" will always be null if 'OrientationCorrection' in response: show_bounding_box_positions(height, width, celebrity['Face']['BoundingBox']) print() return len(response['CelebrityFaces']) def main(): photo = 'photo' celebrity_count = celebrity_image_information(photo) print("celebrities detected: " + str(celebrity_count)) if __name__ == "__main__": main()
Java V2

Este código se ha tomado del GitHub repositorio de ejemplos del SDK de AWS documentación. Consulte el ejemplo completo aquí.

import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.rekognition.model.RecognizeCelebritiesRequest; import software.amazon.awssdk.services.rekognition.model.Image; import software.amazon.awssdk.services.rekognition.model.RecognizeCelebritiesResponse; import software.amazon.awssdk.services.rekognition.model.Celebrity; import software.amazon.awssdk.services.rekognition.model.ComparedFace; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import software.amazon.awssdk.services.rekognition.model.BoundingBox; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class RotateImage { public static void main(String[] args) { final String usage = """ Usage: <sourceImage> Where: sourceImage - The path to the image (for example, C:\\AWS\\pic1.png).\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String sourceImage = args[0]; Region region = Region.US_EAST_1; RekognitionClient rekClient = RekognitionClient.builder() .region(region) .build(); System.out.println("Locating celebrities in " + sourceImage); recognizeAllCelebrities(rekClient, sourceImage); rekClient.close(); } public static void recognizeAllCelebrities(RekognitionClient rekClient, String sourceImage) { try { BufferedImage image; InputStream sourceStream = new FileInputStream(sourceImage); SdkBytes sourceBytes = SdkBytes.fromInputStream(sourceStream); image = ImageIO.read(sourceBytes.asInputStream()); int height = image.getHeight(); int width = image.getWidth(); Image souImage = Image.builder() .bytes(sourceBytes) .build(); RecognizeCelebritiesRequest request = RecognizeCelebritiesRequest.builder() .image(souImage) .build(); RecognizeCelebritiesResponse result = rekClient.recognizeCelebrities(request); List<Celebrity> celebs = result.celebrityFaces(); System.out.println(celebs.size() + " celebrity(s) were recognized.\n"); for (Celebrity celebrity : celebs) { System.out.println("Celebrity recognized: " + celebrity.name()); System.out.println("Celebrity ID: " + celebrity.id()); ComparedFace face = celebrity.face(); ShowBoundingBoxPositions(height, width, face.boundingBox(), result.orientationCorrectionAsString()); } } catch (RekognitionException | FileNotFoundException e) { System.out.println(e.getMessage()); System.exit(1); } catch (IOException e) { e.printStackTrace(); } } public static void ShowBoundingBoxPositions(int imageHeight, int imageWidth, BoundingBox box, String rotation) { float left; float top; if (rotation == null) { System.out.println("No estimated estimated orientation."); return; } // Calculate face position based on the image orientation. switch (rotation) { case "ROTATE_0" -> { left = imageWidth * box.left(); top = imageHeight * box.top(); } case "ROTATE_90" -> { left = imageHeight * (1 - (box.top() + box.height())); top = imageWidth * box.left(); } case "ROTATE_180" -> { left = imageWidth - (imageWidth * (box.left() + box.width())); top = imageHeight * (1 - (box.top() + box.height())); } case "ROTATE_270" -> { left = imageHeight * box.top(); top = imageWidth * (1 - box.left() - box.width()); } default -> { System.out.println("No estimated orientation information. Check Exif data."); return; } } System.out.println("Left: " + (int) left); System.out.println("Top: " + (int) top); System.out.println("Face Width: " + (int) (imageWidth * box.width())); System.out.println("Face Height: " + (int) (imageHeight * box.height())); } }