diff --git a/vision/snippets/src/main/java/com/example/vision/ImportProductSets.java b/vision/snippets/src/main/java/com/example/vision/ImportProductSets.java index 6071e33d0ed..ae8f08b2c9c 100644 --- a/vision/snippets/src/main/java/com/example/vision/ImportProductSets.java +++ b/vision/snippets/src/main/java/com/example/vision/ImportProductSets.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/main/java/com/example/vision/ProductInProductSetManagement.java b/vision/snippets/src/main/java/com/example/vision/ProductInProductSetManagement.java index 36eb1779a9a..06f686ec998 100644 --- a/vision/snippets/src/main/java/com/example/vision/ProductInProductSetManagement.java +++ b/vision/snippets/src/main/java/com/example/vision/ProductInProductSetManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/main/java/com/example/vision/ProductManagement.java b/vision/snippets/src/main/java/com/example/vision/ProductManagement.java index f0a22f106e8..4f5fc7dbb07 100644 --- a/vision/snippets/src/main/java/com/example/vision/ProductManagement.java +++ b/vision/snippets/src/main/java/com/example/vision/ProductManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/main/java/com/example/vision/ProductSearch.java b/vision/snippets/src/main/java/com/example/vision/ProductSearch.java index d36fa6e24c4..2e18e806226 100644 --- a/vision/snippets/src/main/java/com/example/vision/ProductSearch.java +++ b/vision/snippets/src/main/java/com/example/vision/ProductSearch.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.google.cloud.vision.v1p3beta1.Image; import com.google.cloud.vision.v1p3beta1.ImageAnnotatorClient; import com.google.cloud.vision.v1p3beta1.ImageContext; +import com.google.cloud.vision.v1p3beta1.ImageSource; import com.google.cloud.vision.v1p3beta1.ProductSearchParams; import com.google.cloud.vision.v1p3beta1.ProductSearchResults.Result; import com.google.cloud.vision.v1p3beta1.ProductSetName; @@ -54,7 +55,7 @@ public class ProductSearch { // [START vision_product_search_get_similar_products] /** - * Search similar products to image. + * Search similar products to image in local file. * * @param projectId - Id of the project. * @param computeRegion - Region name. @@ -66,7 +67,7 @@ public class ProductSearch { * color:red AND style:kids color:blue AND style:kids * @throws IOException - on I/O errors. */ - public static void getSimilarProducts( + public static void getSimilarProductsFile( String projectId, String computeRegion, String productSetId, @@ -85,11 +86,8 @@ public static void getSimilarProducts( // Create annotate image request along with product search feature. Feature featuresElement = Feature.newBuilder().setType(Type.PRODUCT_SEARCH).build(); - // The input image can be a GCS link or HTTPS link or Raw image bytes. + // The input image can be a HTTPS link or Raw image bytes. // Example: - // To use GCS link replace with below code - // ImageSource source = ImageSource.newBuilder().setGcsImageUri(gcsUri).build(); - // Image image = Image.newBuilder().setSource(source).build(); // To use HTTP link replace with below code // ImageSource source = ImageSource.newBuilder().setImageUri(imageUri).build(); // Image image = Image.newBuilder().setSource(source).build(); @@ -130,6 +128,73 @@ public static void getSimilarProducts( } // [END vision_product_search_get_similar_products] + // [START vision_product_search_get_similar_products_gcs] + /** + * 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 requests = Arrays.asList(annotateImageRequest); + + // Search products similar to the image. + BatchAnnotateImagesResponse response = queryImageClient.batchAnnotateImages(requests); + + List 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())); + } + } + // [END vision_product_search_get_similar_products_gcs] + public static void main(String[] args) throws Exception { ProductSearch productSearch = new ProductSearch(); productSearch.argsHelper(args, System.out); @@ -139,11 +204,17 @@ public static void argsHelper(String[] args, PrintStream out) throws Exception { ArgumentParser parser = ArgumentParsers.newFor("Product Search").build(); Subparsers subparsers = parser.addSubparsers().dest("command"); - Subparser getSimilarProductsParser = subparsers.addParser("get_similar_products"); - getSimilarProductsParser.addArgument("productSetId"); - getSimilarProductsParser.addArgument("productCategory"); - getSimilarProductsParser.addArgument("filePath"); - getSimilarProductsParser.addArgument("filter").nargs("?").setDefault(""); + Subparser getSimilarProductsFileParser = subparsers.addParser("get_similar_products_file"); + getSimilarProductsFileParser.addArgument("productSetId"); + getSimilarProductsFileParser.addArgument("productCategory"); + getSimilarProductsFileParser.addArgument("filePath"); + getSimilarProductsFileParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser getSimilarProductsGcsParser = subparsers.addParser("get_similar_products_gcs"); + getSimilarProductsGcsParser.addArgument("productSetId"); + getSimilarProductsGcsParser.addArgument("productCategory"); + getSimilarProductsGcsParser.addArgument("gcsUri"); + getSimilarProductsGcsParser.addArgument("filter").nargs("?").setDefault(""); String projectId = System.getenv("PROJECT_ID"); String computeRegion = System.getenv("REGION_NAME"); @@ -151,14 +222,22 @@ public static void argsHelper(String[] args, PrintStream out) throws Exception { Namespace ns = null; try { ns = parser.parseArgs(args); - if (ns.get("command").equals("get_similar_products")) { - getSimilarProducts( + if (ns.get("command").equals("get_similar_products_file")) { + getSimilarProductsFile( projectId, computeRegion, ns.getString("productSetId"), ns.getString("productCategory"), ns.getString("filePath"), ns.getString("filter")); + } else if (ns.get("command").equals("get_similar_products_gcs")) { + getSimilarProductsGcs( + projectId, + computeRegion, + ns.getString("productSetId"), + ns.getString("productCategory"), + ns.getString("gcsUri"), + ns.getString("filter")); } } catch (ArgumentParserException e) { diff --git a/vision/snippets/src/main/java/com/example/vision/ReferenceImageManagement.java b/vision/snippets/src/main/java/com/example/vision/ReferenceImageManagement.java index 7618b3d796c..c9413259d5b 100644 --- a/vision/snippets/src/main/java/com/example/vision/ReferenceImageManagement.java +++ b/vision/snippets/src/main/java/com/example/vision/ReferenceImageManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/test/java/com/example/vision/ImportProductSetsIT.java b/vision/snippets/src/test/java/com/example/vision/ImportProductSetsIT.java index 92377727211..a398dfd0037 100644 --- a/vision/snippets/src/test/java/com/example/vision/ImportProductSetsIT.java +++ b/vision/snippets/src/test/java/com/example/vision/ImportProductSetsIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/test/java/com/example/vision/ProductInProductSetManagementIT.java b/vision/snippets/src/test/java/com/example/vision/ProductInProductSetManagementIT.java index 0687d13e494..67bc1713148 100644 --- a/vision/snippets/src/test/java/com/example/vision/ProductInProductSetManagementIT.java +++ b/vision/snippets/src/test/java/com/example/vision/ProductInProductSetManagementIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/test/java/com/example/vision/ProductManagementIT.java b/vision/snippets/src/test/java/com/example/vision/ProductManagementIT.java index 4a20a0d05b5..27db617513a 100644 --- a/vision/snippets/src/test/java/com/example/vision/ProductManagementIT.java +++ b/vision/snippets/src/test/java/com/example/vision/ProductManagementIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vision/snippets/src/test/java/com/example/vision/ProductSearchIT.java b/vision/snippets/src/test/java/com/example/vision/ProductSearchIT.java new file mode 100644 index 00000000000..812ab556c24 --- /dev/null +++ b/vision/snippets/src/test/java/com/example/vision/ProductSearchIT.java @@ -0,0 +1,116 @@ +/* + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.vision; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link ProductSearch}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class ProductSearchIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String COMPUTE_REGION = "us-west1"; + private static final String GCS_URI = + "gs://java-docs-samples-testing/product-search/indexed_product_sets.csv"; + private static final String PRODUCT_SET_ID = "indexed_product_set_id_for_testing"; + private static final String PRODUCT_CATEGORY = "apparel"; + private static final String PRODUCT_ID_1 = "indexed_product_id_for_testing_1"; + private static final String PRODUCT_ID_2 = "indexed_product_id_for_testing_2"; + private static final String IMAGE_URI_1 = + "gs://java-docs-samples-testing/product-search/shoes_1.jpg"; + private static final String FILE_PATH_1 = "./resources/shoes_1.jpg"; + private static final String FILTER = "style=womens"; + private static final String BUCKET = "java-docs-samples-testing"; + private ByteArrayOutputStream bout; + private PrintStream out; + + @Before + public void setUp() throws Exception { + + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + ImportProductSets.importProductSets(PROJECT_ID, COMPUTE_REGION, GCS_URI); + bout.reset(); + } + + @After + public void tearDown() throws Exception { + ProductManagement.deleteProduct(PROJECT_ID,COMPUTE_REGION,PRODUCT_ID_1); + ProductManagement.deleteProduct(PROJECT_ID,COMPUTE_REGION,PRODUCT_ID_2); + ProductSetManagement.deleteProductSet(PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID); + System.setOut(null); + } + + @Test + public void testGetSimilarProductsFile() throws Exception { + // Act + ProductSearch.getSimilarProductsFile( + PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, FILE_PATH_1, ""); + + // Assert + String got = bout.toString(); + assertThat(got).contains(PRODUCT_ID_1); + assertThat(got).contains(PRODUCT_ID_2); + } + + @Test + public void testGetSimilarProductsGcs() throws Exception { + // Act + ProductSearch.getSimilarProductsGcs( + PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, IMAGE_URI_1, ""); + + // Assert + String got = bout.toString(); + assertThat(got).contains(PRODUCT_ID_1); + assertThat(got).contains(PRODUCT_ID_2); + } + + @Test + public void testGetSimilarProductsFileWithFilter() throws Exception { + // Act + ProductSearch.getSimilarProductsFile( + PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, FILE_PATH_1, FILTER); + + // Assert + String got = bout.toString(); + assertThat(got).contains(PRODUCT_ID_1); + assertThat(got).doesNotContain(PRODUCT_ID_2); + } + + @Test + public void testGetSimilarProductsGcsWithFilter() throws Exception { + // Act + ProductSearch.getSimilarProductsGcs( + PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, IMAGE_URI_1, FILTER); + + // Assert + String got = bout.toString(); + assertThat(got).contains(PRODUCT_ID_1); + assertThat(got).doesNotContain(PRODUCT_ID_2); + } +} diff --git a/vision/snippets/src/test/java/com/example/vision/ProductSetManagementIT.java b/vision/snippets/src/test/java/com/example/vision/ProductSetManagementIT.java index 424d6e21be7..9d92d606bf2 100644 --- a/vision/snippets/src/test/java/com/example/vision/ProductSetManagementIT.java +++ b/vision/snippets/src/test/java/com/example/vision/ProductSetManagementIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.