훈련된 모델을 사용한 이미지 분석 - Rekognition

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

훈련된 모델을 사용한 이미지 분석

훈련된 Amazon Rekognition 사용자 지정 레이블 모델로 이미지를 분석하려면 를 호출합니다. DetectCustomLabelsAPI DetectCustomLabels의 결과는 이미지에 특정 객체, 장면 또는 개념이 포함되어 있다는 예측입니다.

DetectCustomLabels를 직접 호출하려면 다음을 지정해야 합니다.

  • 사용하려는 Amazon Rekognition 사용자 지정 레이블 모델의 아마존 리소스 이름 (ARN).

  • 모델이 예측에 사용할 이미지 입력 이미지를 이미지 바이트 배열(base64 인코딩 이미지 바이트) 또는 Amazon S3 객체로 제공할 수 있습니다. 자세한 정보는 이미지를 참조하세요.

사용자 지정 레이블은 Custom Label 객체의 배열로 반환됩니다. 각 사용자 지정 레이블은 이미지에 있는 단일 객체, 장면 또는 개념을 나타냅니다. 사용자 지정 레이블에는 다음이 포함됩니다.

  • 이미지에 있는 객체, 장면 또는 개념의 레이블.

  • 이미지에 있는 객체의 경계 상자. 경계 상자 좌표는 원본 이미지에서 객체가 어디 있는지를 나타냅니다. 좌표 값은 전체 이미지 크기의 비율입니다. 자세한 내용은 을 참조하십시오. BoundingBox DetectCustomLabels모델이 객체 위치를 감지하도록 훈련된 경우에만 경계 상자를 반환합니다.

  • Amazon Rekognition Custom Labels가 레이블과 경계 상자의 정확성에 대해 갖고 있는 신뢰도.

탐지 신뢰도를 기준으로 레이블을 필터링하려면 MinConfidence에 원하는 신뢰 수준을 값으로 지정하세요. 예를 들어 예측에 대한 높은 신뢰도가 필요한 경우 MinConfidence에 높은 값을 지정하세요. 신뢰도에 관계없이 모든 레이블을 가져오려면 MinConfidence 값을 0으로 지정하세요.

모델의 성능은 부분적으로 모델 훈련 중에 계산된 재현율 및 정밀도 지표에 의해 측정됩니다. 자세한 내용은 모델 평가를 위한 지표 단원을 참조하십시오.

모델의 정밀도를 높이려면 MinConfidence의 값을 더 높게 설정하세요. 자세한 내용은 거짓 긍정 감소(정밀도 향상) 단원을 참조하십시오.

모델의 재현율을 높이려면 MinConfidence에 대해 더 낮은 값을 사용하세요. 자세한 내용은 거짓 긍정 감소(기억력 향상) 단원을 참조하십시오.

MinConfidence에 값을 지정하지 않으면 Amazon Rekognition Custom Labels는 해당 레이블에 대해 가정된 임계값을 기반으로 레이블을 반환합니다. 자세한 내용은 추정 임계값 단원을 참조하십시오. 모델의 훈련 결과에서 레이블에 대한 추정 임계값 값을 가져올 수 있습니다. 자세한 내용은 모델 훈련(콘솔) 단원을 참조하십시오.

MinConfidence 입력 파라미터를 사용하면 직접 호출에 대해 원하는 임계값을 지정할 수 있습니다. 신뢰도가 MinConfidence의 값 미만인 것으로 감지된 레이블은 응답으로 반환되지 않습니다. 또한 레이블에 대해 가정된 임계값은 응답에 레이블이 포함되는 데 영향을 주지 않습니다.

참고

Amazon Rekognition Custom Labels 지표는 가정된 임계값을 0-1 사이의 부동 소수점 값으로 표시합니다. MinConfidence의 범위는 임계값을 백분율 값(0-100)으로 정규화합니다. 의 DetectCustomLabels 신뢰도 응답도 백분율로 반환됩니다.

특정 레이블의 임계값을 지정할 수도 있습니다. 예를 들어, 정밀도 측정치를 레이블 A에는 사용할 수 있지만 레이블 B에는 사용할 수 없는 경우가 있습니다. 다른 임계값(MinConfidence)을 지정할 때는 다음 사항을 고려하세요.

  • 단일 레이블(A)에만 관심이 있는 경우 MinConfidence의 값을 원하는 임계값으로 설정하세요. 응답에는 신뢰도가 MinConfidence보다 큰 경우에만 레이블 A에 대한 예측이 다른 레이블과 함께 반환됩니다. 반환되는 다른 레이블은 모두 필터링해야 합니다.

  • 여러 레이블에 서로 다른 임계값을 적용하려면 다음을 수행하세요.

    1. MinConfidence의 값은 0을 사용하세요. 값이 0이면 탐지 신뢰도에 관계없이 모든 레이블이 반환됩니다.

    2. 반환된 각 레이블에 대해 레이블 신뢰도가 레이블에 대해 원하는 임계값보다 큰지 확인하여 원하는 임계값을 적용합니다.

자세한 내용은 훈련된 Amazon Rekognition Custom Labels 모델 개선 단원을 참조하십시오.

DetectCustomLabels에서 반환된 신뢰도 값이 너무 낮으면 모델을 다시 훈련하는 것을 고려하세요. 자세한 내용은 Amazon Rekognition Custom Labels 모델 훈련 단원을 참조하십시오. MaxResults 입력 파라미터를 지정하여 DetectCustomLabels에서 반환되는 사용자 지정 레이블의 수를 제한할 수 있습니다. 결과는 가장 높은 신뢰도에서 가장 낮은 신뢰도 순으로 정렬되어 반환됩니다.

DetectCustomLabels를 직접 호출하는 다른 예제를 보려면 맞춤 라벨 예제 항목을 참조하세요.

DetectCustomLabels 확보에 대한 자세한 내용은 DetectCustomLabels 보호 항목을 참조하세요.

사용자 지정 레이블을 감지하려면 (API)
  1. 아직 하지 않았다면 다음을 수행하세요.

    1. DetectCustomLabelsAmazonS3ReadOnlyAccess의 권한이 있는지 확인하세요. 자세한 내용은 SDK권한 설정 단원을 참조하십시오.

    2. AWS CLI 및 를 설치하고 구성합니다 AWS SDKs. 자세한 내용은 4단계: 설정 AWS CLI 그리고 AWS SDKs 단원을 참조하십시오.

  2. 모델을 훈련하고 배포하세요. 자세한 내용은 Amazon Rekognition Custom Labels 모델 생성 단원을 참조하십시오.

  3. DetectCustomLabels를 직접 호출한 사용자가 2단계에서 사용한 모델에 액세스할 수 있는지 확인하세요. 자세한 내용은 DetectCustomLabels 보호 단원을 참조하십시오.

  4. 분석할 이미지를 S3 버킷에 업로드합니다.

    이에 관한 지침은 Amazon Simple Storage Service 사용 설명서에서 Amazon S3에 객체 업로드를 참조하세요. Python, Java, Java 2 예제는 로컬 이미지 파일을 사용하여 원시 바이트를 사용하여 이미지를 전달하는 방법도 보여줍니다. 파일은 4MB보다 작아야 합니다.

  5. 다음 예제를 사용하여 DetectCustomLabels 작업을 호출합니다. Python 및 Java 예제는 다음 이미지와 마찬가지로 이미지를 표시하고 분석 결과를 오버레이합니다. 다음 이미지에는 전위차계, 적외선 포토트랜지스터 및 부품이 있는 회로 기판의 바운딩 박스와 레이블이 들어 있습니다. LED

    전위차계, 적외선 포토트랜지스터 및 라벨이 부착된 부품이 있는 회로 기판. LED
    AWS CLI

    이 AWS CLI 명령은 작업에 대한 출력을 표시합니다. JSON DetectCustomLabels CLI 다음 입력 파라미터의 값을 변경하세요.

    • bucket을 4단계에서 사용한 Amazon S3 버킷의 이름으로 변경하세요.

    • image를 4단계에서 업로드한 입력 이미지 파일의 이름으로 변경하세요.

    • projectVersionArn사용하려는 모델과 함께. ARN

    aws rekognition detect-custom-labels --project-version-arn model_arn \ --image '{"S3Object":{"Bucket":"bucket","Name":"image"}}' \ --min-confidence 70 \ --profile custom-labels-access
    Python

    다음 예제 코드에는 이미지에 있는 경계 상자와 이미지 레벨 레이블이 표시되어 있습니다.

    로컬 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • 이미지를 분석하는 데 사용할 ARN 모델의.

    • 로컬 이미지 파일의 이름 및 위치.

    Amazon S3 버킷에 저장된 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • 이미지를 분석하는 데 사용하려는 모델의. ARN

    • 4단계에서 사용한 Amazon S3 버킷 내 이미지의 이름 및 위치.

    • --bucket bucket name — 4단계에서 사용한 Amazon S3 버킷.

    참고로 이 예제에서는 현재 사용 중인 Pillow 버전이 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

    다음 예제 코드에는 이미지에 있는 경계 상자와 이미지 레벨 레이블이 표시되어 있습니다.

    로컬 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • 이미지를 분석하는 데 사용하려는 ARN 모델의 모델입니다.

    • 로컬 이미지 파일의 이름 및 위치.

    Amazon S3 버킷에 저장된 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • 이미지를 분석하는 데 사용하려는 모델의. ARN

    • 4단계에서 사용한 Amazon S3 버킷 내 이미지의 이름 및 위치.

    • 4단계에서 사용한 이미지가 포함된 Amazon S3 버킷.

    /* 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

    다음 예제 코드에는 이미지에 있는 경계 상자와 이미지 레벨 레이블이 표시되어 있습니다.

    로컬 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • projectVersionArn— 이미지를 분석하는 데 사용하려는 모델의. ARN

    • photo: 로컬 이미지 파일의 이름 및 위치.

    S3 버킷에 저장된 이미지를 분석하려면 프로그램을 실행하고 다음 명령줄 인수를 제공하세요.

    • 이미지를 분석하는 데 사용하려는 모델의. ARN

    • 4단계에서 사용한 S3 버킷 내 이미지의 이름 및 위치.

    • 4단계에서 사용한 이미지가 포함된 Amazon S3 버킷.

    /* 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 작업 요청

DetectCustomLabels 작업에서 사용자는 입력 이미지를 base64로 인코딩된 바이트 배열 또는 Amazon S3 버킷에 저장된 이미지로 제공합니다. 다음 예제 JSON 요청은 Amazon S3 버킷에서 로드된 이미지를 보여줍니다.

{ "ProjectVersionArn": "string", "Image":{ "S3Object":{ "Bucket":"string", "Name":"string", "Version":"string" } }, "MinConfidence": 90, "MaxLabels": 10, }

DetectCustomLabels 작업 응답

DetectCustomLabels작업의 다음 JSON 응답은 다음 이미지에서 감지된 사용자 지정 레이블을 보여줍니다.

{ "CustomLabels": [ { "Name": "MyLogo", "Confidence": 77.7729721069336, "Geometry": { "BoundingBox": { "Width": 0.198987677693367, "Height": 0.31296101212501526, "Left": 0.07924537360668182, "Top": 0.4037395715713501 } } } ] }