Ottenere l'orientamento dell'immagine e le coordinate del riquadro di delimitazione - Amazon Rekognition

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Ottenere l'orientamento dell'immagine e le coordinate del riquadro di delimitazione

Le applicazioni che utilizzano Immagini Amazon Rekognition solitamente devono visualizzare le immagini che vengono rilevate dalle operazioni di Immagini Amazon Rekognition e i riquadri intorno ai volti rilevati. Per visualizzare correttamente un'immagine nella propria applicazione, è necessario conoscere l'orientamento dell'immagine. Potrebbe essere necessario correggere questo orientamento. Per alcuni file .jpg, l'orientamento dell'immagine è contenuto nei metadata Exif (Exchangeable image file format) dell'immagine.

Per visualizzare un riquadro intorno a un volto, è necessario disporre delle coordinate del riquadro di delimitazione del volto. Se il riquadro non è orientato correttamente, potrebbe essere necessario modificare tali coordinate. Le operazioni di riconoscimento facciale di Immagini Amazon Rekognition restituiscono le coordinate del bounding box per ogni volto rilevato, ma non stimano le coordinate per i file.jpg senza metadati Exif.

Il seguente esempio mostra come ottenere le coordinate del riquadro di delimitazione per i volti rilevati in un'immagine.

Utilizzare le informazioni in questo esempio per verificare che le immagini siano orientate correttamente e che i riquadri di delimitazione siano visualizzati in posizione corretta all'interno dell'applicazione.

Poiché il codice utilizzato per ruotare e visualizzare le immagini e i riquadri di delimitazione dipende dalla lingua e dall'ambiente utilizzati, non spiegheremo come visualizzare le immagini e i riquadri nel codice o come ottenere informazioni di orientamento dai metadati Exif.

Determinazione dell'orientamento di un'immagine

Per visualizzare correttamente un'immagine nella propria applicazione, potrebbe essere necessario ruotarla. La seguente immagine è orientata a 0 gradi ed è visualizzata correttamente.

Icona generica del profilo che rappresenta un account utente o un'immagine del profilo.

Tuttavia, la seguente immagine è ruotata di 90 gradi in senso antiorario. Per visualizzarla correttamente, è necessario determinare l'orientamento dell'immagine e utilizzare tali informazioni nel codice per ruotare l'immagine a 0 gradi.

Icona generica del profilo che rappresenta un account utente o un'immagine del profilo, ruotata di 90 gradi in senso antiorario.

Alcune immagini in formato .jpg contengono le informazioni di orientamento nei metadata Exif. Se disponibili, i metadati Exif dell'immagine contengono l'orientamento. Nei metadata Exif è possibile trovare l'orientamento dell'immagine nel campo orientation. Anche se Immagini Amazon Rekognition identifica la presenza di informazioni sull'orientamento dell'immagine nei metadati Exif, non fornisce accesso a tali informazioni. Per accedere ai metadata Exif in un'immagine, utilizzare una libreria di terze parti o scrivere il proprio codice. Per ulteriori informazioni, consulta Exif versione 2.32.

Quando si conosce l'orientamento di un'immagine, è possibile scrivere il codice per ruotarla e visualizzarla correttamente.

Visualizzazione di riquadri di delimitazione

Le operazioni di Immagini Amazon Rekognition che analizzano i volti in un'immagine restituiscono anche le coordinate dei riquadri di delimitazione che circondano i volti. Per BoundingBoxulteriori informazioni, vedere.

Per visualizzare un riquadro intorno a un volto simile a quello mostrato nell'immagine seguente all'interno dell'applicazione, utilizzare le coordinate del riquadro nel proprio codice. Le coordinate del riquadro di delimitazione restituite da un'operazione indicano l'orientamento dell'immagine. Se è necessario ruotare l'immagine per visualizzarla correttamente, potrebbe essere necessario convertire le coordinate del riquadro di delimitazione.

Icona del profilo con la faccia evidenziata in un quadrato rosso.

Visualizzazione dei riquadri di delimitazione quando le informazioni di orientamento sono presenti nei metadata Exif

Se l'orientamento di un'immagine è inclusa nei metadata Exif, le operazioni di Immagini Amazon Rekognition eseguiranno quanto segue:

  • Restituiranno un valore nullo nel campo di correzione dell'orientamento nella risposta dell'operazione. Per ruotare l'immagine, utilizzare l'orientamento fornito nei metadata Exif del proprio codice.

  • Restituiranno le coordinate del riquadro di delimitazione già orientate a 0 gradi. Per visualizzare il riquadro di delimitazione nella posizione corretta, utilizzare le coordinate restituite. Non è necessario convertirle.

Esempio: ottenimento dell'orientamento dell'immagine e delle coordinate del riquadro per un'immagine

L'esempio seguente mostra come utilizzare l'AWS SDK per ottenere i dati di orientamento dell'immagine Exif e le coordinate del riquadri di delimitazione per le celebrità rilevate dall'operazione RecognizeCelebrities.

Nota

Il supporto per la stima dell'orientamento dell'immagine utilizzando il campo OrientationCorrection è cessato ad agosto 2021. Tutti i valori restituiti per questo campo inclusi in una risposta API saranno sempre NULL.

Java

In questo esempio viene caricata un'immagine dal file system locale, richiamata l'operazione RecognizeCelebrities, determinata l'altezza e la larghezza dell'immagine e vengono inoltre calcolate le coordinate del riquadro di delimitazione del volto per l'immagine ruotata. L'esempio non mostra come elaborare le informazioni di orientamento memorizzate nei metadata Exif.

Nella funzione main sostituire il valore di photo con il nome e il percorso di un'immagine memorizzata localmente in 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

In questo esempio viene utilizzata la libreria di immagini PIL/Pillow per ottenere la larghezza e l'altezza dell'immagine. Per ulteriori informazioni, consulta Pillow. In questo esempio vengono conservati i metadati exif che potrebbe essere necessari in altri punti dell'applicazione.

Nella funzione main sostituire il valore di photo con il nome e il percorso di un'immagine memorizzata localmente in 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

Questo codice è tratto dal GitHub repository degli esempi di AWS Documentation SDK. Guarda l'esempio completo qui.

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())); } }