Searching for Products

Once you have created your product set and the product set has been indexed, you can query the product set using the Cloud Vision API.

Request

You can find similar products to a given image by passing the image's Google Cloud Storage URI, web URL, or base64 encoded string to Cloud Vision API Product Search.

Search using a local image

The following samples read a local file and query the API by inlining the raw image bytes (base64 encoded image) in the request.

Command-line

To query the product set, make a POST request to the v1/images:annotate endpoint, specifying the PRODUCT_SEARCH feature and passing the product set's id in the imageContext field. You must use authentication for the same project as the product set being queried. For a full list of fields, refer to the ProductSearchParams reference.
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
https://vision.googleapis.com/v1/images:annotate -d '{
  "requests": [
    {
      "image": {
        "content": BASE64_ENCODED_IMAGE
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH"
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/project-id/locations/location-id/productSets/product-set-id",
          "productCategories": [
               "homegoods"
             ],
        "filter": "style = womens"
        }
      }
    }
  ]
}

Java

/**
 * Search similar products to image in local file.
 *
 * @param projectId - Id of the project.
 * @param computeRegion - Region name.
 * @param productSetId - Id of the product set.
 * @param productCategory - Category of the product.
 * @param filePath - Local file path of the image to be searched
 * @param filter - Condition to be applied on the labels. Example for filter: (color = red OR
 *     color = blue) AND style = kids It will search on all products with the following labels:
 *     color:red AND style:kids color:blue AND style:kids
 * @throws IOException - on I/O errors.
 */
public static void getSimilarProductsFile(
    String projectId,
    String computeRegion,
    String productSetId,
    String productCategory,
    String filePath,
    String filter)
    throws IOException {
  try (ImageAnnotatorClient queryImageClient = ImageAnnotatorClient.create()) {

    // Get the full path of the product set.
    String productSetPath =
        ProductSearchClient.formatProductSetName(projectId, computeRegion, productSetId);

    // Read the image as a stream of bytes.
    File imgPath = new File(filePath);
    byte[] content = Files.readAllBytes(imgPath.toPath());

    // Create annotate image request along with product search feature.
    Feature featuresElement = Feature.newBuilder().setType(Type.PRODUCT_SEARCH).build();
    // The input image can be a HTTPS link or Raw image bytes.
    // Example:
    // To use HTTP link replace with below code
    //  ImageSource source = ImageSource.newBuilder().setImageUri(imageUri).build();
    //  Image image = Image.newBuilder().setSource(source).build();
    Image image = Image.newBuilder().setContent(ByteString.copyFrom(content)).build();
    ImageContext imageContext =
        ImageContext.newBuilder()
            .setProductSearchParams(
                ProductSearchParams.newBuilder()
                    .setProductSet(productSetPath)
                    .addProductCategories(productCategory)
                    .setFilter(filter))
            .build();

    AnnotateImageRequest annotateImageRequest =
        AnnotateImageRequest.newBuilder()
            .addFeatures(featuresElement)
            .setImage(image)
            .setImageContext(imageContext)
            .build();
    List<AnnotateImageRequest> requests = Arrays.asList(annotateImageRequest);

    // Search products similar to the image.
    BatchAnnotateImagesResponse response = queryImageClient.batchAnnotateImages(requests);

    List<Result> similarProducts =
        response.getResponses(0).getProductSearchResults().getResultsList();
    System.out.println("Similar Products: ");
    for (Result product : similarProducts) {
      System.out.println(String.format("\nProduct name: %s", product.getProduct().getName()));
      System.out.println(
          String.format("Product display name: %s", product.getProduct().getDisplayName()));
      System.out.println(
          String.format("Product description: %s", product.getProduct().getDescription()));
      System.out.println(String.format("Score(Confidence): %s", product.getScore()));
      System.out.println(String.format("Image name: %s", product.getImage()));
    }
  }
}

Node.js

async function getSimilarProductsFile(
  projectId,
  location,
  productSetId,
  productCategory,
  filePath,
  filter
) {
  // Imports the Google Cloud client library
  const vision = require('@google-cloud/vision');
  const fs = require('fs');
  // Creates a client
  const productSearchClient = new vision.ProductSearchClient();
  const imageAnnotatorClient = new vision.ImageAnnotatorClient();

  /**
   * TODO(developer): Uncomment the following line before running the sample.
   */
  // const projectId = 'nodejs-docs-samples';
  // const location = 'us-west1';
  // const productSetId = 'indexed_product_set_id_for_testing';
  // const productCategory = 'apparel';
  // const filePath = './resources/shoes_1.jpg';
  // const filter = '';
  const productSetPath = productSearchClient.productSetPath(
    projectId,
    location,
    productSetId
  );
  const content = fs.readFileSync(filePath, 'base64');
  const request = {
    // The input image can be a GCS link or HTTPS link or Raw image bytes.
    // Example:
    // To use GCS link replace with below code
    // image: {source: {gcsImageUri: filePath}}
    // To use HTTP link replace with below code
    // image: {source: {imageUri: filePath}}
    image: {content: content},
    features: [{type: 'PRODUCT_SEARCH'}],
    imageContext: {
      productSearchParams: {
        productSet: productSetPath,
        productCategories: [productCategory],
        filter: filter,
      },
    },
  };
  const [response] = await imageAnnotatorClient.batchAnnotateImages({
    requests: [request],
  });
  console.log('Search Image:', filePath);
  const results = response['responses'][0]['productSearchResults']['results'];
  console.log('\nSimilar product information:');
  results.forEach(result => {
    console.log('Product id:', result['product'].name.split('/').pop(-1));
    console.log('Product display name:', result['product'].displayName);
    console.log('Product description:', result['product'].description);
    console.log('Product category:', result['product'].productCategory);
  });
}

PHP

namespace Google\Cloud\Samples\Vision;

use Google\Cloud\Vision\V1\ImageAnnotatorClient;
use Google\Cloud\Vision\V1\ProductSearchClient;
use Google\Cloud\Vision\V1\ProductSearchParams;

/**
 * Search similar products to image
 *
 * @param string $projectId Your Google Cloud project ID
 * @param string $location Google Cloud compute region name
 * @param string $productSetId ID of the product set
 * @param string $productCategory Category of the product
 * @param string $filePath Local file path of the image to be searched
 * @param string $filter Condition to be applied on the labels
 */
function product_search_similar($projectId, $location, $productSetId, $productCategory, $filePath, $filter)
{
    $imageAnnotatorClient = new ImageAnnotatorClient();
    $productSearchClient = new ProductSearchClient();

    # read the image
    $image = file_get_contents($filePath);

    # get the name of the product set
    $productSetPath = $productSearchClient->productSetName($projectId, $location, $productSetId);

    # product search specific parameters
    $productSearchParams = (new ProductSearchParams())
        ->setProductSet($productSetPath)
        ->setProductCategories([$productCategory])
        ->setFilter($filter);

    # search products similar to the image
    $response = $imageAnnotatorClient->productSearch($image, $productSearchParams);

    if ($productSearchResults = $response->getProductSearchResults()) {
        $indexTime = $productSearchResults->getIndexTime();
        printf('Product set index time: %d seconds %d nanos' . PHP_EOL, $indexTime->getSeconds(), $indexTime->getNanos());

        $results = $productSearchResults->getResults();
        print('Search results: ' . PHP_EOL);
        foreach ($results as $result) {
            printf('Score (confidence): %d' . PHP_EOL, $result->getScore());

            # display the product information.
            $product = $result->getProduct();
            $productName = $product->getName();
            $productNameArray = explode('/', $productName);

            printf('Product name: %s' . PHP_EOL, $productName);
            printf('Product id: %s' . PHP_EOL, end($productNameArray));
            printf('Product display name: %s' . PHP_EOL, $product->getDisplayName());
            printf('Product description: %s' . PHP_EOL, $product->getDescription());
            printf('Product category: %s' . PHP_EOL, $product->getProductCategory());
            print('Product labels: ' . PHP_EOL);
            foreach ($product->getProductLabels() as $label) {
                printf('%s : %s' . PHP_EOL, $label->getKey(), $label->getValue());
            }
        }
    } else {
        print($response->getError()->getMessage());
    }

    $imageAnnotatorClient->close();
    $productSearchClient->close();
}

Python

from google.cloud import vision

def get_similar_products_file(
        project_id, location, product_set_id, product_category,
        file_path, filter):
    """Search similar products to image.
    Args:
        project_id: Id of the project.
        location: A compute region name.
        product_set_id: Id of the product set.
        product_category: Category of the product.
        file_path: Local file path of the image to be searched.
        filter: Condition to be applied on the labels.
        Example for filter: (color = red OR color = blue) AND style = kids
        It will search on all products with the following labels:
        color:red AND style:kids
        color:blue AND style:kids
    """
    # product_search_client is needed only for its helper methods.
    product_search_client = vision.ProductSearchClient()
    image_annotator_client = vision.ImageAnnotatorClient()

    # Read the image as a stream of bytes.
    with open(file_path, 'rb') as image_file:
        content = image_file.read()

    # Create annotate image request along with product search feature.
    image = vision.types.Image(content=content)

    # product search specific parameters
    product_set_path = product_search_client.product_set_path(
        project=project_id, location=location,
        product_set=product_set_id)
    product_search_params = vision.types.ProductSearchParams(
        product_set=product_set_path,
        product_categories=[product_category],
        filter=filter)
    image_context = vision.types.ImageContext(
        product_search_params=product_search_params)

    # Search products similar to the image.
    response = image_annotator_client.product_search(
        image, image_context=image_context)

    index_time = response.product_search_results.index_time
    print('Product set index time:')
    print('  seconds: {}'.format(index_time.seconds))
    print('  nanos: {}\n'.format(index_time.nanos))

    results = response.product_search_results.results

    print('Search results:')
    for result in results:
        product = result.product

        print('Score(Confidence): {}'.format(result.score))
        print('Image name: {}'.format(result.image))

        print('Product name: {}'.format(product.name))
        print('Product display name: {}'.format(
            product.display_name))
        print('Product description: {}\n'.format(product.description))
        print('Product labels: {}\n'.format(product.product_labels))

Search using an image URI

You also have the option of finding similar products to a given image by specifying the Google Cloud Storage URI to the image.

Command-line

To query the product set, make a POST request to the v1/images:annotate endpoint, specifying the PRODUCT_SEARCH feature and passing the product set's id in the imageContext field. You must use authentication for the same project as the product set being queried.

For a full list of fields, refer to the ProductSearchParams reference.

curl -X POST \ 
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ 
-H "Content-Type: application/json" \ 
https://vision.googleapis.com/v1/images:annotate -d '{
  "requests": [
    {
      "image": {
        "source": {
          "gcsImageUri": "gs://YOUR_BUCKET_NAME/YOUR_FILE_NAME"
        }
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH"
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/project-id/locations/location-id/productSets/product-set-id",
          "productCategories": [
               "homegoods"
             ],
        "filter": "style = womens"
        }
      }
    }
  ]
}

Java

/**
 * Search similar products to image in Google Cloud Storage.
 *
 * @param projectId - Id of the project.
 * @param computeRegion - Region name.
 * @param productSetId - Id of the product set.
 * @param productCategory - Category of the product.
 * @param gcsUri - GCS file path of the image to be searched
 * @param filter - Condition to be applied on the labels. Example for filter: (color = red OR
 *     color = blue) AND style = kids It will search on all products with the following labels:
 *     color:red AND style:kids color:blue AND style:kids
 * @throws Exception - on errors.
 */
public static void getSimilarProductsGcs(
    String projectId,
    String computeRegion,
    String productSetId,
    String productCategory,
    String gcsUri,
    String filter)
    throws Exception {
  try (ImageAnnotatorClient queryImageClient = ImageAnnotatorClient.create()) {

    // Get the full path of the product set.
    String productSetPath = ProductSetName.of(projectId, computeRegion, productSetId).toString();

    // Get the image from Google Cloud Storage
    ImageSource source = ImageSource.newBuilder().setGcsImageUri(gcsUri).build();

    // Create annotate image request along with product search feature.
    Feature featuresElement = Feature.newBuilder().setType(Type.PRODUCT_SEARCH).build();
    Image image = Image.newBuilder().setSource(source).build();
    ImageContext imageContext =
        ImageContext.newBuilder()
            .setProductSearchParams(
                ProductSearchParams.newBuilder()
                    .setProductSet(productSetPath)
                    .addProductCategories(productCategory)
                    .setFilter(filter))
            .build();

    AnnotateImageRequest annotateImageRequest =
        AnnotateImageRequest.newBuilder()
            .addFeatures(featuresElement)
            .setImage(image)
            .setImageContext(imageContext)
            .build();
    List<AnnotateImageRequest> requests = Arrays.asList(annotateImageRequest);

    // Search products similar to the image.
    BatchAnnotateImagesResponse response = queryImageClient.batchAnnotateImages(requests);

    List<Result> similarProducts =
        response.getResponses(0).getProductSearchResults().getResultsList();
    System.out.println("Similar Products: ");
    for (Result product : similarProducts) {
      System.out.println(String.format("\nProduct name: %s", product.getProduct().getName()));
      System.out.println(
          String.format("Product display name: %s", product.getProduct().getDisplayName()));
      System.out.println(
          String.format("Product description: %s", product.getProduct().getDescription()));
      System.out.println(String.format("Score(Confidence): %s", product.getScore()));
      System.out.println(String.format("Image name: %s", product.getImage()));
    }
  }
}

Node.js

async function getSimilarProductsGcs(
  projectId,
  location,
  productSetId,
  productCategory,
  filePath,
  filter
) {
  // Imports the Google Cloud client library
  const vision = require('@google-cloud/vision');
  // Creates a client
  const productSearchClient = new vision.ProductSearchClient();
  const imageAnnotatorClient = new vision.ImageAnnotatorClient();

  /**
   * TODO(developer): Uncomment the following line before running the sample.
   */
  // const projectId = 'Your Google Cloud project Id';
  // const location = 'A compute region name';
  // const productSetId = 'Id of the product set';
  // const productCategory = 'Category of the product';
  // const filePath = 'Local file path of the image to be searched';
  // const filter = 'Condition to be applied on the labels';
  const productSetPath = productSearchClient.productSetPath(
    projectId,
    location,
    productSetId
  );

  const request = {
    // The input image can be a GCS link or HTTPS link or Raw image bytes.
    // Example:
    // To use GCS link replace with below code
    // image: {source: {gcsImageUri: filePath}}
    // To use HTTP link replace with below code
    // image: {source: {imageUri: filePath}}
    image: {source: {gcsImageUri: filePath}},
    features: [{type: 'PRODUCT_SEARCH'}],
    imageContext: {
      productSearchParams: {
        productSet: productSetPath,
        productCategories: [productCategory],
        filter: filter,
      },
    },
  };
  console.log(request.image);

  const [response] = await imageAnnotatorClient.batchAnnotateImages({
    requests: [request],
  });
  console.log('Search Image:', filePath);
  console.log('\nSimilar product information:');

  const results = response['responses'][0]['productSearchResults']['results'];
  results.forEach(result => {
    console.log('Product id:', result['product'].name.split('/').pop(-1));
    console.log('Product display name:', result['product'].displayName);
    console.log('Product description:', result['product'].description);
    console.log('Product category:', result['product'].productCategory);
  });
}

PHP

namespace Google\Cloud\Samples\Vision;

use Google\Cloud\Vision\V1\ImageAnnotatorClient;
use Google\Cloud\Vision\V1\ProductSearchClient;
use Google\Cloud\Vision\V1\ProductSearchParams;

/**
 * Search similar products to image
 *
 * @param string $projectId Your Google Cloud project ID
 * @param string $location Google Cloud compute region name
 * @param string $productSetId ID of the product set
 * @param string $productCategory Category of the product
 * @param string $gcs Google Cloud Storage path of the image to be searched
 * @param string $filter Condition to be applied on the labels
 */
function product_search_similar_gcs($projectId, $location, $productSetId, $productCategory, $gcsUri, $filter)
{
    $imageAnnotatorClient = new ImageAnnotatorClient();
    $productSearchClient = new ProductSearchClient();

    # get the name of the product set
    $productSetPath = $productSearchClient->productSetName($projectId, $location, $productSetId);

    # product search specific parameters
    $productSearchParams = (new ProductSearchParams())
        ->setProductSet($productSetPath)
        ->setProductCategories([$productCategory])
        ->setFilter($filter);

    # search products similar to the image
    $response = $imageAnnotatorClient->productSearch($gcsUri, $productSearchParams);

    if ($productSearchResults = $response->getProductSearchResults()) {
        $indexTime = $productSearchResults->getIndexTime();
        printf('Product set index time: %d seconds %d nanos' . PHP_EOL, $indexTime->getSeconds(), $indexTime->getNanos());

        $results = $productSearchResults->getResults();
        print('Search results: ' . PHP_EOL);
        foreach ($results as $result) {
            printf('Score (confidence): %d' . PHP_EOL, $result->getScore());

            # display the product information.
            $product = $result->getProduct();
            $productName = $product->getName();
            $productNameArray = explode('/', $productName);

            printf('Product name: %s' . PHP_EOL, $productName);
            printf('Product id: %s' . PHP_EOL, end($productNameArray));
            printf('Product display name: %s' . PHP_EOL, $product->getDisplayName());
            printf('Product description: %s' . PHP_EOL, $product->getDescription());
            printf('Product category: %s' . PHP_EOL, $product->getProductCategory());
            print('Product labels: ' . PHP_EOL);
            foreach ($product->getProductLabels() as $label) {
                printf('%s : %s' . PHP_EOL, $label->getKey(), $label->getValue());
            }
        }
    } else {
        print($response->getError()->getMessage());
    }

    $imageAnnotatorClient->close();
    $productSearchClient->close();
}

Python

from google.cloud import vision

def get_similar_products_uri(
        project_id, location, product_set_id, product_category,
        image_uri, filter):
    """Search similar products to image.
    Args:
        project_id: Id of the project.
        location: A compute region name.
        product_set_id: Id of the product set.
        product_category: Category of the product.
        file_path: Local file path of the image to be searched.
        filter: Condition to be applied on the labels.
        Example for filter: (color = red OR color = blue) AND style = kids
        It will search on all products with the following labels:
        color:red AND style:kids
        color:blue AND style:kids
    """
    # product_search_client is needed only for its helper methods.
    product_search_client = vision.ProductSearchClient()
    image_annotator_client = vision.ImageAnnotatorClient()

    # Create annotate image request along with product search feature.
    image_source = vision.types.ImageSource(image_uri=image_uri)
    image = vision.types.Image(source=image_source)

    # product search specific parameters
    product_set_path = product_search_client.product_set_path(
        project=project_id, location=location,
        product_set=product_set_id)
    product_search_params = vision.types.ProductSearchParams(
        product_set=product_set_path,
        product_categories=[product_category],
        filter=filter)
    image_context = vision.types.ImageContext(
        product_search_params=product_search_params)

    # Search products similar to the image.
    response = image_annotator_client.product_search(
        image, image_context=image_context)

    index_time = response.product_search_results.index_time
    print('Product set index time:')
    print('  seconds: {}'.format(index_time.seconds))
    print('  nanos: {}\n'.format(index_time.nanos))

    results = response.product_search_results.results

    print('Search results:')
    for result in results:
        product = result.product

        print('Score(Confidence): {}'.format(result.score))
        print('Image name: {}'.format(result.image))

        print('Product name: {}'.format(product.name))
        print('Product display name: {}'.format(
            product.display_name))
        print('Product description: {}\n'.format(product.description))
        print('Product labels: {}\n'.format(product.product_labels))

Refer to the Usage Limits for maximum request size and quota information.

Response

A successful request returns the following:

{
  "responses": [{
    "productSearchResults": {
      "indexTime": "2018-04-20T00:09:51.124651070Z",
      "results": [{
          "product": {
            "name": "projects/visual-search-176510/locations/us-west1/products/PE602571",
            "displayName": "sample-product-1234",
            "productCategory": "homegoods"
          },
          "score": 1
        },
        {
          "product": {
            "name": "projects/visual-search-176510/locations/us-west1/products/PE602572",
            "displayName": "sample-product-5678",
            "productCategory": "homegoods"
          },
          "score": 0.99392104
        }
      ]
    }
  }]
}

A field score is returned as well. This field indicates the confidence at which the service feels the product matches the supplied image, on a scale of 0 (no confidence) to 1 (full confidence).

The indexTime field shows which version of the index is being searched. Image changes made after this time are not reflected in the results.

Was this page helpful? Let us know how we did:

Send feedback about...

Cloud Vision API Product Search
Need help? Visit our support page.