你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

调用图像分析 4.0 API

本文演示如何调用图像分析 4.0 API 以返回有关图像的视觉特征的信息。 它还介绍了如何分析返回的信息。

先决条件

本指南假定你已按照快速入门页中提到的步骤进行操作。 这意味着:

  • 你已经创建了计算机视觉资源 并获取了密钥和终结点 URL。
  • 你已安装相应的 SDK 包,并且有一个正在运行的快速入门应用程序。 可以根据此处的代码示例修改此快速入门应用程序。

创建客户端并对其进行身份验证

若要对图像分析服务进行身份验证,需要计算机视觉密钥和终结点 URL。 本指南假定你使用密钥和终结点定义了环境变量 VISION_KEYVISION_ENDPOINT

提示

请不要直接在代码中包含密钥,并且绝不公开发布密钥。 有关 Azure Key Vault 等更多身份验证选项,请参阅 Azure AI 服务安全性一文。

首先创建 ImageAnalysisClient 对象。 例如:

string endpoint = Environment.GetEnvironmentVariable("VISION_ENDPOINT");
string key = Environment.GetEnvironmentVariable("VISION_KEY");

// Create an Image Analysis client.
ImageAnalysisClient client = new ImageAnalysisClient(
    new Uri(endpoint),
    new AzureKeyCredential(key));

选择要分析的图像

可以通过提供可公开访问的图像 URL 或将二进制数据传递给 SDK 来选择映像。 有关支持的图像格式,请参阅图像要求

图像 URL

为要分析的图像创建 Uri 对象。

Uri imageURL = new Uri("https://aka.ms/azsdk/image-analysis/sample.jpg");

图像缓冲区

或者,可以通过 BinaryData 对象将图像数据传递到 SDK。 例如,从要分析的本地图像文件中读取。

using FileStream stream = new FileStream("sample.jpg", FileMode.Open);
BinaryData imageData = BinaryData.FromStream(stream);

选择视觉特征

使用分析 4.0 API 可以访问所有服务的图像分析特征。 基于自己的用例选择要执行的操作。 有关每种特征的说明,请参阅概述。 本部分中的示例添加了所有可用的视觉功能,但实际使用而言,所需的功能很可能没有这么多。

重要

视觉功能“Captions”和“DenseCaptions”仅在以下 Azure 区域中受支持:美国东部、法国中部、韩国中部、北欧、东南亚、西欧、美国西部。

VisualFeatures visualFeatures =
    VisualFeatures.Caption |
    VisualFeatures.DenseCaptions |
    VisualFeatures.Objects |
    VisualFeatures.Read |
    VisualFeatures.Tags |
    VisualFeatures.People |
    VisualFeatures.SmartCrops;

选择分析选项

使用 ImageAnalysisOptions 对象指定 Analyze API 调用的各种选项。

  • 语言:可以指定返回的数据的语言。 语言为可选项,默认值为英语。 有关支持的语言代码的列表以及每种语言支持的视觉功能的列表,请参阅语言支持
  • 性别中立描述文字:如果要提取描述文字或密集描述文字(使用 VisualFeatures.CaptionVisualFeatures.DenseCaptions),可以请求性别中立描述文字。 性别中立的描述文字为可选项,默认为区分性别的描述文字。 例如,在英语中,当你选择性别中立的描述文字时,“女性”或“男性”等术语将替换为“人员”,而“男孩”或“女孩”则将替换为“儿童”。
  • 裁剪纵横比:纵横比的计算方法是将目标裁剪宽度除以高度。 支持的值为 0.75 到 1.8(含)。 仅当选择 VisualFeatures.SmartCrops 作为可视功能列表的一部分时,设置此属性才具有相关性。 如果选择了 VisualFeatures.SmartCrops,但没有指定纵横比,则服务将返回一条裁剪建议,其中包含它认为合适的纵横比。 在本例中,纵横比介于 0.5 和 2.0(含)之间。
ImageAnalysisOptions options = new ImageAnalysisOptions { 
    GenderNeutralCaption = true,
    Language = "en",
    SmartCropsAspectRatios = new float[] { 0.9F, 1.33F }};

调用分析 API

本部分介绍如何对服务进行分析调用。

ImageAnalysisClient 对象上调用 Analyze 方法,如下所示。 这是一种同步调用,直到服务返回结果或发生错误为止。 或者,也可以调用非阻塞的 AnalyzeAsync 方法。

使用在上述部分中创建的输入对象。 若要从图像缓冲区而不是 URL 进行分析,请将方法调用中的 imageURL 替换为 imageData 变量。

ImageAnalysisResult result = client.Analyze(
    imageURL,
    visualFeatures,
    options);

获取服务结果

以下代码演示如何分析各种 Analyze 操作的结果。

Console.WriteLine("Image analysis results:");

// Print caption results to the console
Console.WriteLine(" Caption:");
Console.WriteLine($"   '{result.Caption.Text}', Confidence {result.Caption.Confidence:F4}");

// Print dense caption results to the console
Console.WriteLine(" Dense Captions:");
foreach (DenseCaption denseCaption in result.DenseCaptions.Values)
{
    Console.WriteLine($"   '{denseCaption.Text}', Confidence {denseCaption.Confidence:F4}, Bounding box {denseCaption.BoundingBox}");
}

// Print object detection results to the console
Console.WriteLine(" Objects:");
foreach (DetectedObject detectedObject in result.Objects.Values)
{
    Console.WriteLine($"   '{detectedObject.Tags.First().Name}', Bounding box {detectedObject.BoundingBox.ToString()}");
}

// Print text (OCR) analysis results to the console
Console.WriteLine(" Read:");
foreach (DetectedTextBlock block in result.Read.Blocks)
    foreach (DetectedTextLine line in block.Lines)
    {
        Console.WriteLine($"   Line: '{line.Text}', Bounding Polygon: [{string.Join(" ", line.BoundingPolygon)}]");
        foreach (DetectedTextWord word in line.Words)
        {
            Console.WriteLine($"     Word: '{word.Text}', Confidence {word.Confidence.ToString("#.####")}, Bounding Polygon: [{string.Join(" ", word.BoundingPolygon)}]");
        }
    }

// Print tags results to the console
Console.WriteLine(" Tags:");
foreach (DetectedTag tag in result.Tags.Values)
{
    Console.WriteLine($"   '{tag.Name}', Confidence {tag.Confidence:F4}");
}

// Print people detection results to the console
Console.WriteLine(" People:");
foreach (DetectedPerson person in result.People.Values)
{
    Console.WriteLine($"   Person: Bounding box {person.BoundingBox.ToString()}, Confidence {person.Confidence:F4}");
}

// Print smart-crops analysis results to the console
Console.WriteLine(" SmartCrops:");
foreach (CropRegion cropRegion in result.SmartCrops.Values)
{
    Console.WriteLine($"   Aspect ratio: {cropRegion.AspectRatio}, Bounding box: {cropRegion.BoundingBox}");
}

// Print metadata
Console.WriteLine(" Metadata:");
Console.WriteLine($"   Model: {result.ModelVersion}");
Console.WriteLine($"   Image width: {result.Metadata.Width}");
Console.WriteLine($"   Image hight: {result.Metadata.Height}");

疑难解答

异常处理

使用 .NET SDK 与图像分析交互时,没有 200(成功)状态代码的服务的任何响应都会导致引发异常。 例如,如果尝试分析由于 URL 损坏而无法访问的图像,则会返回 400 状态,指示请求错误,并引发相应的异常。

在以下代码片段中,通过捕获异常并显示有关错误的其他信息来妥善处理该错误。

var imageUrl = new Uri("https://some-host-name.com/non-existing-image.jpg");

try
{
    var result = client.Analyze(imageUrl, VisualFeatures.Caption);
}
catch (RequestFailedException e)
{
    if (e.Status != 200)
    {
        Console.WriteLine("Error analyzing image.");
        Console.WriteLine($"HTTP status code {e.Status}: {e.Message}");
    }
    else
    {
        throw;
    }
}

可以在此处详细了解如何启用 SDK 日志记录。

先决条件

本指南假定你已成功按照快速入门中提到的步骤进行操作。 这意味着:

  • 你已经创建了计算机视觉资源 并获取了密钥和终结点 URL。
  • 你已安装相应的 SDK 包,并且有一个正在运行的快速入门应用程序。 可以根据此处的代码示例修改此快速入门应用程序。

创建客户端并对其进行身份验证

若要对图像分析服务进行身份验证,需要计算机视觉密钥和终结点 URL。 本指南假定你使用密钥和终结点定义了环境变量 VISION_KEYVISION_ENDPOINT

提示

请不要直接在代码中包含密钥,并且绝不公开发布密钥。 有关 Azure Key Vault 等更多身份验证选项,请参阅 Azure AI 服务安全性一文。

首先使用一个构造函数创建 ImageAnalysisClient 对象。 例如:

client = ImageAnalysisClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(key)
)

选择要分析的图像

可以通过提供可公开访问的图像 URL 或将图像数据读入 SDK 的输入缓冲区来选择映像。 有关支持的图像格式,请参阅图像要求

图像 URL

可使用以下示例图像 URL。

# Define image URL
image_url = "https://learn.microsoft.com/azure/ai-services/computer-vision/media/quickstarts/presentation.png"

图像缓冲区

或者,可以将图像作为 bytes 对象传入。 例如,从要分析的本地图像文件中读取。

# Load image to analyze into a 'bytes' object
with open("sample.jpg", "rb") as f:
    image_data = f.read()

选择视觉特征

使用分析 4.0 API 可以访问所有服务的图像分析特征。 基于自己的用例选择要执行的操作。 有关每种特征的说明,请参阅概述。 本部分中的示例添加了所有可用的视觉功能,但实际使用而言,所需的功能很可能没有这么多。

visual_features =[
        VisualFeatures.TAGS,
        VisualFeatures.OBJECTS,
        VisualFeatures.CAPTION,
        VisualFeatures.DENSE_CAPTIONS,
        VisualFeatures.READ,
        VisualFeatures.SMART_CROPS,
        VisualFeatures.PEOPLE,
    ]

使用选项调用 analyze_from_url 方法

以下代码使用你在上面选择的功能和下面定义的其他选项在客户端上调用 analyze_from_url 方法。 若要从图像缓冲区而不是 URL 进行分析,请转而调用 analyze 方法,并将 image_data=image_data 作为第一个参数。

# Analyze all visual features from an image stream. This will be a synchronously (blocking) call.
result = client.analyze_from_url(
    image_url=image_url,
    visual_features=visual_features,
    smart_crops_aspect_ratios=[0.9, 1.33],
    gender_neutral_caption=True,
    language="en"
)

选择智能裁剪纵横比

纵横比的计算方法是将目标裁剪宽度除以高度。 支持的值为 0.75 到 1.8(含)。 仅当选择 VisualFeatures.SMART_CROPS 作为可视功能列表的一部分时,设置此属性才具有相关性。 如果选择了 VisualFeatures.SMART_CROPS,但没有指定纵横比,则服务将返回一条裁剪建议,其中包含它认为合适的纵横比。 在本例中,纵横比介于 0.5 和 2.0(含)之间。

选择性别中立的描述文字

如果要提取描述文字或密集描述文字(使用 VisualFeatures.CAPTIONVisualFeatures.DENSE_CAPTIONS),可以请求性别中立描述文字。 性别中立的描述文字为可选项,默认为区分性别的描述文字。 例如,在英语中,当你选择性别中立的描述文字时,“女性”或“男性”等术语将替换为“人员”,而“男孩”或“女孩”则将替换为“儿童”。

指定语言

可以指定返回的数据的语言。 语言为可选项,默认值为英语。 有关支持的语言代码的列表以及每种语言支持的视觉功能的列表,请参阅语言支持

获取服务结果

以下代码演示如何分析 analyze_from_url 或 analyze 操作的结果。

# Print all analysis results to the console
print("Image analysis results:")

if result.caption is not None:
    print(" Caption:")
    print(f"   '{result.caption.text}', Confidence {result.caption.confidence:.4f}")

if result.dense_captions is not None:
    print(" Dense Captions:")
    for caption in result.dense_captions.list:
        print(f"   '{caption.text}', {caption.bounding_box}, Confidence: {caption.confidence:.4f}")

if result.read is not None:
    print(" Read:")
    for line in result.read.blocks[0].lines:
        print(f"   Line: '{line.text}', Bounding box {line.bounding_polygon}")
        for word in line.words:
            print(f"     Word: '{word.text}', Bounding polygon {word.bounding_polygon}, Confidence {word.confidence:.4f}")

if result.tags is not None:
    print(" Tags:")
    for tag in result.tags.list:
        print(f"   '{tag.name}', Confidence {tag.confidence:.4f}")

if result.objects is not None:
    print(" Objects:")
    for object in result.objects.list:
        print(f"   '{object.tags[0].name}', {object.bounding_box}, Confidence: {object.tags[0].confidence:.4f}")

if result.people is not None:
    print(" People:")
    for person in result.people.list:
        print(f"   {person.bounding_box}, Confidence {person.confidence:.4f}")

if result.smart_crops is not None:
    print(" Smart Cropping:")
    for smart_crop in result.smart_crops.list:
        print(f"   Aspect ratio {smart_crop.aspect_ratio}: Smart crop {smart_crop.bounding_box}")

print(f" Image height: {result.metadata.height}")
print(f" Image width: {result.metadata.width}")
print(f" Model version: {result.model_version}")

疑难解答

例外

analyze 方法会针对来自服务的非成功 HTTP 状态代码响应引发 HttpResponseError 异常。 异常的 status_code 是 HTTP 响应状态代码。 异常的 error.message 包含一条详细消息,用于诊断问题:

try:
    result = client.analyze( ... )
except HttpResponseError as e:
    print(f"Status code: {e.status_code}")
    print(f"Reason: {e.reason}")
    print(f"Message: {e.error.message}")

例如,当你提供错误的身份验证密钥时:

Status code: 401
Reason: PermissionDenied
Message: Access denied due to invalid subscription key or wrong API endpoint. Make sure to provide a valid key for an active subscription and use a correct regional API endpoint for your resource.

或者,当你提供不存在或不可访问的图像 URL 时:

Status code: 400
Reason: Bad Request
Message: The provided image url is not accessible.

日志记录

客户端使用标准 Python 日志记录库。 SDK 会记录 HTTP 请求和响应详细信息,它们对于故障排除可能很有用。 若要登录到 stdout,请添加以下内容:

import sys
import logging

# Acquire the logger for this client library. Use 'azure' to affect both
# 'azure.core` and `azure.ai.vision.imageanalysis' libraries.
logger = logging.getLogger("azure")

# Set the desired logging level. logging.INFO or logging.DEBUG are good options.
logger.setLevel(logging.INFO)

# Direct logging output to stdout (the default):
handler = logging.StreamHandler(stream=sys.stdout)
# Or direct logging output to a file:
# handler = logging.FileHandler(filename = 'sample.log')
logger.addHandler(handler)

# Optional: change the default logging format. Here we add a timestamp.
formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(name)s:%(message)s")
handler.setFormatter(formatter)

默认情况下,日志会编修 URL 查询字符串的值、某些 HTTP 请求和响应头的值(包括保存密钥的 Ocp-Apim-Subscription-Key)以及请求和响应有效负载。 若要创建日志而不进行编修,请在创建 ImageAnalysisClient 时或对客户端调用 analyze 时设置方法参数 logging_enable = True

# Create an Image Analysis client with none redacted log
client = ImageAnalysisClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(key),
    logging_enable=True
)

仅针对日志级别 logging.DEBUG 生成无编修的日志。 请务必保护无编修的日志,以避免损害安全性。 有关详细信息,请参阅在用于 Python 的 Azure 库中配置日志记录

先决条件

本指南假定你已按照快速入门页中的步骤进行操作。 这意味着:

  • 你已经创建了计算机视觉资源 并获取了密钥和终结点 URL。
  • 你已安装相应的 SDK 包,并且有一个正在运行的快速入门应用程序。 可以根据此处的代码示例修改此快速入门应用程序。

创建客户端并对其进行身份验证

若要对图像分析服务进行身份验证,需要计算机视觉密钥和终结点 URL。 本指南假定你使用密钥和终结点定义了环境变量 VISION_KEYVISION_ENDPOINT

提示

请不要直接在代码中包含密钥,并且绝不公开发布密钥。 有关 Azure Key Vault 等更多身份验证选项,请参阅 Azure AI 服务安全性一文。

首先创建 ImageAnalysisClient 对象。 例如:

String endpoint = System.getenv("VISION_ENDPOINT");
String key = System.getenv("VISION_KEY");

if (endpoint == null || key == null) {
    System.out.println("Missing environment variable 'VISION_ENDPOINT' or 'VISION_KEY'.");
    System.out.println("Set them before running this sample.");
    System.exit(1);
}

// Create a synchronous Image Analysis client.
ImageAnalysisClient client = new ImageAnalysisClientBuilder()
    .endpoint(endpoint)
    .credential(new KeyCredential(key))
    .buildClient();

选择要分析的图像

可以通过提供可公开访问的图像 URL 或将图像数据读入 SDK 的输入缓冲区来选择映像。 有关支持的图像格式,请参阅图像要求

图像 URL

创建一个 imageUrl 字符串,用于保存要分析的图像的可公开访问 URL。

String imageUrl = "https://learn.microsoft.com/azure/ai-services/computer-vision/media/quickstarts/presentation.png";

图像缓冲区

或者,可以使用 BinaryData 对象将图像作为内存缓冲区传入。 例如,从要分析的本地图像文件中读取。

BinaryData imageData = BinaryData.fromFile(new File("sample.png").toPath());

选择视觉特征

使用分析 4.0 API 可以访问所有服务的图像分析特征。 基于自己的用例选择要执行的操作。 有关每种特征的说明,请参阅概述。 本部分中的示例添加了所有可用的视觉功能,但实际使用而言,所需的功能很可能没有这么多。

重要

视觉功能“描述文字”和“密集描述文字”仅在以下 Azure 区域中受支持:美国东部、法国中部、韩国中部、北欧、东南亚、西欧、美国西部。

// visualFeatures: Select one or more visual features to analyze.
List<VisualFeatures> visualFeatures = Arrays.asList(
            VisualFeatures.SMART_CROPS,
            VisualFeatures.CAPTION,
            VisualFeatures.DENSE_CAPTIONS,
            VisualFeatures.OBJECTS,
            VisualFeatures.PEOPLE,
            VisualFeatures.READ,
            VisualFeatures.TAGS);

选择分析选项

使用 ImageAnalysisOptions 对象指定 Analyze API 调用的各种选项。

  • 语言:可以指定返回的数据的语言。 语言为可选项,默认值为英语。 有关支持的语言代码的列表以及每种语言支持的视觉功能的列表,请参阅语言支持
  • 性别中立描述文字:如果要提取描述文字或密集描述文字(使用 VisualFeatures.CAPTIONVisualFeatures.DENSE_CAPTIONS),可以请求性别中立描述文字。 性别中立的描述文字为可选项,默认为区分性别的描述文字。 例如,在英语中,当你选择性别中立的描述文字时,“女性”或“男性”等术语将替换为“人员”,而“男孩”或“女孩”则将替换为“儿童”。
  • 裁剪纵横比:纵横比的计算方法是将目标裁剪宽度除以高度。 支持的值为 0.75 到 1.8(含)。 仅当选择 VisualFeatures.SMART_CROPS 作为可视功能列表的一部分时,设置此属性才具有相关性。 如果选择了 VisualFeatures.SMART_CROPS,但没有指定纵横比,则服务将返回一条裁剪建议,其中包含它认为合适的纵横比。 在本例中,纵横比介于 0.5 和 2.0(含)之间。
// Specify analysis options (or set `options` to null for defaults)
ImageAnalysisOptions options = new ImageAnalysisOptions()
    .setLanguage("en")
    .setGenderNeutralCaption(true)
    .setSmartCropsAspectRatios(Arrays.asList(0.9, 1.33, 1.78));

调用 analyzeFromUrl 方法

本部分介绍如何对服务进行分析调用。

ImageAnalysisClient 对象上调用 analyzeFromUrl 方法,如下所示。 这是一种同步调用,直到服务返回结果或发生错误为止。 或者,可转而使用 ImageAnalysisAsyncClient 对象,并调用其 analyzeFromUrl 方法(非阻塞)。

若要从图像缓冲区而不是 URL 进行分析,请转而调用 analyze 方法,并将 imageData 作为第一个参数传入。

try {
    // Analyze all visual features from an image URL. This is a synchronous (blocking) call.
    ImageAnalysisResult result = client.analyzeFromUrl(
        imageUrl,
        visualFeatures,
        options);

    printAnalysisResults(result);

} catch (HttpResponseException e) {
    System.out.println("Exception: " + e.getClass().getSimpleName());
    System.out.println("Status code: " + e.getResponse().getStatusCode());
    System.out.println("Message: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Message: " + e.getMessage());
}

获取服务结果

以下代码演示如何分析 analyzeFromUrl 和 analyze 操作的结果。

// Print all analysis results to the console
public static void printAnalysisResults(ImageAnalysisResult result) {

    System.out.println("Image analysis results:");

    if (result.getCaption() != null) {
        System.out.println(" Caption:");
        System.out.println("   \"" + result.getCaption().getText() + "\", Confidence "
            + String.format("%.4f", result.getCaption().getConfidence()));
    }

    if (result.getDenseCaptions() != null) {
        System.out.println(" Dense Captions:");
        for (DenseCaption denseCaption : result.getDenseCaptions().getValues()) {
            System.out.println("   \"" + denseCaption.getText() + "\", Bounding box "
                + denseCaption.getBoundingBox() + ", Confidence " + String.format("%.4f", denseCaption.getConfidence()));
        }
    }

    if (result.getRead() != null) {
        System.out.println(" Read:");
        for (DetectedTextLine line : result.getRead().getBlocks().get(0).getLines()) {
            System.out.println("   Line: '" + line.getText()
                + "', Bounding polygon " + line.getBoundingPolygon());
            for (DetectedTextWord word : line.getWords()) {
                System.out.println("     Word: '" + word.getText()
                    + "', Bounding polygon " + word.getBoundingPolygon()
                    + ", Confidence " + String.format("%.4f", word.getConfidence()));
            }
        }
    }

    if (result.getTags() != null) {
        System.out.println(" Tags:");
        for (DetectedTag tag : result.getTags().getValues()) {
            System.out.println("   \"" + tag.getName() + "\", Confidence " + String.format("%.4f", tag.getConfidence()));
        }
    }

    if (result.getObjects() != null) {
        System.out.println(" Objects:");
        for (DetectedObject detectedObject : result.getObjects().getValues()) {
            System.out.println("   \"" + detectedObject.getTags().get(0).getName() + "\", Bounding box "
                + detectedObject.getBoundingBox() + ", Confidence " + String.format("%.4f", detectedObject.getTags().get(0).getConfidence()));
        }
    }

    if (result.getPeople() != null) {
        System.out.println(" People:");
        for (DetectedPerson person : result.getPeople().getValues()) {
            System.out.println("   Bounding box "
                + person.getBoundingBox() + ", Confidence " + String.format("%.4f", person.getConfidence()));
        }
    }

    if (result.getSmartCrops() != null) {
        System.out.println(" Crop Suggestions:");
        for (CropRegion cropRegion : result.getSmartCrops().getValues()) {
            System.out.println("   Aspect ratio "
                + cropRegion.getAspectRatio() + ": Bounding box " + cropRegion.getBoundingBox());
        }
    }

    System.out.println(" Image height = " + result.getMetadata().getHeight());
    System.out.println(" Image width = " + result.getMetadata().getWidth());
    System.out.println(" Model version = " + result.getModelVersion());
}

疑难解答

异常

当服务响应非成功 HTTP 状态代码时,analyze 方法会引发 HttpResponseException。 异常的 getResponse().getStatusCode() 保留 HTTP 响应状态代码。 异常的 getMessage() 包含一条详细消息,用于诊断问题:

try {
    ImageAnalysisResult result = client.analyze(...)
} catch (HttpResponseException e) {
    System.out.println("Exception: " + e.getClass().getSimpleName());
    System.out.println("Status code: " + e.getResponse().getStatusCode());
    System.out.println("Message: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Message: " + e.getMessage());
}

例如,当你提供错误的身份验证密钥时:

Exception: ClientAuthenticationException
Status code: 401
Message: Status code 401, "{"error":{"code":"401","message":"Access denied due to invalid subscription key or wrong API endpoint. Make sure to provide a valid key for an active subscription and use a correct regional API endpoint for your resource."}}"

或者,当你以无法识别的格式提供图像时:

Exception: HttpResponseException
Status code: 400
Message: Status code 400, "{"error":{"code":"InvalidRequest","message":"Image format is not valid.","innererror":{"code":"InvalidImageFormat","message":"Input data is not a valid image."}}}"

启用 HTTP 请求/响应日志记录

检查通过网络向图像分析服务发送的 HTTP 请求或收到的响应有助于排除故障。 图像分析客户端库支持用于临时调试的内置控制台记录框架。 它还支持使用 SLF4J 接口进行更高级的日志记录。 有关详细信息,请参阅使用 Azure SDK for Java 中的日志记录

以下各节讨论如何使用内置框架启用控制台日志记录。

通过设置环境变量

可以通过设置以下两个环境变量,为整个应用程序启用 HTTP 请求和响应的控制台日志记录。 此更改会影响支持记录 HTTP 请求和响应的每个 Azure 客户端。

  • 将环境变量 AZURE_LOG_LEVEL 设置为 debug
  • 将环境变量 AZURE_HTTP_LOG_DETAIL_LEVEL 设置为以下值之一:
日志记录级别
none HTTP 请求/响应日志记录已禁用
basic 仅记录 URL、HTTP 方法和完成请求的时间。
headers 记录 BASIC 中的所有内容,加上所有请求和响应头。
body 记录 BASIC 中的所有内容,加上所有请求和响应主体。
body_and_headers 记录 HEADERS 和 BODY 中的所有内容。

通过设置 httpLogOptions

为单个客户端启用 HTTP 请求和响应的控制台日志记录

  • 将环境变量 AZURE_LOG_LEVEL 设置为 debug
  • 在生成 ImageAnalysisClient 时添加对 httpLogOptions 的调用:
ImageAnalysisClient client = new ImageAnalysisClientBuilder()
    .endpoint(endpoint)
    .credential(new KeyCredential(key))
    .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS))
    .buildClient();

枚举 HttpLogDetailLevel 定义支持的日志记录级别。

默认情况下,在日志记录时,会编修某些 HTTP 标头和查询参数值。 可以通过指定记录哪些标头和查询参数是安全的来替代此默认值:

ImageAnalysisClient client = new ImageAnalysisClientBuilder()
    .endpoint(endpoint)
    .credential(new KeyCredential(key))
    .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)
        .addAllowedHeaderName("safe-to-log-header-name")
        .addAllowedQueryParamName("safe-to-log-query-parameter-name"))
    .buildClient();

例如,若要获取 HTTP 请求的完整未编修日志,请应用以下项:

    .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)
        .addAllowedHeaderName("Ocp-Apim-Subscription-Key")
        .addAllowedQueryParamName("features")
        .addAllowedQueryParamName("language")
        .addAllowedQueryParamName("gender-neutral-caption")
        .addAllowedQueryParamName("smartcrops-aspect-ratios")
        .addAllowedQueryParamName("model-version"))

将更多添加到上面,以获取未编修的 HTTP 响应。 共享未编修的日志时,请确保它不包含机密,例如订阅密钥。

先决条件

本指南假定你已成功按照快速入门中提到的步骤进行操作。 这意味着:

  • 你已经创建了计算机视觉资源 并获取了密钥和终结点 URL。
  • 你已安装相应的 SDK 包,并且有一个正在运行的快速入门应用程序。 可以根据此处的代码示例修改此快速入门应用程序。

创建客户端并对其进行身份验证

若要对图像分析服务进行身份验证,需要计算机视觉密钥和终结点 URL。 本指南假定你使用密钥和终结点定义了环境变量 VISION_KEYVISION_ENDPOINT

提示

请不要直接在代码中包含密钥,并且绝不公开发布密钥。 有关 Azure Key Vault 等更多身份验证选项,请参阅 Azure AI 服务安全性一文。

首先创建 ImageAnalysisClient 对象。 例如:

// Load the .env file if it exists
require("dotenv").config();

const endpoint = process.env['VISION_ENDPOINT'] || '<your_endpoint>';
const key = process.env['VISION_KEY'] || '<your_key>';

const credential = new AzureKeyCredential(key);
const client = createClient(endpoint, credential);

选择要分析的图像

可以通过提供可公开访问的图像 URL 或将图像数据读入 SDK 的输入缓冲区来选择映像。 有关支持的图像格式,请参阅图像要求

图像 URL

可使用以下示例图像 URL。

const imageUrl = 'https://learn.microsoft.com/azure/ai-services/computer-vision/media/quickstarts/presentation.png';

图像缓冲区

或者,可以将图像作为数据数组传入。 例如,从要分析的本地图像文件中读取。

const imagePath = '../sample.jpg';
const imageData = fs.readFileSync(imagePath);

选择视觉特征

使用分析 4.0 API 可以访问所有服务的图像分析特征。 基于自己的用例选择要执行的操作。 有关每种特征的说明,请参阅概述。 本部分中的示例添加了所有可用的视觉功能,但实际使用而言,所需的功能很可能没有这么多。

const features = [
  'Caption',
  'DenseCaptions',
  'Objects',
  'People',
  'Read',
  'SmartCrops',
  'Tags'
];

调用具有选项的 Analyze API

以下代码会调用具有你在上面选择的功能和下面定义的其他选项的 Analyze API。 若要从图像缓冲区而不是 URL 进行分析,请将方法调用中的 imageURL 替换为 imageData

const result = await client.path('/imageanalysis:analyze').post({
  body: {
      url: imageUrl
  },
  queryParameters: {
      features: features,
      'language': 'en',
      'gender-neutral-captions': 'true',
      'smartCrops-aspect-ratios': [0.9, 1.33]
  },
  contentType: 'application/json'
});

选择智能裁剪纵横比

纵横比的计算方法是将目标裁剪宽度除以高度。 支持的值为 0.75 到 1.8(含)。 仅当选择 VisualFeatures.SmartCrops 作为可视功能列表的一部分时,设置此属性才具有相关性。 如果选择了 VisualFeatures.SmartCrops,但没有指定纵横比,则服务将返回一条裁剪建议,其中包含它认为合适的纵横比。 在本例中,纵横比介于 0.5 和 2.0(含)之间。

选择性别中立的描述文字

如果要提取描述文字或密集描述文字(使用 VisualFeatures.CaptionVisualFeatures.DenseCaptions),可以请求性别中立描述文字。 性别中立的描述文字为可选项,默认为区分性别的描述文字。 例如,在英语中,当你选择性别中立的描述文字时,“女性”或“男性”等术语将替换为“人员”,而“男孩”或“女孩”则将替换为“儿童”。

指定语言

可以指定返回的数据的语言。 语言为可选项,默认值为英语。 有关支持的语言代码的列表以及每种语言支持的视觉功能的列表,请参阅语言支持

获取服务结果

以下代码演示如何分析各种 analyze 操作的结果。

const iaResult = result.body;

console.log(`Model Version: ${iaResult.modelVersion}`);
console.log(`Image Metadata: ${JSON.stringify(iaResult.metadata)}`);
if (iaResult.captionResult) {
  console.log(`Caption: ${iaResult.captionResult.text} (confidence: ${iaResult.captionResult.confidence})`);
}
if (iaResult.denseCaptionsResult) {
  iaResult.denseCaptionsResult.values.forEach(denseCaption => console.log(`Dense Caption: ${JSON.stringify(denseCaption)}`));
}
if (iaResult.objectsResult) {
  iaResult.objectsResult.values.forEach(object => console.log(`Object: ${JSON.stringify(object)}`));
}
if (iaResult.peopleResult) {
  iaResult.peopleResult.values.forEach(person => console.log(`Person: ${JSON.stringify(person)}`));
}
if (iaResult.readResult) {
  iaResult.readResult.blocks.forEach(block => console.log(`Text Block: ${JSON.stringify(block)}`));
}
if (iaResult.smartCropsResult) {
  iaResult.smartCropsResult.values.forEach(smartCrop => console.log(`Smart Crop: ${JSON.stringify(smartCrop)}`));
}
if (iaResult.tagsResult) {
  iaResult.tagsResult.values.forEach(tag => console.log(`Tag: ${JSON.stringify(tag)}`));
}

疑难解答

日志记录

启用日志记录可能有助于发现有关故障的有用信息。 若要查看 HTTP 请求和响应的日志,请将 AZURE_LOG_LEVEL 环境变量设置为 info。 或者,可以在运行时通过调用 @azure/logger 中的 setLogLevel 来启用日志记录:

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

有关如何启用日志的更详细说明,请查看 @azure/logger 包文档

先决条件

本指南假定你已成功按照快速入门页中提到的步骤进行操作。 这意味着:

  • 你已经创建了计算机视觉资源 并获取了密钥和终结点 URL。
  • 你已成功对服务进行了 curl.exe 调用(或使用了替代工具)。 根据此处的示例修改 curl.exe 调用。

对服务进行身份验证

若要对图像分析服务进行身份验证,需要计算机视觉密钥和终结点 URL。

提示

请不要直接在代码中包含密钥,并且绝不公开发布密钥。 有关 Azure Key Vault 等更多身份验证选项,请参阅 Azure AI 服务安全性一文。

SDK 示例假定你使用密钥和终结点定义了环境变量 VISION_KEYVISION_ENDPOINT

身份验证是通过添加 HTTP 请求头 Ocp-Apim-Subscription-Key 并将其设为你的视觉密钥来完成的。 向 URL <endpoint>/computervision/imageanalysis:analyze?api-version=2024-02-01 进行调用,其中 <endpoint> 是唯一的计算机视觉终结点 URL。 根据分析选项添加查询字符串。

选择要分析的图像

本指南中的代码使用 URL 引用的远程图像。 你可能要自行尝试不同的图像,以了解图像分析功能的完整功能。

分析远程图像时,请通过设置请求正文的格式来指定图像的 URL,如下所示:{"url":"https://learn.microsoft.com/azure/cognitive-services/computer-vision/images/windows-kitchen.jpg"}Content-Type 应为 application/json

若要分析本地图像,请将二进制图像数据放在 HTTP 请求正文中。 Content-Type 应为 application/octet-streammultipart/form-data

选择分析选项

使用标准模型时选择视觉特征

使用分析 4.0 API 可以访问所有服务的图像分析特征。 基于自己的用例选择要执行的操作。 有关每种特征的说明,请参阅概述。 本部分中的示例添加了所有可用的视觉特征,但对于实际使用,所需的特征可能更少。

视觉特征“文字描述”和“密集文字描述”仅在以下 Azure 区域中受支持:美国东部、法国中部、韩国中部、北欧、东南亚、西欧、美国西部。

注意

REST API 使用术语“智能裁剪”和“智能裁剪纵横比”。 SDK 使用术语“裁剪建议”和“裁剪纵横比”。 它们指的是同一种服务操作。 同样,REST API 使用读取一词来检测图像中的文本 (OCR),而 SDK 使用文本一词执行相同的操作。

可以通过设置分析 4.0 API 的 URL 查询参数来指定要使用的特征。 参数可以具有多个值(用逗号分隔)。

URL 参数 说明
features read 读取图像中的可见文本并将其输出为结构化 JSON 数据。
features caption 使用受支持的语言以完整的句子描述图像内容。
features denseCaptions 为最多 10 个突出的图像区域生成详细描述文字。
features smartCrops 查找将图像裁剪为所需纵横比的矩形坐标,同时保留感兴趣的区域。
features objects 检测图像中的各种对象,包括大致位置。 Objects 参数仅以英语提供。
features tags 使用与图像内容相关字词的详细列表来标记图像。
features people 检测图像中显示的人员,包括大致位置。

填充的 URL 可能如下所示:

<endpoint>/computervision/imageanalysis:analyze?api-version=2024-02-01&features=tags,read,caption,denseCaptions,smartCrops,objects,people

使用自定义模型时设置模型名称

还可以使用自定义训练模型执行图像分析。 若要创建和训练模型,请参阅创建自定义图像分析模型。 训练好模型后,现在你只需要模型的名称。 如果使用自定义模型,则无需指定视觉特征。

若要使用自定义模型,请勿使用特征查询参数。 相反,请将 model-name 参数设置为模型的名称,如下所示。 将 MyCustomModelName 替换为你的自定义模型名称。

<endpoint>/computervision/imageanalysis:analyze?api-version=2023-02-01&model-name=MyCustomModelName

指定语言

可以指定返回的数据的语言。 语言为可选项,默认值为英语。 有关支持的语言代码的列表以及每种语言支持的视觉功能的列表,请参阅语言支持

语言选项仅在使用标准模型时适用。

以下 URL 查询参数指定语言。 默认值为 en

URL 参数 说明
language en 英语
language es 西班牙语
language ja 日语
language pt 葡萄牙语
language zh 简体中文

填充的 URL 可能如下所示:

<endpoint>/computervision/imageanalysis:analyze?api-version=2024-02-01&features=caption&language=en

选择性别中立的描述文字

如果要提取描述文字或密集描述文字,可以要求提供性别中立的描述文字。 性别中立的描述文字为可选项,默认为区分性别的描述文字。 例如,在英语中,当你选择性别中立的描述文字时,“女性”或“男性”等术语将替换为“人员”,而“男孩”或“女孩”则将替换为“儿童”。

性别中立的描述文字选项仅在使用标准模型时适用。

添加可选的查询字符串 gender-neutral-caption,其值为 truefalse(默认值)。

填充的 URL 可能如下所示:

<endpoint>/computervision/imageanalysis:analyze?api-version=2024-02-01&features=caption&gender-neutral-caption=true

选择智能裁剪纵横比

纵横比的计算方法是将目标裁剪宽度除以高度。 支持的值为 0.75 到 1.8(含)。 仅当选择 VisualFeatures.SmartCrops 作为可视功能列表的一部分时,设置此属性才具有相关性。 如果选择了 VisualFeatures.SmartCrops,但没有指定纵横比,则服务将返回一条裁剪建议,其中包含它认为合适的纵横比。 在本例中,纵横比介于 0.5 和 2.0(含)之间。

智能裁剪纵横比仅在使用标准模型时适用。

添加可选的查询字符串 smartcrops-aspect-ratios,其中包含由逗号分隔的一个或多个纵横比。

填充的 URL 可能如下所示:

<endpoint>/computervision/imageanalysis:analyze?api-version=2024-02-01&features=smartCrops&smartcrops-aspect-ratios=0.8,1.2

获取服务结果

使用标准模型获取结果

本部分介绍如何使用标准模型对服务进行分析调用并获取结果。

服务返回 200 HTTP 响应,正文包含 JSON 字符串形式的返回数据。 以下文本是一个 JSON 响应示例。

{
    "modelVersion": "string",
    "captionResult": {
      "text": "string",
      "confidence": 0.0
    },
    "denseCaptionsResult": {
      "values": [
        {
          "text": "string",
          "confidence": 0.0,
          "boundingBox": {
            "x": 0,
            "y": 0,
            "w": 0,
            "h": 0
          }
        }
      ]
    },
    "metadata": {
      "width": 0,
      "height": 0
    },
    "tagsResult": {
      "values": [
        {
          "name": "string",
          "confidence": 0.0
        }
      ]
    },
    "objectsResult": {
      "values": [
        {
          "id": "string",
          "boundingBox": {
            "x": 0,
            "y": 0,
            "w": 0,
            "h": 0
          },
          "tags": [
            {
              "name": "string",
              "confidence": 0.0
            }
          ]
        }
      ]
    },
    "readResult": {
      "blocks": [
        {
          "lines": [
            {
              "text": "string",
              "boundingPolygon": [
                {
                  "x": 0,
                  "y": 0
                },
                {
                    "x": 0,
                    "y": 0
                },
                {
                    "x": 0,
                    "y": 0
                },
                {
                    "x": 0,
                    "y": 0
                }
              ],
              "words": [
                {
                  "text": "string",
                  "boundingPolygon": [
                    {
                        "x": 0,
                        "y": 0
                    },
                    {
                        "x": 0,
                        "y": 0
                    },
                    {
                        "x": 0,
                        "y": 0
                    },
                    {
                        "x": 0,
                        "y": 0
                    }
                  ],
                  "confidence": 0.0
                }
              ]
            }
          ]
        }
      ]
    },
    "smartCropsResult": {
      "values": [
        {
          "aspectRatio": 0.0,
          "boundingBox": {
            "x": 0,
            "y": 0,
            "w": 0,
            "h": 0
          }
        }
      ]
    },
    "peopleResult": {
      "values": [
        {
          "boundingBox": {
            "x": 0,
            "y": 0,
            "w": 0,
            "h": 0
          },
          "confidence": 0.0
        }
      ]
    }
  }

错误代码

出现错误时,图像分析服务响应会包含一个 JSON 有效负载,它包含错误代码和错误消息。 它还可能包括其他详细信息,以内部错误代码和消息的形式出现。 例如:

{
    "error":
    {
        "code": "InvalidRequest",
        "message": "Analyze query is invalid.",
        "innererror":
        {
            "code": "NotSupportedVisualFeature",
            "message": "Specified feature type is not valid"
        }
    }
}

下面是常见错误及其原因的列表。 列表项采用以下格式显示:

  • HTTP 响应代码
    • JSON 响应中的错误代码和消息
      • [可选] JSON 响应中的内部错误代码和消息

常见错误表:

  • 400 Bad Request
    • InvalidRequest - Image URL is badly formatted or not accessible。 确保图像 URL 有效且可公开访问。
    • InvalidRequest - The image size is not allowed to be zero or larger than 20971520 bytes。 通过压缩图像和/或调整大小来减小图像的大小,然后重新提交请求。
    • InvalidRequest - The feature 'Caption' is not supported in this region。 此功能仅在特定的 Azure 区域中受支持。 有关受支持的 Azure 区域列表,请参阅快速入门先决条件
    • InvalidRequest - The provided image content type ... is not supported。 请求中的 HTTP 标头 Content-Type 不是允许的类型:
      • 对于图像 URL,Content-Type 应为 application/json
      • 对于二进制图像数据,Content-Type 应为 application/octet-streammultipart/form-data
    • InvalidRequest - Either 'features' or 'model-name' needs to be specified in the query parameter
    • InvalidRequest - Image format is not valid
      • InvalidImageFormat - Image format is not valid。 有关支持的图像格式,请参阅图像要求部分。
    • InvalidRequest - Analyze query is invalid
      • NotSupportedVisualFeature - Specified feature type is not valid。 确保特征查询字符串具有有效的值。
      • NotSupportedLanguage - The input language is not supported。 根据下表,确保语言查询字符串具有对所选视觉特征有效的值。
      • BadArgument - 'smartcrops-aspect-ratios' aspect ratio is not in allowed range [0.75 to 1.8]
  • 401 PermissionDenied
    • 401 - Access denied due to invalid subscription key or wrong API endpoint. Make sure to provide a valid key for an active subscription and use a correct regional API endpoint for your resource
  • 404 Resource Not Found
    • 404 - Resource not found。 服务无法根据 model-name 查询字符串提供 的名称找到自定义模型。

后续步骤