Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Analyse d’une image avec un modèle entraîné
Pour analyser une image à l'aide d'un modèle d'étiquettes personnalisées Amazon Rekognition expérimenté, vous appelez le. DetectCustomLabelsAPI Le résultat de DetectCustomLabels
est une prédiction indiquant que l’image contient des objets, des scènes ou des concepts spécifiques.
Pour appeler DetectCustomLabels
, vous spécifiez ce qui suit :
Nom de ressource Amazon (ARN) du modèle d'étiquettes personnalisées Amazon Rekognition que vous souhaitez utiliser.
L’image avec laquelle vous souhaitez que le modèle fasse une prédiction. Vous pouvez fournir une image d’entrée sous la forme d’un tableau d’octets d’image (octets d’image encodés en base64) ou en tant qu’objet Amazon S3. Pour plus d’informations, consultez Image.
Les étiquettes personnalisées sont renvoyées dans un tableau d’objets Étiquette personnalisée. Chaque étiquette personnalisée représente un objet, une scène ou un concept unique présent dans l’image. Une étiquette personnalisée inclut :
Une étiquette pour l’objet, la scène ou le concept présent dans l’image.
Un cadre de délimitation pour les objets trouvés dans l’image. Les coordonnées du cadre de délimitation montrent où l’objet est situé sur l’image source. Les valeurs des coordonnées sont un ratio de la taille globale de l’image. Pour plus d'informations, consultez BoundingBox. DetectCustomLabels
renvoie des cadres de délimitation uniquement si le modèle est entraîné à détecter l'emplacement des objets.
La confiance de la fonctionnalité Étiquettes personnalisées Amazon Rekognition quant à la précision de l’étiquette et du cadre de délimitation.
Pour filtrer les étiquettes en fonction du niveau de confiance de détection, spécifiez une valeur pour MinConfidence
correspondant au niveau de confiance souhaité. Par exemple, si vous devez être très sûr de la prédiction, spécifiez une valeur élevée pour MinConfidence
. Pour obtenir toutes les étiquettes, quel que soit le niveau de confiance, spécifiez une valeur MinConfidence
de 0.
Les performances de votre modèle sont mesurées, en partie, par les métriques de rappel et de précision calculées lors de l’entraînement du modèle. Pour plus d’informations, consultez Métriques d’évaluation du modèle.
Pour augmenter la précision de votre modèle, définissez une valeur plus élevée pour MinConfidence
. Pour plus d’informations, consultez Réduction des faux positifs (plus grande précision).
Pour augmenter le rappel de votre modèle, utilisez une valeur inférieure pour MinConfidence
. Pour plus d’informations, consultez Réduction des faux négatifs (meilleur rappel).
Si vous ne spécifiez aucune valeur pour MinConfidence
, la fonctionnalité Étiquettes personnalisées Amazon Rekognition renvoie une étiquette basée sur le seuil supposé pour cette étiquette. Pour plus d’informations, consultez Seuil supposé. Vous pouvez obtenir la valeur du seuil supposé d’une étiquette à partir des résultats d’entraînement du modèle. Pour plus d’informations, consultez Entraînement d’un modèle (console).
En utilisant le paramètre d’entrée MinConfidence
, vous spécifiez le seuil souhaité pour l’appel. Les étiquettes détectées avec un niveau de confiance inférieur à la valeur de MinConfidence
ne sont pas renvoyées dans la réponse. De plus, le seuil supposé pour une étiquette n’affecte pas l’inclusion de l’étiquette dans la réponse.
Les métriques Étiquettes personnalisées Amazon Rekognition expriment un seuil supposé sous la forme d’une valeur à virgule flottante comprise entre 0 et 1. La plage de MinConfidence
normalise le seuil à une valeur en pourcentage (0-100). Les réponses de confiance de DetectCustomLabels sont également renvoyées sous forme de pourcentage.
Vous pouvez vouloir spécifier un seuil pour des étiquettes spécifiques. Par exemple, lorsque la métrique de précision est acceptable pour l’étiquette A, mais pas pour l’étiquette B. Lorsque vous spécifiez un seuil différent (MinConfidence
), tenez compte des points suivants.
Si vous n’êtes intéressé que par une seule étiquette (A), définissez la valeur de MinConfidence
sur le seuil souhaité. Dans la réponse, les prédictions pour l’étiquette A sont renvoyées (ainsi que pour les autres étiquettes) uniquement si le niveau de confiance est supérieur à MinConfidence
. Vous devez filtrer toutes les autres étiquettes renvoyées.
Si vous souhaitez appliquer différents seuils à plusieurs étiquettes, procédez comme suit :
Utilisez une valeur 0 pour MinConfidence
. La valeur 0 garantit que toutes les étiquettes sont renvoyées, quel que soit le niveau de confiance de détection.
Pour chaque étiquette renvoyée, appliquez le seuil souhaité en vérifiant que le niveau de confiance de l’étiquette est supérieur au seuil que vous souhaitez pour l’étiquette.
Pour plus d’informations, consultez Amélioration d’un modèle entraîné Étiquettes personnalisées Amazon Rekognition.
Si vous trouvez que les valeurs de confiance renvoyées par DetectCustomLabels
sont trop faibles, pensez à entraîner à nouveau le modèle. Pour plus d’informations, consultez Entraînement d’un modèle Étiquettes personnalisées Amazon Rekognition. Vous pouvez limiter le nombre d’étiquettes personnalisées renvoyées par DetectCustomLabels
en spécifiant le paramètre d’entrée MaxResults
. Les résultats sont renvoyés triés du niveau de confiance le plus élevé au niveau de confiance le plus faible.
Pour d’autres exemples appelant DetectCustomLabels
, consultez Exemples d'étiquettes personnalisées.
Pour plus d’informations sur la sécurisation de DetectCustomLabels
, consultez SécurisationDetectCustomLabels.
Pour détecter les étiquettes personnalisées (API)
Si vous ne l’avez pas déjà fait :
Veillez à disposer des autorisations DetectCustomLabels
et AmazonS3ReadOnlyAccess
. Pour de plus amples informations, veuillez consulter Configuration des autorisations du kit SDK.
Installez et configurez le AWS CLI et le AWS SDKs. Pour de plus amples informations, veuillez consulter Étape 4 : Configuration des AWS SDK AWS CLI et.
Entraînez et déployez votre modèle. Pour plus d’informations, consultez Création d'un modèle d'étiquettes personnalisées Amazon Rekognition.
Veillez à ce que l’utilisateur qui appelle DetectCustomLabels
a accès au modèle que vous avez utilisé à l’étape 2. Pour plus d’informations, consultez SécurisationDetectCustomLabels.
-
Chargez une image que vous souhaitez analyser dans un compartiment S3.
Pour en savoir plus, consultez Chargement d’objets dans Amazon S3 dans le Guide de l’utilisateur Amazon Simple Storage Service. Les exemples Python, Java et Java 2 vous montrent également comment utiliser un fichier image local pour transmettre une image en utilisant des octets bruts. La taille du fichier doit être inférieure à 4 Mo.
Utilisez les exemples suivants pour appeler l’opération DetectCustomLabels
. Les exemples Python et Java montrent l’image et superposent les résultats de l’analyse, comme dans l’image suivante. Les images suivantes contiennent des boîtes de délimitation et des étiquettes pour une carte de circuit avec un potentiomètre, un phototransistor infrarouge et des composants. LED
- AWS CLI
-
Cette AWS CLI commande affiche le JSON résultat de l'DetectCustomLabels
CLIopération. Modifiez les valeurs des paramètres d’entrée suivants.
bucket
avec le nom du compartiment Amazon S3 que vous avez utilisé à l’étape 4.
image
avec le nom du fichier image d’entrée que vous avez chargé à l’étape 4.
projectVersionArn
avec ARN le modèle que vous souhaitez utiliser.
aws rekognition detect-custom-labels --project-version-arn model_arn
\
--image '{"S3Object":{"Bucket":"bucket
","Name":"image
"}}' \
--min-confidence 70 \
--profile custom-labels-access
- Python
-
L’exemple de code suivant affiche les cadres de délimitation et les étiquettes de niveau d’image trouvés dans une image.
Pour analyser une image locale, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Pour analyser une image stockée dans un compartiment Amazon S3, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Le ARN modèle avec lequel vous souhaitez analyser l'image.
Le nom et l’emplacement d’une image dans le compartiment Amazon S3 que vous avez utilisée à l’étape 4.
--bucket
bucket name
— Le compartiment Amazon S3 que vous avez utilisé à l'étape 4.
Notez que cet exemple suppose que votre version de Pillow est >= 8.0.0.
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Purpose
Amazon Rekognition Custom Labels detection example used in the service documentation:
https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/detecting-custom-labels.html
Shows how to detect custom labels by using an Amazon Rekognition Custom Labels model.
The image can be stored on your local computer or in an Amazon S3 bucket.
"""
import io
import logging
import argparse
import boto3
from PIL import Image, ImageDraw, ImageFont
from botocore.exceptions import ClientError
logger = logging.getLogger(__name__)
def analyze_local_image(rek_client, model, photo, min_confidence):
"""
Analyzes an image stored as a local file.
:param rek_client: The Amazon Rekognition Boto3 client.
:param s3_connection: The Amazon S3 Boto3 S3 connection object.
:param model: The ARN of the Amazon Rekognition Custom Labels model that you want to use.
:param photo: The name and file path of the photo that you want to analyze.
:param min_confidence: The desired threshold/confidence for the call.
"""
try:
logger.info("Analyzing local file: %s", photo)
image = Image.open(photo)
image_type = Image.MIME[image.format]
if (image_type == "image/jpeg" or image_type == "image/png") is False:
logger.error("Invalid image type for %s", photo)
raise ValueError(
f"Invalid file format. Supply a jpeg or png format file: {photo}"
)
# get images bytes for call to detect_anomalies
image_bytes = io.BytesIO()
image.save(image_bytes, format=image.format)
image_bytes = image_bytes.getvalue()
response = rek_client.detect_custom_labels(Image={'Bytes': image_bytes},
MinConfidence=min_confidence,
ProjectVersionArn=model)
show_image(image, response)
return len(response['CustomLabels'])
except ClientError as client_err:
logger.error(format(client_err))
raise
except FileNotFoundError as file_error:
logger.error(format(file_error))
raise
def analyze_s3_image(rek_client, s3_connection, model, bucket, photo, min_confidence):
"""
Analyzes an image stored in the specified S3 bucket.
:param rek_client: The Amazon Rekognition Boto3 client.
:param s3_connection: The Amazon S3 Boto3 S3 connection object.
:param model: The ARN of the Amazon Rekognition Custom Labels model that you want to use.
:param bucket: The name of the S3 bucket that contains the image that you want to analyze.
:param photo: The name of the photo that you want to analyze.
:param min_confidence: The desired threshold/confidence for the call.
"""
try:
# Get image from S3 bucket.
logger.info("analyzing bucket: %s image: %s", bucket, photo)
s3_object = s3_connection.Object(bucket, photo)
s3_response = s3_object.get()
stream = io.BytesIO(s3_response['Body'].read())
image = Image.open(stream)
image_type = Image.MIME[image.format]
if (image_type == "image/jpeg" or image_type == "image/png") is False:
logger.error("Invalid image type for %s", photo)
raise ValueError(
f"Invalid file format. Supply a jpeg or png format file: {photo}")
ImageDraw.Draw(image)
# Call DetectCustomLabels.
response = rek_client.detect_custom_labels(
Image={'S3Object': {'Bucket': bucket, 'Name': photo}},
MinConfidence=min_confidence,
ProjectVersionArn=model)
show_image(image, response)
return len(response['CustomLabels'])
except ClientError as err:
logger.error(format(err))
raise
def show_image(image, response):
"""
Displays the analyzed image and overlays analysis results
:param image: The analyzed image
:param response: the response from DetectCustomLabels
"""
try:
font_size = 40
line_width = 5
img_width, img_height = image.size
draw = ImageDraw.Draw(image)
# Calculate and display bounding boxes for each detected custom label.
image_level_label_height = 0
for custom_label in response['CustomLabels']:
confidence = int(round(custom_label['Confidence'], 0))
label_text = f"{custom_label['Name']}:{confidence}%"
fnt = ImageFont.truetype('Tahoma.ttf', font_size)
text_left, text_top, text_right, text_bottom = draw.textbbox((0, 0), label_text, fnt)
text_width, text_height = text_right - text_left, text_bottom - text_top
logger.info("Label: %s", custom_label['Name'])
logger.info("Confidence: %s", confidence)
# Draw bounding boxes, if present
if 'Geometry' in custom_label:
box = custom_label['Geometry']['BoundingBox']
left = img_width * box['Left']
top = img_height * box['Top']
width = img_width * box['Width']
height = img_height * box['Height']
logger.info("Bounding box")
logger.info("\tLeft: {0:.0f}".format(left))
logger.info("\tTop: {0:.0f}".format(top))
logger.info("\tLabel Width: {0:.0f}".format(width))
logger.info("\tLabel Height: {0:.0f}".format(height))
points = (
(left, top),
(left + width, top),
(left + width, top + height),
(left, top + height),
(left, top))
# Draw bounding box and label text
draw.line(points, fill="limegreen", width=line_width)
draw.rectangle([(left + line_width, top+line_width),
(left + text_width + line_width, top + line_width + text_height)], fill="black")
draw.text((left + line_width, top + line_width),
label_text, fill="limegreen", font=fnt)
# draw image-level label text.
else:
draw.rectangle([(10, image_level_label_height),
(text_width + 10, image_level_label_height+text_height)], fill="black")
draw.text((10, image_level_label_height),
label_text, fill="limegreen", font=fnt)
image_level_label_height += text_height
image.show()
except Exception as err:
logger.error(format(err))
raise
def add_arguments(parser):
"""
Adds command line arguments to the parser.
:param parser: The command line parser.
"""
parser.add_argument(
"model_arn", help="The ARN of the model that you want to use."
)
parser.add_argument(
"image", help="The path and file name of the image that you want to analyze"
)
parser.add_argument(
"--bucket", help="The bucket that contains the image. If not supplied, image is assumed to be a local file.", required=False
)
def main():
try:
logging.basicConfig(level=logging.INFO,
format="%(levelname)s: %(message)s")
# Get command line arguments.
parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
add_arguments(parser)
args = parser.parse_args()
label_count = 0
min_confidence = 50
session = boto3.Session(profile_name='custom-labels-access')
rekognition_client = session.client("rekognition")
if args.bucket is None:
# Analyze local image.
label_count = analyze_local_image(rekognition_client,
args.model_arn,
args.image,
min_confidence)
else:
# Analyze image in S3 bucket.
s3_connection = session.resource('s3')
label_count = analyze_s3_image(rekognition_client,
s3_connection,
args.model_arn,
args.bucket,
args.image,
min_confidence)
print(f"Custom labels detected: {label_count}")
except ClientError as client_err:
print("A service client error occurred: " +
format(client_err.response["Error"]["Message"]))
except ValueError as value_err:
print("A value error occurred: " + format(value_err))
except FileNotFoundError as file_error:
print("File not found error: " + format(file_error))
except Exception as err:
print("An error occurred: " + format(err))
if __name__ == "__main__":
main()
- Java
-
L’exemple de code suivant affiche les cadres de délimitation et les étiquettes de niveau d’image trouvés dans une image.
Pour analyser une image locale, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Pour analyser une image stockée dans un compartiment Amazon S3, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Le ARN modèle avec lequel vous souhaitez analyser l'image.
Le nom et l’emplacement d’une image dans le compartiment Amazon S3 que vous avez utilisée à l’étape 4.
Le compartiment Amazon S3 contenant l’image que vous avez utilisée à l’étape 4.
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package com.amazonaws.samples;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.awt.font.FontRenderContext;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
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.CustomLabel;
import com.amazonaws.services.rekognition.model.DetectCustomLabelsRequest;
import com.amazonaws.services.rekognition.model.DetectCustomLabelsResult;
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;
import com.amazonaws.services.rekognition.model.AmazonRekognitionException;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.util.IOUtils;
// Calls DetectCustomLabels and displays a bounding box around each detected image.
public class DetectCustomLabels extends JPanel {
private transient DetectCustomLabelsResult response;
private transient Dimension dimension;
private transient BufferedImage image;
public static final Logger logger = Logger.getLogger(DetectCustomLabels.class.getName());
// Finds custom labels in an image stored in an S3 bucket.
public DetectCustomLabels(AmazonRekognition rekClient,
AmazonS3 s3client,
String projectVersionArn,
String bucket,
String key,
Float minConfidence) throws AmazonRekognitionException, AmazonS3Exception, IOException {
logger.log(Level.INFO, "Processing S3 bucket: {0} image {1}", new Object[] { bucket, key });
// Get image from S3 bucket and create BufferedImage
com.amazonaws.services.s3.model.S3Object s3object = s3client.getObject(bucket, key);
S3ObjectInputStream inputStream = s3object.getObjectContent();
image = ImageIO.read(inputStream);
// Set image size
setWindowDimensions();
DetectCustomLabelsRequest request = new DetectCustomLabelsRequest()
.withProjectVersionArn(projectVersionArn)
.withImage(new Image().withS3Object(new S3Object().withName(key).withBucket(bucket)))
.withMinConfidence(minConfidence);
// Call DetectCustomLabels
response = rekClient.detectCustomLabels(request);
logFoundLabels(response.getCustomLabels());
drawLabels();
}
// Finds custom label in a local image file.
public DetectCustomLabels(AmazonRekognition rekClient,
String projectVersionArn,
String photo,
Float minConfidence)
throws IOException, AmazonRekognitionException {
logger.log(Level.INFO, "Processing local file: {0}", photo);
// Get image bytes and buffered image
ByteBuffer imageBytes;
try (InputStream inputStream = new FileInputStream(new File(photo))) {
imageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream));
}
// Get image for display
InputStream imageBytesStream;
imageBytesStream = new ByteArrayInputStream(imageBytes.array());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image = ImageIO.read(imageBytesStream);
ImageIO.write(image, "jpg", baos);
// Set image size
setWindowDimensions();
// Analyze image
DetectCustomLabelsRequest request = new DetectCustomLabelsRequest()
.withProjectVersionArn(projectVersionArn)
.withImage(new Image()
.withBytes(imageBytes))
.withMinConfidence(minConfidence);
response = rekClient.detectCustomLabels(request);
logFoundLabels(response.getCustomLabels());
drawLabels();
}
// Log the labels found by DetectCustomLabels
private void logFoundLabels(List<CustomLabel> customLabels) {
logger.info("Custom labels found");
if (customLabels.isEmpty()) {
logger.log(Level.INFO, "No Custom Labels found. Consider lowering min confidence.");
} else {
for (CustomLabel customLabel : customLabels) {
logger.log(Level.INFO, " Label: {0} Confidence: {1}",
new Object[] { customLabel.getName(), customLabel.getConfidence() });
}
}
}
// Sets window dimensions to 1/2 screen size, unless image is smaller
public void setWindowDimensions() {
dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
dimension.width = (int) dimension.getWidth() / 2;
if (image.getWidth() < dimension.width) {
dimension.width = image.getWidth();
}
dimension.height = (int) dimension.getHeight() / 2;
if (image.getHeight() < dimension.height) {
dimension.height = image.getHeight();
}
setPreferredSize(dimension);
}
// Draws the image containing the bounding boxes and labels.
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g; // Create a Java2D version of g.
// Draw the image.
g2d.drawImage(image, 0, 0, dimension.width, dimension.height, this);
}
public void drawLabels() {
// Draws bounding boxes (if present) and label text.
int boundingBoxBorderWidth = 5;
int imageHeight = image.getHeight(this);
int imageWidth = image.getWidth(this);
// Set up drawing
Graphics2D g2d = image.createGraphics();
g2d.setColor(Color.GREEN);
g2d.setFont(new Font("Tahoma", Font.PLAIN, 50));
Font font = g2d.getFont();
FontRenderContext frc = g2d.getFontRenderContext();
g2d.setStroke(new BasicStroke(boundingBoxBorderWidth));
List<CustomLabel> customLabels = response.getCustomLabels();
int imageLevelLabelHeight = 0;
for (CustomLabel customLabel : customLabels) {
String label = customLabel.getName();
int textWidth = (int) (font.getStringBounds(label, frc).getWidth());
int textHeight = (int) (font.getStringBounds(label, frc).getHeight());
// Draw bounding box, if present
if (customLabel.getGeometry() != null) {
BoundingBox box = customLabel.getGeometry().getBoundingBox();
float left = imageWidth * box.getLeft();
float top = imageHeight * box.getTop();
// Draw black rectangle
g2d.setColor(Color.BLACK);
g2d.fillRect(Math.round(left + (boundingBoxBorderWidth)), Math.round(top + (boundingBoxBorderWidth)),
textWidth + boundingBoxBorderWidth, textHeight + boundingBoxBorderWidth);
// Write label onto black rectangle
g2d.setColor(Color.GREEN);
g2d.drawString(label, left + boundingBoxBorderWidth, (top + textHeight));
// Draw bounding box around label location
g2d.drawRect(Math.round(left), Math.round(top), Math.round((imageWidth * box.getWidth())),
Math.round((imageHeight * box.getHeight())));
}
// Draw image level labels.
else {
// Draw black rectangle
g2d.setColor(Color.BLACK);
g2d.fillRect(10, 10 + imageLevelLabelHeight, textWidth, textHeight);
g2d.setColor(Color.GREEN);
g2d.drawString(label, 10, textHeight + imageLevelLabelHeight);
imageLevelLabelHeight += textHeight;
}
}
g2d.dispose();
}
public static void main(String args[]) throws Exception {
String photo = null;
String bucket = null;
String projectVersionArn = null;
float minConfidence = 50;
final String USAGE = "\n" + "Usage: " + "<model_arn> <image> <bucket>\n\n" + "Where:\n"
+ " model_arn - The ARN of the model that you want to use. \n\n"
+ " image - The location of the image on your local file system or within an S3 bucket.\n\n"
+ " bucket - The S3 bucket that contains the image. Don't specify if image is local.\n\n";
// Collect the arguments. If 3 arguments are present, the image is assumed to be
// in an S3 bucket.
if (args.length < 2 || args.length > 3) {
System.out.println(USAGE);
System.exit(1);
}
projectVersionArn = args[0];
photo = args[1];
if (args.length == 3) {
bucket = args[2];
}
DetectCustomLabels panel = null;
try {
AWSCredentialsProvider provider =new ProfileCredentialsProvider("custom-labels-access");
AmazonRekognition rekClient = AmazonRekognitionClientBuilder.standard()
.withCredentials(provider)
.withRegion(Regions.US_WEST_2)
.build();
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
.withCredentials(provider)
.withRegion(Regions.US_WEST_2)
.build();
// Create frame and panel.
JFrame frame = new JFrame("Custom Labels");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
if (args.length == 2) {
// Analyze local image
panel = new DetectCustomLabels(rekClient, projectVersionArn, photo, minConfidence);
} else {
// Analyze image in S3 bucket
panel = new DetectCustomLabels(rekClient, s3client, projectVersionArn, bucket, photo, minConfidence);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
} catch (AmazonRekognitionException rekError) {
String errorMessage = "Rekognition client error: " + rekError.getMessage();
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (FileNotFoundException fileError) {
String errorMessage = "File not found: " + photo;
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (IOException fileError) {
String errorMessage = "Input output exception: " + fileError.getMessage();
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (AmazonS3Exception s3Error) {
String errorMessage = "S3 error: " + s3Error.getErrorMessage();
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
}
}
}
- Java V2
-
L’exemple de code suivant affiche les cadres de délimitation et les étiquettes de niveau d’image trouvés dans une image.
Pour analyser une image locale, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Pour analyser une image stockée dans un compartiment S3, exécutez le programme et fournissez les arguments de ligne de commande suivants :
Le ARN modèle avec lequel vous souhaitez analyser l'image.
Le nom et l’emplacement d’une image dans le compartiment S3 que vous avez utilisée à l’étape 4.
Le compartiment Amazon S3 contenant l’image que vous avez utilisée à l’étape 4.
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package com.example.rekognition;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.sync.ResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rekognition.RekognitionClient;
import software.amazon.awssdk.services.rekognition.model.S3Object;
import software.amazon.awssdk.services.rekognition.model.Image;
import software.amazon.awssdk.services.rekognition.model.DetectCustomLabelsRequest;
import software.amazon.awssdk.services.rekognition.model.DetectCustomLabelsResponse;
import software.amazon.awssdk.services.rekognition.model.CustomLabel;
import software.amazon.awssdk.services.rekognition.model.RekognitionException;
import software.amazon.awssdk.services.rekognition.model.BoundingBox;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.NoSuchBucketException;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.util.logging.Level;
import java.util.logging.Logger;
// Calls DetectCustomLabels on an image. Displays bounding boxes or
// image level labels found in the image.
public class ShowCustomLabels extends JPanel {
private transient BufferedImage image;
private transient DetectCustomLabelsResponse response;
private transient Dimension dimension;
public static final Logger logger = Logger.getLogger(ShowCustomLabels.class.getName());
// Finds custom labels in an image stored in an S3 bucket.
public ShowCustomLabels(RekognitionClient rekClient,
S3Client s3client,
String projectVersionArn,
String bucket,
String key,
Float minConfidence) throws RekognitionException, NoSuchBucketException, NoSuchKeyException, IOException {
logger.log(Level.INFO, "Processing S3 bucket: {0} image {1}", new Object[] { bucket, key });
// Get image from S3 bucket and create BufferedImage
GetObjectRequest requestObject = GetObjectRequest.builder().bucket(bucket).key(key).build();
ResponseBytes<GetObjectResponse> result = s3client.getObject(requestObject, ResponseTransformer.toBytes());
ByteArrayInputStream bis = new ByteArrayInputStream(result.asByteArray());
image = ImageIO.read(bis);
// Set image size
setWindowDimensions();
// Construct request parameter for DetectCustomLabels
S3Object s3Object = S3Object.builder().bucket(bucket).name(key).build();
Image s3Image = Image.builder().s3Object(s3Object).build();
DetectCustomLabelsRequest request = DetectCustomLabelsRequest.builder().image(s3Image)
.projectVersionArn(projectVersionArn).minConfidence(minConfidence).build();
response = rekClient.detectCustomLabels(request);
logFoundLabels(response.customLabels());
drawLabels();
}
// Finds custom label in a local image file.
public ShowCustomLabels(RekognitionClient rekClient,
String projectVersionArn,
String photo,
Float minConfidence)
throws IOException, RekognitionException {
logger.log(Level.INFO, "Processing local file: {0}", photo);
// Get image bytes and buffered image
InputStream sourceStream = new FileInputStream(new File(photo));
SdkBytes imageBytes = SdkBytes.fromInputStream(sourceStream);
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes.asByteArray());
image = ImageIO.read(inputStream);
setWindowDimensions();
// Construct request parameter for DetectCustomLabels
Image localImageBytes = Image.builder().bytes(imageBytes).build();
DetectCustomLabelsRequest request = DetectCustomLabelsRequest.builder().image(localImageBytes)
.projectVersionArn(projectVersionArn).minConfidence(minConfidence).build();
response = rekClient.detectCustomLabels(request);
logFoundLabels(response.customLabels());
drawLabels();
}
// Sets window dimensions to 1/2 screen size, unless image is smaller
public void setWindowDimensions() {
dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
dimension.width = (int) dimension.getWidth() / 2;
if (image.getWidth() < dimension.width) {
dimension.width = image.getWidth();
}
dimension.height = (int) dimension.getHeight() / 2;
if (image.getHeight() < dimension.height) {
dimension.height = image.getHeight();
}
setPreferredSize(dimension);
}
// Draws bounding boxes (if present) and label text.
public void drawLabels() {
int boundingBoxBorderWidth = 5;
int imageHeight = image.getHeight(this);
int imageWidth = image.getWidth(this);
// Set up drawing
Graphics2D g2d = image.createGraphics();
g2d.setColor(Color.GREEN);
g2d.setFont(new Font("Tahoma", Font.PLAIN, 50));
Font font = g2d.getFont();
FontRenderContext frc = g2d.getFontRenderContext();
g2d.setStroke(new BasicStroke(boundingBoxBorderWidth));
List<CustomLabel> customLabels = response.customLabels();
int imageLevelLabelHeight = 0;
for (CustomLabel customLabel : customLabels) {
String label = customLabel.name();
int textWidth = (int) (font.getStringBounds(label, frc).getWidth());
int textHeight = (int) (font.getStringBounds(label, frc).getHeight());
// Draw bounding box, if present
if (customLabel.geometry() != null) {
BoundingBox box = customLabel.geometry().boundingBox();
float left = imageWidth * box.left();
float top = imageHeight * box.top();
// Draw black rectangle
g2d.setColor(Color.BLACK);
g2d.fillRect(Math.round(left + (boundingBoxBorderWidth)), Math.round(top + (boundingBoxBorderWidth)),
textWidth + boundingBoxBorderWidth, textHeight + boundingBoxBorderWidth);
// Write label onto black rectangle
g2d.setColor(Color.GREEN);
g2d.drawString(label, left + boundingBoxBorderWidth, (top + textHeight));
// Draw bounding box around label location
g2d.drawRect(Math.round(left), Math.round(top), Math.round((imageWidth * box.width())),
Math.round((imageHeight * box.height())));
}
// Draw image level labels.
else {
// Draw black rectangle
g2d.setColor(Color.BLACK);
g2d.fillRect(10, 10 + imageLevelLabelHeight, textWidth, textHeight);
g2d.setColor(Color.GREEN);
g2d.drawString(label, 10, textHeight + imageLevelLabelHeight);
imageLevelLabelHeight += textHeight;
}
}
g2d.dispose();
}
// Log the labels found by DetectCustomLabels
private void logFoundLabels(List<CustomLabel> customLabels) {
logger.info("Custom labels found:");
if (customLabels.isEmpty()) {
logger.log(Level.INFO, "No Custom Labels found. Consider lowering min confidence.");
}
else {
for (CustomLabel customLabel : customLabels) {
logger.log(Level.INFO, " Label: {0} Confidence: {1}",
new Object[] { customLabel.name(), customLabel.confidence() } );
}
}
}
// Draws the image containing the bounding boxes and labels.
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g; // Create a Java2D version of g.
// Draw the image.
g2d.drawImage(image, 0, 0, dimension.width, dimension.height, this);
}
public static void main(String args[]) throws Exception {
String photo = null;
String bucket = null;
String projectVersionArn = null;
final String USAGE = "\n" + "Usage: " + "<model_arn> <image> <bucket>\n\n" + "Where:\n"
+ " model_arn - The ARN of the model that you want to use. \n\n"
+ " image - The location of the image on your local file system or within an S3 bucket.\n\n"
+ " bucket - The S3 bucket that contains the image. Don't specify if image is local.\n\n";
// Collect the arguments. If 3 arguments are present, the image is assumed to be
// in an S3 bucket.
if (args.length < 2 || args.length > 3) {
System.out.println(USAGE);
System.exit(1);
}
projectVersionArn = args[0];
photo = args[1];
if (args.length == 3) {
bucket = args[2];
}
float minConfidence = 50;
ShowCustomLabels panel = null;
try {
// Get the Rekognition client
// Get the Rekognition client.
RekognitionClient rekClient = RekognitionClient.builder()
.credentialsProvider(ProfileCredentialsProvider.create("custom-labels-access"))
.region(Region.US_WEST_2)
.build();
S3Client s3Client = S3Client.builder()
.credentialsProvider(ProfileCredentialsProvider.create("custom-labels-access"))
.region(Region.US_WEST_2)
.build();
// Create frame and panel.
JFrame frame = new JFrame("Custom Labels");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
if (args.length == 2) {
// Analyze local image
panel = new ShowCustomLabels(rekClient, projectVersionArn, photo, minConfidence);
} else {
// Analyze image in S3 bucket
panel = new ShowCustomLabels(rekClient, s3Client, projectVersionArn, bucket, photo, minConfidence);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
} catch (RekognitionException rekError) {
String errorMessage = "Rekognition client error: " + rekError.getMessage();
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (FileNotFoundException fileError) {
String errorMessage = "File not found: " + photo;
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (IOException fileError) {
String errorMessage = "Input output exception: " + fileError.getMessage();
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (NoSuchKeyException bucketError) {
String errorMessage = String.format("Image not found: %s in bucket %s.", photo, bucket);
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
} catch (NoSuchBucketException bucketError) {
String errorMessage = "Bucket not found: " + bucket;
logger.log(Level.SEVERE, errorMessage);
System.out.println(errorMessage);
System.exit(1);
}
}
}
DetectCustomLabels demande d'opération
Dans le cadre de l’opération DetectCustomLabels
, vous fournissez une image d’entrée sous la forme d’un tableau d’octets encodé en base64 ou en tant qu’image stockée dans un compartiment Amazon S3. L'exemple de JSON demande suivant montre l'image chargée depuis un compartiment Amazon S3.
{
"ProjectVersionArn": "string",
"Image":{
"S3Object":{
"Bucket":"string",
"Name":"string",
"Version":"string"
}
},
"MinConfidence": 90,
"MaxLabels": 10,
}
DetectCustomLabels réponse à l'opération
La JSON réponse suivante à l'DetectCustomLabels
opération montre les étiquettes personnalisées détectées dans l'image suivante.
{
"CustomLabels": [
{
"Name": "MyLogo",
"Confidence": 77.7729721069336,
"Geometry": {
"BoundingBox": {
"Width": 0.198987677693367,
"Height": 0.31296101212501526,
"Left": 0.07924537360668182,
"Top": 0.4037395715713501
}
}
}
]
}