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 raw bytes to Cloud Vision Product Search. The following samples read a local file and query the API by inlining the raw image bytes in the request.

Command-line

To query the product set, make a POST request to the v1p3beta1/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.

POST https://vision.googleapis.com/v1p3beta1/images:annotate
{
  "requests": [
    {
      "image": {
        "source": {
          "imageUri": "IMAGE_URL"
        }
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH"
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/project-id/locations/location-id/productSets/product-set-id",
          "productCategories": [
               "homegoods"
             ],
        "filter": "style = womens"
        }
      }
    }
  ]
}

Python

from google.cloud import vision_v1p3beta1 as 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))

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 {
  ImageAnnotatorClient queryImageClient = ImageAnnotatorClient.create();

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

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

function getSimilarProductsFile(
  projectId,
  location,
  productSetId,
  productCategory,
  filePath,
  filter
) {
  // Imports the Google Cloud client library
  const vision = require('@google-cloud/vision').v1p3beta1;
  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 = 'java-docs-samples-testing';
  // 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,
      },
    },
  };
  imageAnnotatorClient
    .batchAnnotateImages({requests: [request]})
    .then(responses => {
      const response = responses[0];

      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);
      });
    })
    .catch(err => {
      console.error(err);
    });
}

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 v1p3beta1/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.

POST https://vision.googleapis.com/v1p3beta1/images:annotate
{
  "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"
        }
      }
    }
  ]
}

Python

from google.cloud import vision_v1p3beta1 as 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))

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 {
  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

function getSimilarProductsGcs(
  projectId,
  location,
  productSetId,
  productCategory,
  filePath,
  filter
) {
  // Imports the Google Cloud client library
  const vision = require('@google-cloud/vision').v1p3beta1;
  // 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);
  imageAnnotatorClient
    .batchAnnotateImages({requests: [request]})
    .then(responses => {
      const response = responses[0];
      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);
      });
    })
    .catch(err => {
      console.error(err);
    });
}

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": "PE602571",
            "productCategory": "homegoods"
          },
          "score": 1
        },
        {
          "product": {
            "name": "projects/visual-search-176510/locations/us-west1/products/PE602572",
            "displayName": "PE602572",
            "productCategory": "homegoods"
          },
          "score": 0.99392104
        }
      ]
    }
  }]
}

A new field, score, is returned. 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
Need help? Visit our support page.