イメージの向きとバウンディングボックスの座標を取得する - Amazon Rekognition

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

イメージの向きとバウンディングボックスの座標を取得する

Amazon REKognition Image を使用するアプリケーションは、通常、Amazon REKognition Image オペレーションで検出されたイメージと、検出された顔の周囲のボックスを表示する必要があります。アプリケーションで正しくイメージを表示するには、イメージの向きを知る必要があります。この向きを修正することが必要な場合があります。一部の .jpg ファイルでは、イメージの向きは、イメージの Exchangeable イメージファイル形式 (Exif) メタデータに含まれています。

顔の周りにボックスを表示するには、顔の境界ボックスの座標が必要です。ボックスの向きが正しくない場合は、座標の調整が必要になることがあります。Amazon REKognition イメージの顔検出オペレーションでは、検出された顔ごとに境界ボックスが返されます。ただし、Exif メタデータがない状態の.jpg ファイルの座標は推定されません。

以下の例では、イメージで検出された顔の境界ボックスの座標を取得する方法を示します。

この例の情報を使用して、イメージの向きが正しく、境界ボックスがアプリケーションで正しい位置に表示されるようにします。

イメージと境界ボックスを回転および表示するためのコードは、使用する言語と環境に依存するため、イメージと境界ボックスをコードで表示する方法や、Exif メタデータから向きの情報を取得する方法については説明しません。

画像の向きを見つける

アプリケーションで正しくイメージを表示するには、回転が必要になる場合があります。次のイメージの向きは 0 度で、正しく表示されています。

ただし、次のイメージは反時計回りに 90 度回転しています。これを正しく表示するには、イメージの向きを見つけ、その情報をコードで使用してイメージを 0 度に回転する必要があります。

.jpg 形式の一部のイメージには、Exif メタデータに向きの情報が含まれています。使用可能な場合、イメージの Exif メタデータには向きが含まれています。Exif メタデータで、イメージの向きは orientation フィールドで見つかります。Amazon REKognition Image は Exif メタデータ内のイメージの向きの情報の存在を認識しますが、その情報へのアクセスは提供しません。イメージで Exif メタデータにアクセスするには、サードパーティーのライブラリを使用するか、独自のコードを記述します。詳細については、「Exif バージョン 2.32」を参照してください。

イメージの向きがわかっている場合は、コードを記述して回転し、正しく表示できます。

境界ボックスの表示

イメージの顔を分析する Amazon Rekognition Image オペレーションも、顔を囲む境界ボックスの座標を返します。詳細については、「BoundingBox」を参照してください。

アプリケーションの次のイメージに示すボックスに類似した境界ボックスを顔の周囲に表示するには、コードで境界ボックスの座標を使用します。オペレーションで返される境界ボックスの座標は、イメージの向きを反映しています。イメージを回転して正しく表示する必要がある場合は、境界ボックスの座標の変換が必要になる場合があります。

向き情報が Exif メタデータに存在するときに境界ボックスを表示する

イメージの向きが Exif メタデータに含まれている場合、Amazon REKognition イメージのオペレーションで以下が実行されます。

  • オペレーションのレスポンスの向き修正フィールドで null が返されます。イメージを回転するには、コードの Exif メタデータに含まれている向きを使用します。

  • すでに向きが設定されている境界ボックスの座標を 0 度に戻します。正しい位置に境界ボックスを表示するには、返された座標を使用します。それらを変換する必要はありません。

例: イメージのイメージの向きとバウンディングボックスの座標を取得する

以下の例では、AWS SDK を使用して Exif イメージの向きデータとで検出された有名人の境界ボックスの座標を取得する方法を示します。RecognizeCelebritiesオペレーション.

注記

画像方向の見積もりのSupportOrientationCorrection2021年8月現在、フィールドは終了している。API レスポンスに含まれるこのフィールドの戻り値は、常に NULL になります。

Java

この例では、ローカルファイルシステムからイメージをロードし、RecognizeCelebritiesオペレーションでは、イメージの高さと幅を判断してから、回転したイメージの顔の境界ボックスの座標を計算します。この例では、Exif メタデータに保存される向きの情報を処理する方法は示しません。

関数 main で、photo の値は、ローカルに保存されているイメージ (.png または .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

この例では、PIL/Pillow イメージライブラリを使用してイメージの幅と高さを取得します。詳細については、「Pillow」を参照してください。この例では、exif メタデータを保存し、アプリケーションの他の場所で利用できるようにします。

関数 main で、photo の値は、ローカルに保存されているイメージ (.png または .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

このコードはAWSドキュメント SDK の例 GitHub リポジトリ。完全な例を見るここに

public static void recognizeAllCelebrities(RekognitionClient rekClient, String sourceImage) { try { BufferedImage image = null; 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 = 0; float top = 0; 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(); break; case "ROTATE_90": left = imageHeight * (1 - (box.top() + box.height())); top = imageWidth * box.left(); break; case "ROTATE_180": left = imageWidth - (imageWidth * (box.left() + box.width())); top = imageHeight * (1 - (box.top() + box.height())); break; case "ROTATE_270": left = imageHeight * box.top(); top = imageWidth * (1 - box.left() - box.width()); break; 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())); }