顯示週框方塊 - Amazon Rekognition

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

顯示週框方塊

Amazon Rekognition Image 操作可以針對映像中偵測到的專案傳回週框方塊。例如,此DetectFaces作業會針對影像中偵測到的每個臉部傳回邊界方框 (BoundingBox)。您可以使用週框方塊座標,來顯示所偵測到之專案的周圍方塊。例如,以下映像會顯示圍繞人臉的週框方塊。

微笑, 年輕婦女, 戴眼鏡, 由于, 氣泡, 大約, 她。

BoundingBox 具有下列屬性:

  • 高度:週框方塊的高度,以整體映像高度的比例表示。

  • 左邊:週框方塊的左邊座標,以整體映像寬度的比例表示。

  • 上方:週框方塊的上方座標,以整體映像高度的比例表示。

  • 寬度:週框方塊的寬度,以整體映像寬度的比例表示。

每個 BoundingBox 屬性都有一個介於 0 和 1 之間的值。每個屬性值是整體映像寬度 (LeftWidth) 或高度 (HeightTop) 的比例。例如,如果輸入映像為 700 x 200 像素,而週框方塊的左上方座標為 350 x 50 像素,則 API 會傳回 Left 值 0.5 (350/700) 和 Top 值 0.25 (50/200)。

下圖顯示每個週框方塊屬性涵蓋的映像範圍。

描述邊界方框與影像尺寸之間的關聯性的圖形。

要顯示具有正確位置和大小的邊界框,您必須將 BoundingBox 值乘以圖像寬度或高度(取決於您想要的值)才能獲得像素值。您可以使用像素值來顯示週框方塊。例如,前一個映像的像素維度為 608 寬度 x 588 高度。臉部的週框方塊值如下:

BoundingBox.Left: 0.3922065 BoundingBox.Top: 0.15567766 BoundingBox.Width: 0.284666 BoundingBox.Height: 0.2930403

臉部週框方塊的位置 (以像素表示) 的計算方式如下:

Left coordinate = BoundingBox.Left (0.3922065) * image width (608) = 238

Top coordinate = BoundingBox.Top (0.15567766) * image height (588) = 91

Face width = BoundingBox.Width (0.284666) * image width (608) = 173

Face height = BoundingBox.Height (0.2930403) * image height (588) = 172

您可以使用這些值來顯示臉部的週框方塊。

注意

您可以透過多種方式導向映像。您的應用程式可能需要旋轉映像,才能以正確方向顯示它。週框方塊座標會受到映像方向的影響。您可能需要轉換座標,然後才能在正確位置顯示週框方塊。如需詳細資訊,請參閱 取得映像方向與週框方塊座標

下列範例顯示如何在透過呼叫偵測到的面周圍顯示邊界方塊DetectFaces。這些範例假設映像導向至 0 度。這些範例也會顯示如何從 Amazon S3 儲存貯體下載映像。

顯示週框方塊
  1. 如果您尚未執行:

    1. 建立或更新具有 AmazonRekognitionFullAccessAmazonS3ReadOnlyAccess 許可的使用者。如需詳細資訊,請參閱 步驟 1:設定 AWS 帳戶並建立使用者

    2. 安裝和設定 AWS CLI AWS 軟體開發套件。如需詳細資訊,請參閱 步驟 2:設定 AWS CLI 和開 AWS 發套件

  2. 使用下列範例來呼叫 DetectFaces 操作。

    Java

    bucket 的值變更為包含映像檔案的 Amazon S3 儲存貯體。將 photo 的值變更為某個映像檔案的檔案名稱 (.jpg 或 .png 格式)。

    //Loads images, detects faces and draws bounding boxes.Determines exif orientation, if necessary. package com.amazonaws.samples; //Import the basic graphics classes. import java.awt.*; import java.awt.image.BufferedImage; import java.util.List; import javax.imageio.ImageIO; import javax.swing.*; import com.amazonaws.services.rekognition.AmazonRekognition; import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder; import com.amazonaws.services.rekognition.model.BoundingBox; import com.amazonaws.services.rekognition.model.DetectFacesRequest; import com.amazonaws.services.rekognition.model.DetectFacesResult; import com.amazonaws.services.rekognition.model.FaceDetail; import com.amazonaws.services.rekognition.model.Image; import com.amazonaws.services.rekognition.model.S3Object; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.S3ObjectInputStream; // Calls DetectFaces and displays a bounding box around each detected image. public class DisplayFaces extends JPanel { private static final long serialVersionUID = 1L; BufferedImage image; static int scale; DetectFacesResult result; public DisplayFaces(DetectFacesResult facesResult, BufferedImage bufImage) throws Exception { super(); scale = 1; // increase to shrink image size. result = facesResult; image = bufImage; } // Draws the bounding box around the detected faces. public void paintComponent(Graphics g) { float left = 0; float top = 0; int height = image.getHeight(this); int width = image.getWidth(this); Graphics2D g2d = (Graphics2D) g; // Create a Java2D version of g. // Draw the image. g2d.drawImage(image, 0, 0, width / scale, height / scale, this); g2d.setColor(new Color(0, 212, 0)); // Iterate through faces and display bounding boxes. List<FaceDetail> faceDetails = result.getFaceDetails(); for (FaceDetail face : faceDetails) { BoundingBox box = face.getBoundingBox(); left = width * box.getLeft(); top = height * box.getTop(); g2d.drawRect(Math.round(left / scale), Math.round(top / scale), Math.round((width * box.getWidth()) / scale), Math.round((height * box.getHeight())) / scale); } } public static void main(String arg[]) throws Exception { String photo = "photo.png"; String bucket = "bucket"; int height = 0; int width = 0; // Get the image from an S3 Bucket AmazonS3 s3client = AmazonS3ClientBuilder.defaultClient(); com.amazonaws.services.s3.model.S3Object s3object = s3client.getObject(bucket, photo); S3ObjectInputStream inputStream = s3object.getObjectContent(); BufferedImage image = ImageIO.read(inputStream); DetectFacesRequest request = new DetectFacesRequest() .withImage(new Image().withS3Object(new S3Object().withName(photo).withBucket(bucket))); width = image.getWidth(); height = image.getHeight(); // Call DetectFaces AmazonRekognition amazonRekognition = AmazonRekognitionClientBuilder.defaultClient(); DetectFacesResult result = amazonRekognition.detectFaces(request); //Show the bounding box info for each face. List<FaceDetail> faceDetails = result.getFaceDetails(); for (FaceDetail face : faceDetails) { BoundingBox box = face.getBoundingBox(); float left = width * box.getLeft(); float top = height * box.getTop(); System.out.println("Face:"); System.out.println("Left: " + String.valueOf((int) left)); System.out.println("Top: " + String.valueOf((int) top)); System.out.println("Face Width: " + String.valueOf((int) (width * box.getWidth()))); System.out.println("Face Height: " + String.valueOf((int) (height * box.getHeight()))); System.out.println(); } // Create frame and panel. JFrame frame = new JFrame("RotateImage"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DisplayFaces panel = new DisplayFaces(result, image); panel.setPreferredSize(new Dimension(image.getWidth() / scale, image.getHeight() / scale)); frame.setContentPane(panel); frame.pack(); frame.setVisible(true); } }
    Python

    bucket 的值變更為包含映像檔案的 Amazon S3 儲存貯體。將 photo 的值變更為某個映像檔案的檔案名稱 (.jpg 或 .png 格式)。將建立 Rekognition 工作階段的行中 profile_name 值取代為您開發人員設定檔的名稱。

    import boto3 import io from PIL import Image, ImageDraw def show_faces(photo, bucket): session = boto3.Session(profile_name='profile-name') client = session.client('rekognition') # Load image from S3 bucket s3_connection = boto3.resource('s3') s3_object = s3_connection.Object(bucket, photo) s3_response = s3_object.get() stream = io.BytesIO(s3_response['Body'].read()) image = Image.open(stream) # Call DetectFaces response = client.detect_faces(Image={'S3Object': {'Bucket': bucket, 'Name': photo}}, Attributes=['ALL']) imgWidth, imgHeight = image.size draw = ImageDraw.Draw(image) # calculate and display bounding boxes for each detected face print('Detected faces for ' + photo) for faceDetail in response['FaceDetails']: print('The detected face is between ' + str(faceDetail['AgeRange']['Low']) + ' and ' + str(faceDetail['AgeRange']['High']) + ' years old') box = faceDetail['BoundingBox'] left = imgWidth * box['Left'] top = imgHeight * box['Top'] width = imgWidth * box['Width'] height = imgHeight * box['Height'] print('Left: ' + '{0:.0f}'.format(left)) print('Top: ' + '{0:.0f}'.format(top)) print('Face Width: ' + "{0:.0f}".format(width)) print('Face Height: ' + "{0:.0f}".format(height)) points = ( (left, top), (left + width, top), (left + width, top + height), (left, top + height), (left, top) ) draw.line(points, fill='#00d400', width=2) # Alternatively can draw rectangle. However you can't set line width. # draw.rectangle([left,top, left + width, top + height], outline='#00d400') image.show() return len(response['FaceDetails']) def main(): bucket = "bucket-name" photo = "photo-name" faces_count = show_faces(photo, bucket) print("faces detected: " + str(faces_count)) if __name__ == "__main__": main()
    Java V2

    此代碼取自 AWS 文檔 SDK 示例 GitHub 存儲庫。請參閱此處的完整範例。

    請注意,s3 是指 AWS SDK Amazon Amazon S3 客戶端,并且 rekClient 是指 AWS SDK Amazon Rekognition 客戶端。

    //snippet-start:[rekognition.java2.detect_labels.import] import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.imageio.ImageIO; import javax.swing.*; import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.core.ResponseBytes; import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.model.Attribute; import software.amazon.awssdk.services.rekognition.model.BoundingBox; import software.amazon.awssdk.services.rekognition.model.DetectFacesRequest; import software.amazon.awssdk.services.rekognition.model.DetectFacesResponse; import software.amazon.awssdk.services.rekognition.model.FaceDetail; import software.amazon.awssdk.services.rekognition.model.Image; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.GetObjectResponse; import software.amazon.awssdk.services.s3.model.S3Exception; //snippet-end:[rekognition.java2.detect_labels.import] /** * 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 DisplayFaces extends JPanel { static DetectFacesResponse result; static BufferedImage image; static int scale; public static void main(String[] args) throws Exception { final String usage = "\n" + "Usage: " + " <sourceImage> <bucketName>\n\n" + "Where:\n" + " sourceImage - The name of the image in an Amazon S3 bucket (for example, people.png). \n\n" + " bucketName - The name of the Amazon S3 bucket (for example, myBucket). \n\n"; if (args.length != 2) { System.out.println(usage); System.exit(1); } String sourceImage = args[0]; String bucketName = args[1]; Region region = Region.US_EAST_1; S3Client s3 = S3Client.builder() .region(region) .credentialsProvider(ProfileCredentialsProvider.create("profile-name")) .build(); RekognitionClient rekClient = RekognitionClient.builder() .region(region) .credentialsProvider(ProfileCredentialsProvider.create("profile-name")) .build(); displayAllFaces(s3, rekClient, sourceImage, bucketName); s3.close(); rekClient.close(); } // snippet-start:[rekognition.java2.display_faces.main] public static void displayAllFaces(S3Client s3, RekognitionClient rekClient, String sourceImage, String bucketName) { int height; int width; byte[] data = getObjectBytes (s3, bucketName, sourceImage); InputStream is = new ByteArrayInputStream(data); try { SdkBytes sourceBytes = SdkBytes.fromInputStream(is); image = ImageIO.read(sourceBytes.asInputStream()); width = image.getWidth(); height = image.getHeight(); // Create an Image object for the source image software.amazon.awssdk.services.rekognition.model.Image souImage = Image.builder() .bytes(sourceBytes) .build(); DetectFacesRequest facesRequest = DetectFacesRequest.builder() .attributes(Attribute.ALL) .image(souImage) .build(); result = rekClient.detectFaces(facesRequest); // Show the bounding box info for each face. List<FaceDetail> faceDetails = result.faceDetails(); for (FaceDetail face : faceDetails) { BoundingBox box = face.boundingBox(); float left = width * box.left(); float top = height * box.top(); System.out.println("Face:"); System.out.println("Left: " + (int) left); System.out.println("Top: " + (int) top); System.out.println("Face Width: " + (int) (width * box.width())); System.out.println("Face Height: " + (int) (height * box.height())); System.out.println(); } // Create the frame and panel. JFrame frame = new JFrame("RotateImage"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DisplayFaces panel = new DisplayFaces(image); panel.setPreferredSize(new Dimension(image.getWidth() / scale, image.getHeight() / scale)); frame.setContentPane(panel); frame.pack(); frame.setVisible(true); } catch (RekognitionException | FileNotFoundException e) { System.out.println(e.getMessage()); System.exit(1); } catch (IOException e) { e.printStackTrace(); } } public static byte[] getObjectBytes (S3Client s3, String bucketName, String keyName) { try { GetObjectRequest objectRequest = GetObjectRequest .builder() .key(keyName) .bucket(bucketName) .build(); ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest); return objectBytes.asByteArray(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; } public DisplayFaces(BufferedImage bufImage) { super(); scale = 1; // increase to shrink image size. image = bufImage; } // Draws the bounding box around the detected faces. public void paintComponent(Graphics g) { float left; float top; int height = image.getHeight(this); int width = image.getWidth(this); Graphics2D g2d = (Graphics2D) g; // Create a Java2D version of g. // Draw the image g2d.drawImage(image, 0, 0, width / scale, height / scale, this); g2d.setColor(new Color(0, 212, 0)); // Iterate through the faces and display bounding boxes. List<FaceDetail> faceDetails = result.faceDetails(); for (FaceDetail face : faceDetails) { BoundingBox box = face.boundingBox(); left = width * box.left(); top = height * box.top(); g2d.drawRect(Math.round(left / scale), Math.round(top / scale), Math.round((width * box.width()) / scale), Math.round((height * box.height())) / scale); } } // snippet-end:[rekognition.java2.display_faces.main] }