From 5a6a25fdd6d4ba04ace10e6c7ad98844e4916a88 Mon Sep 17 00:00:00 2001 From: Gus Class Date: Mon, 6 Mar 2017 15:06:09 -0800 Subject: [PATCH] Updates vision to the latest library (#548) --- vision/cloud-client/pom.xml | 2 +- .../main/java/com/example/vision/Detect.java | 502 +++++++++++++++--- .../java/com/example/vision/DetectIT.java | 107 +++- 3 files changed, 509 insertions(+), 102 deletions(-) diff --git a/vision/cloud-client/pom.xml b/vision/cloud-client/pom.xml index 13f0cb911c7..3774856c3dc 100644 --- a/vision/cloud-client/pom.xml +++ b/vision/cloud-client/pom.xml @@ -38,7 +38,7 @@ com.google.cloud google-cloud-vision - 0.8.1-alpha + 0.9.4-beta diff --git a/vision/cloud-client/src/main/java/com/example/vision/Detect.java b/vision/cloud-client/src/main/java/com/example/vision/Detect.java index 4daab79314e..c57e0932393 100644 --- a/vision/cloud-client/src/main/java/com/example/vision/Detect.java +++ b/vision/cloud-client/src/main/java/com/example/vision/Detect.java @@ -1,28 +1,27 @@ /** * Copyright 2017, Google, Inc. * - * 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 + *

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

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

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 com.google.cloud.vision.spi.v1.ImageAnnotatorClient; import com.google.cloud.vision.spi.v1.ImageAnnotatorSettings; import com.google.cloud.vision.v1.AnnotateImageRequest; import com.google.cloud.vision.v1.AnnotateImageResponse; import com.google.cloud.vision.v1.BatchAnnotateImagesResponse; +import com.google.cloud.vision.v1.Block; import com.google.cloud.vision.v1.ColorInfo; +import com.google.cloud.vision.v1.CropHint; +import com.google.cloud.vision.v1.CropHintsAnnotation; import com.google.cloud.vision.v1.DominantColorsAnnotation; import com.google.cloud.vision.v1.EntityAnnotation; import com.google.cloud.vision.v1.FaceAnnotation; @@ -31,9 +30,17 @@ import com.google.cloud.vision.v1.Image; import com.google.cloud.vision.v1.ImageSource; import com.google.cloud.vision.v1.LocationInfo; +import com.google.cloud.vision.v1.Page; +import com.google.cloud.vision.v1.Paragraph; import com.google.cloud.vision.v1.SafeSearchAnnotation; +import com.google.cloud.vision.v1.Symbol; +import com.google.cloud.vision.v1.TextAnnotation; +import com.google.cloud.vision.v1.WebDetection; +import com.google.cloud.vision.v1.WebDetection.WebEntity; +import com.google.cloud.vision.v1.WebDetection.WebImage; +import com.google.cloud.vision.v1.WebDetection.WebPage; +import com.google.cloud.vision.v1.Word; import com.google.protobuf.ByteString; - import org.joda.time.Duration; import java.io.FileInputStream; @@ -46,6 +53,7 @@ public class Detect { /** * Detects entities,sentiment and syntax in a document using the Natural Language API. + * * @throws IOException on Input/Output errors. */ public static void main(String[] args) throws IOException { @@ -54,6 +62,7 @@ public static void main(String[] args) throws IOException { /** * Helper that handles the input passed to the program. + * * @throws IOException on Input/Output errors. */ public static void argsHelper(String[] args, PrintStream out) throws IOException { @@ -61,10 +70,11 @@ public static void argsHelper(String[] args, PrintStream out) throws IOException out.println("Usage:"); out.printf( "\tjava %s \"\" \"\"\n" - + "Commands:\n" - + "\tall-local | faces | labels | landmarks | logos | text | safe-search | properties\n" - + "Path:\n\tA file path (ex: ./resources/wakeupcat.jpg) or a URI for a Cloud Storage " - + "resource (gs://...)\n", + + "Commands:\n" + + "\tall-local | faces | labels | landmarks | logos | text | safe-search | properties" + + "| web | crop \n" + + "Path:\n\tA file path (ex: ./resources/wakeupcat.jpg) or a URI for a Cloud Storage " + + "resource (gs://...)\n", Detect.class.getCanonicalName()); return; } @@ -93,7 +103,9 @@ public static void argsHelper(String[] args, PrintStream out) throws IOException detectLabels(path, out); } } else if (command.equals("landmarks")) { - if (path.startsWith("gs://")) { + if (path.startsWith("http")) { + detectLandmarksUrl(path, out); + } else if (path.startsWith("gs://")) { detectLandmarksGcs(path, out); } else { detectLandmarks(path, out); @@ -122,6 +134,24 @@ public static void argsHelper(String[] args, PrintStream out) throws IOException } else { detectSafeSearch(path, out); } + } else if (command.equals("web")) { + if (path.startsWith("gs://")) { + detectWebDetectionsGcs(path, out); + } else { + detectWebDetections(path, out); + } + } else if (command.equals("crop")) { + if (path.startsWith("gs://")) { + detectCropHintsGcs(path, out); + } else { + detectCropHints(path, out); + } + } else if (command.equals("fulltext")) { + if (path.startsWith("gs://")) { + detectDocumentTextGcs(path, out); + } else { + detectDocumentText(path, out); + } } } @@ -129,6 +159,8 @@ public static void argsHelper(String[] args, PrintStream out) throws IOException /** * Constructs a {@link Detect} which connects to the Cloud Vision API. + * + * @param client The Vision API client. */ public Detect(ImageAnnotatorClient client) { visionApi = client; @@ -136,6 +168,7 @@ public Detect(ImageAnnotatorClient client) { /** * Detects faces in the specified local image. + * * @param filePath The path to the file to perform face detection on. * @param out A {@link PrintStream} to write detected features to. * @throws IOException on Input/Output errors. @@ -147,10 +180,8 @@ public static void detectFaces(String filePath, PrintStream out) throws IOExcept Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.FACE_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -164,7 +195,8 @@ public static void detectFaces(String filePath, PrintStream out) throws IOExcept // For full list of available annotations, see http://g.co/cloud/vision/docs for (FaceAnnotation annotation : res.getFaceAnnotationsList()) { - out.printf("anger: %s\njoy: %s\nsurprise: %s\nposition: %s", + out.printf( + "anger: %s\njoy: %s\nsurprise: %s\nposition: %s", annotation.getAngerLikelihood(), annotation.getJoyLikelihood(), annotation.getSurpriseLikelihood(), @@ -175,6 +207,7 @@ public static void detectFaces(String filePath, PrintStream out) throws IOExcept /** * Detects faces in the specified remote image. + * * @param gcsPath The path to the remote file to perform face detection on. * @param out A {@link PrintStream} to write detected features to. * @throws IOException on Input/Output errors. @@ -184,7 +217,9 @@ public static void detectFacesGcs(String gcsPath, PrintStream out) throws IOExce ImageAnnotatorSettings.Builder imageAnnotatorSettingsBuilder = ImageAnnotatorSettings.defaultBuilder(); - imageAnnotatorSettingsBuilder.batchAnnotateImagesSettings().getRetrySettingsBuilder() + imageAnnotatorSettingsBuilder + .batchAnnotateImagesSettings() + .getRetrySettingsBuilder() .setTotalTimeout(Duration.standardSeconds(30)); ImageAnnotatorSettings settings = imageAnnotatorSettingsBuilder.build(); @@ -192,10 +227,8 @@ public static void detectFacesGcs(String gcsPath, PrintStream out) throws IOExce Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.FACE_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); ImageAnnotatorClient client = ImageAnnotatorClient.create(settings); @@ -210,7 +243,8 @@ public static void detectFacesGcs(String gcsPath, PrintStream out) throws IOExce // For full list of available annotations, see http://g.co/cloud/vision/docs for (FaceAnnotation annotation : res.getFaceAnnotationsList()) { - out.printf("anger: %s\njoy: %s\nsurprise: %s\nposition: %s", + out.printf( + "anger: %s\njoy: %s\nsurprise: %s\nposition: %s", annotation.getAngerLikelihood(), annotation.getJoyLikelihood(), annotation.getSurpriseLikelihood(), @@ -221,6 +255,7 @@ public static void detectFacesGcs(String gcsPath, PrintStream out) throws IOExce /** * Detects labels in the specified local image. + * * @param filePath The path to the file to perform label detection on. * @param out A {@link PrintStream} to write detected labels to. * @throws IOException on Input/Output errors. @@ -232,10 +267,8 @@ public static void detectLabels(String filePath, PrintStream out) throws IOExcep Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.LABEL_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -249,13 +282,14 @@ public static void detectLabels(String filePath, PrintStream out) throws IOExcep // For full list of available annotations, see http://g.co/cloud/vision/docs for (EntityAnnotation annotation : res.getLabelAnnotationsList()) { - annotation.getAllFields().forEach((k, v)->out.printf("%s : %s\n", k, v.toString())); + annotation.getAllFields().forEach((k, v) -> out.printf("%s : %s\n", k, v.toString())); } } } /** * Detects labels in the specified remote image. + * * @param gcsPath The path to the remote file to perform label detection on. * @param out A {@link PrintStream} to write detected features to. * @throws IOException on Input/Output errors. @@ -266,10 +300,8 @@ public static void detectLabelsGcs(String gcsPath, PrintStream out) throws IOExc ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.LABEL_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -283,13 +315,14 @@ public static void detectLabelsGcs(String gcsPath, PrintStream out) throws IOExc // For full list of available annotations, see http://g.co/cloud/vision/docs for (EntityAnnotation annotation : res.getLabelAnnotationsList()) { - annotation.getAllFields().forEach((k, v)->out.printf("%s : %s\n", k, v.toString())); + annotation.getAllFields().forEach((k, v) -> out.printf("%s : %s\n", k, v.toString())); } } } /** * Detects landmarks in the specified local image. + * * @param filePath The path to the file to perform landmark detection on. * @param out A {@link PrintStream} to write detected landmarks to. * @throws IOException on Input/Output errors. @@ -300,10 +333,42 @@ public static void detectLandmarks(String filePath, PrintStream out) throws IOEx Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.LANDMARK_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // For full list of available annotations, see http://g.co/cloud/vision/docs + for (EntityAnnotation annotation : res.getLandmarkAnnotationsList()) { + LocationInfo info = annotation.getLocationsList().listIterator().next(); + out.printf("Landmark: %s\n %s\n", annotation.getDescription(), info.getLatLng()); + } + } + } + + /** + * Detects landmarks in the specified URI. + * + * @param url The path to the file to perform landmark detection on. + * @param out A {@link PrintStream} to write detected landmarks to. + * @throws IOException on Input/Output errors. + */ + public static void detectLandmarksUrl(String url, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ImageSource imgSource = ImageSource.newBuilder().setImageUri(url).build(); + Image img = Image.newBuilder().setSource(imgSource).build(); + Feature feat = Feature.newBuilder().setType(Type.LANDMARK_DETECTION).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -325,6 +390,7 @@ public static void detectLandmarks(String filePath, PrintStream out) throws IOEx /** * Detects landmarks in the specified remote image. + * * @param gcsPath The path to the remote file to perform landmark detection on. * @param out A {@link PrintStream} to write detected landmarks to. * @throws IOException on Input/Output errors. @@ -335,10 +401,8 @@ public static void detectLandmarksGcs(String gcsPath, PrintStream out) throws IO ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.LANDMARK_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -360,6 +424,7 @@ public static void detectLandmarksGcs(String gcsPath, PrintStream out) throws IO /** * Detects logos in the specified local image. + * * @param filePath The path to the local file to perform logo detection on. * @param out A {@link PrintStream} to write detected logos to. * @throws IOException on Input/Output errors. @@ -371,10 +436,8 @@ public static void detectLogos(String filePath, PrintStream out) throws IOExcept Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.LOGO_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -395,6 +458,7 @@ public static void detectLogos(String filePath, PrintStream out) throws IOExcept /** * Detects logos in the specified remote image. + * * @param gcsPath The path to the remote file to perform logo detection on. * @param out A {@link PrintStream} to write detected logos to. * @throws IOException on Input/Output errors. @@ -405,10 +469,8 @@ public static void detectLogosGcs(String gcsPath, PrintStream out) throws IOExce ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.LOGO_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -427,9 +489,9 @@ public static void detectLogosGcs(String gcsPath, PrintStream out) throws IOExce } } - /** * Detects text in the specified image. + * * @param filePath The path to the file to detect text in. * @param out A {@link PrintStream} to write the detected text to. * @throws IOException on Input/Output errors. @@ -441,10 +503,8 @@ public static void detectText(String filePath, PrintStream out) throws IOExcepti Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.TEXT_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -466,6 +526,7 @@ public static void detectText(String filePath, PrintStream out) throws IOExcepti /** * Detects text in the specified remote image. + * * @param gcsPath The path to the remote file to detect text in. * @param out A {@link PrintStream} to write the detected text to. * @throws IOException on Input/Output errors. @@ -476,10 +537,8 @@ public static void detectTextGcs(String gcsPath, PrintStream out) throws IOExcep ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.TEXT_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -501,6 +560,7 @@ public static void detectTextGcs(String gcsPath, PrintStream out) throws IOExcep /** * Detects image properties such as color frequency from the specified local image. + * * @param filePath The path to the file to detect properties. * @param out A {@link PrintStream} to write * @throws IOException on Input/Output errors. @@ -512,10 +572,8 @@ public static void detectProperties(String filePath, PrintStream out) throws IOE Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.IMAGE_PROPERTIES).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -530,7 +588,8 @@ public static void detectProperties(String filePath, PrintStream out) throws IOE // For full list of available annotations, see http://g.co/cloud/vision/docs DominantColorsAnnotation colors = res.getImagePropertiesAnnotation().getDominantColors(); for (ColorInfo color : colors.getColorsList()) { - out.printf("fraction: %f\nr: %f, g: %f, b: %f\n", + out.printf( + "fraction: %f\nr: %f, g: %f, b: %f\n", color.getPixelFraction(), color.getColor().getRed(), color.getColor().getGreen(), @@ -541,6 +600,7 @@ public static void detectProperties(String filePath, PrintStream out) throws IOE /** * Detects image properties such as color frequency from the specified remote image. + * * @param gcsPath The path to the remote file to detect properties on. * @param out A {@link PrintStream} to write * @throws IOException on Input/Output errors. @@ -551,10 +611,8 @@ public static void detectPropertiesGcs(String gcsPath, PrintStream out) throws I ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.IMAGE_PROPERTIES).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -569,7 +627,8 @@ public static void detectPropertiesGcs(String gcsPath, PrintStream out) throws I // For full list of available annotations, see http://g.co/cloud/vision/docs DominantColorsAnnotation colors = res.getImagePropertiesAnnotation().getDominantColors(); for (ColorInfo color : colors.getColorsList()) { - out.printf("fraction: %f\nr: %f, g: %f, b: %f\n", + out.printf( + "fraction: %f\nr: %f, g: %f, b: %f\n", color.getPixelFraction(), color.getColor().getRed(), color.getColor().getGreen(), @@ -578,9 +637,9 @@ public static void detectPropertiesGcs(String gcsPath, PrintStream out) throws I } } - /** * Detects whether the specified image has features you would want to moderate. + * * @param filePath The path to the local file used for safe search detection. * @param out A {@link PrintStream} to write the results to. * @throws IOException on Input/Output errors. @@ -592,10 +651,8 @@ public static void detectSafeSearch(String filePath, PrintStream out) throws IOE Image img = Image.newBuilder().setContent(imgBytes).build(); Feature feat = Feature.newBuilder().setType(Type.SAFE_SEARCH_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -609,7 +666,8 @@ public static void detectSafeSearch(String filePath, PrintStream out) throws IOE // For full list of available annotations, see http://g.co/cloud/vision/docs SafeSearchAnnotation annotation = res.getSafeSearchAnnotation(); - out.printf("adult: %s\nmedical: %s\nspoofed: %s\nviolence: %s\n", + out.printf( + "adult: %s\nmedical: %s\nspoofed: %s\nviolence: %s\n", annotation.getAdult(), annotation.getMedical(), annotation.getSpoof(), @@ -619,6 +677,7 @@ public static void detectSafeSearch(String filePath, PrintStream out) throws IOE /** * Detects whether the specified remote image has features you would want to moderate. + * * @param gcsPath The path to the remote file to detect safe-search on. * @param out A {@link PrintStream} to write the results to. * @throws IOException on Input/Output errors. @@ -629,10 +688,8 @@ public static void detectSafeSearchGcs(String gcsPath, PrintStream out) throws I ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); Image img = Image.newBuilder().setSource(imgSource).build(); Feature feat = Feature.newBuilder().setType(Type.SAFE_SEARCH_DETECTION).build(); - AnnotateImageRequest request = AnnotateImageRequest.newBuilder() - .addFeatures(feat) - .setImage(img) - .build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); requests.add(request); BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); @@ -646,11 +703,290 @@ public static void detectSafeSearchGcs(String gcsPath, PrintStream out) throws I // For full list of available annotations, see http://g.co/cloud/vision/docs SafeSearchAnnotation annotation = res.getSafeSearchAnnotation(); - out.printf("adult: %s\nmedical: %s\nspoofed: %s\nviolence: %s\n", + out.printf( + "adult: %s\nmedical: %s\nspoofed: %s\nviolence: %s\n", annotation.getAdult(), annotation.getMedical(), annotation.getSpoof(), annotation.getViolence()); } } + + /** + * Finds references to the specified image on the web. + * + * @param filePath The path to the local file used for web annotation detection. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectWebDetections(String filePath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath)); + + Image img = Image.newBuilder().setContent(imgBytes).build(); + Feature feat = Feature.newBuilder().setType(Type.WEB_DETECTION).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // Search the web for usages of the image. You could use these signals later + // for user input moderation or linking external references. + // For a full list of available annotations, see http://g.co/cloud/vision/docs + WebDetection annotation = res.getWebDetection(); + out.println("Entity:Id:Score"); + out.println("==============="); + for (WebEntity entity : annotation.getWebEntitiesList()) { + out.println(entity.getDescription() + " : " + entity.getEntityId() + " : " + + entity.getScore()); + } + out.println("\nPages with matching images: Score\n=="); + for (WebPage page : annotation.getPagesWithMatchingImagesList()) { + out.println(page.getUrl() + " : " + page.getScore()); + } + out.println("\nPages with partially matching images: Score\n=="); + for (WebImage image : annotation.getPartialMatchingImagesList()) { + out.println(image.getUrl() + " : " + image.getScore()); + } + out.println("\nPages with fully matching images: Score\n=="); + for (WebImage image : annotation.getFullMatchingImagesList()) { + out.println(image.getUrl() + " : " + image.getScore()); + } + } + } + + /** + * Detects whether the specified remote image has features you would want to moderate. + * + * @param gcsPath The path to the remote file to detect safe-search on. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectWebDetectionsGcs(String gcsPath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); + Image img = Image.newBuilder().setSource(imgSource).build(); + Feature feat = Feature.newBuilder().setType(Type.WEB_DETECTION).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // Search the web for usages of the image. You could use these signals later + // for user input moderation or linking external references. + // For a full list of available annotations, see http://g.co/cloud/vision/docs + WebDetection annotation = res.getWebDetection(); + out.println("Entity:Id:Score"); + out.println("==============="); + for (WebEntity entity : annotation.getWebEntitiesList()) { + out.println(entity.getDescription() + " : " + entity.getEntityId() + " : " + + entity.getScore()); + } + out.println("\nPages with matching images: Score\n=="); + for (WebPage page : annotation.getPagesWithMatchingImagesList()) { + out.println(page.getUrl() + " : " + page.getScore()); + } + out.println("\nPages with partially matching images: Score\n=="); + for (WebImage image : annotation.getPartialMatchingImagesList()) { + out.println(image.getUrl() + " : " + image.getScore()); + } + out.println("\nPages with fully matching images: Score\n=="); + for (WebImage image : annotation.getFullMatchingImagesList()) { + out.println(image.getUrl() + " : " + image.getScore()); + } + } + } + + /** + * Suggests a region to crop to for a local file. + * + * @param filePath The path to the local file used for web annotation detection. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectCropHints(String filePath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath)); + + Image img = Image.newBuilder().setContent(imgBytes).build(); + Feature feat = Feature.newBuilder().setType(Type.CROP_HINTS).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // For full list of available annotations, see http://g.co/cloud/vision/docs + CropHintsAnnotation annotation = res.getCropHintsAnnotation(); + for (CropHint hint : annotation.getCropHintsList()) { + out.println(hint.getBoundingPoly()); + } + } + } + + /** + * Suggests a region to crop to for a remote file. + * + * @param gcsPath The path to the remote file to detect safe-search on. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectCropHintsGcs(String gcsPath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); + Image img = Image.newBuilder().setSource(imgSource).build(); + Feature feat = Feature.newBuilder().setType(Type.CROP_HINTS).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // For full list of available annotations, see http://g.co/cloud/vision/docs + CropHintsAnnotation annotation = res.getCropHintsAnnotation(); + for (CropHint hint : annotation.getCropHintsList()) { + out.println(hint.getBoundingPoly()); + } + } + } + + /** + * Performs document text detection on a local image file. + * + * @param filePath The path to the local file to detect document text on. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectDocumentText(String filePath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath)); + + Image img = Image.newBuilder().setContent(imgBytes).build(); + Feature feat = Feature.newBuilder().setType(Type.DOCUMENT_TEXT_DETECTION).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + + // For full list of available annotations, see http://g.co/cloud/vision/docs + TextAnnotation annotation = res.getFullTextAnnotation(); + for (Page page: annotation.getPagesList()) { + String pageText = ""; + for (Block block : page.getBlocksList()) { + String blockText = ""; + for (Paragraph para : block.getParagraphsList()) { + String paraText = ""; + for (Word word: para.getWordsList()) { + String wordText = ""; + for (Symbol symbol: word.getSymbolsList()) { + wordText = wordText + symbol.getText(); + } + paraText = paraText + wordText; + } + // Output Example using Paragraph: + out.println("Paragraph: \n" + paraText); + out.println("Bounds: \n" + para.getBoundingBox() + "\n"); + blockText = blockText + paraText; + } + pageText = pageText + blockText; + } + } + out.println(annotation.getText()); + } + } + + /** + * Performs document text detection on a local image file. + * + * @param gcsPath The path to the remote file to detect document text on. + * @param out A {@link PrintStream} to write the results to. + * @throws IOException on Input/Output errors. + */ + public static void detectDocumentTextGcs(String gcsPath, PrintStream out) throws IOException { + List requests = new ArrayList<>(); + + ImageSource imgSource = ImageSource.newBuilder().setGcsImageUri(gcsPath).build(); + Image img = Image.newBuilder().setSource(imgSource).build(); + Feature feat = Feature.newBuilder().setType(Type.DOCUMENT_TEXT_DETECTION).build(); + AnnotateImageRequest request = + AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build(); + requests.add(request); + + BatchAnnotateImagesResponse response = visionApi.batchAnnotateImages(requests); + List responses = response.getResponsesList(); + + for (AnnotateImageResponse res : responses) { + if (res.hasError()) { + out.printf("Error: %s\n", res.getError().getMessage()); + return; + } + // For full list of available annotations, see http://g.co/cloud/vision/docs + TextAnnotation annotation = res.getFullTextAnnotation(); + for (Page page: annotation.getPagesList()) { + String pageText = ""; + for (Block block : page.getBlocksList()) { + String blockText = ""; + for (Paragraph para : block.getParagraphsList()) { + String paraText = ""; + for (Word word: para.getWordsList()) { + String wordText = ""; + for (Symbol symbol: word.getSymbolsList()) { + wordText = wordText + symbol.getText(); + } + paraText = paraText + wordText; + } + // Output Example using Paragraph: + out.println("Paragraph: \n" + paraText); + out.println("Bounds: \n" + para.getBoundingBox() + "\n"); + blockText = blockText + paraText; + } + pageText = pageText + blockText; + } + } + out.println(annotation.getText()); + } + } } diff --git a/vision/cloud-client/src/test/java/com/example/vision/DetectIT.java b/vision/cloud-client/src/test/java/com/example/vision/DetectIT.java index 0bcf8afb027..a75c98cfb10 100644 --- a/vision/cloud-client/src/test/java/com/example/vision/DetectIT.java +++ b/vision/cloud-client/src/test/java/com/example/vision/DetectIT.java @@ -29,9 +29,7 @@ import java.io.IOException; import java.io.PrintStream; -/** - * Tests for vision "Detect" sample. - */ +/** Tests for vision "Detect" sample. */ @RunWith(JUnit4.class) @SuppressWarnings("checkstyle:abbreviationaswordinname") public class DetectIT { @@ -52,18 +50,6 @@ public void tearDown() { System.setOut(null); } - @Test - public void testDetectEmptyArgs() throws Exception { - // Act - String[] args = {}; - Detect.argsHelper(args, out); - - // Assert - String got = bout.toString(); - assertThat(got).contains("all-local | faces | labels | landmarks |" - + " logos | text | safe-search | properties"); - } - @Test public void testFaces() throws Exception { // Act @@ -76,7 +62,7 @@ public void testFaces() throws Exception { assertThat(got).contains("joy: POSSIBLE"); assertThat(got).contains("surprise: UNLIKELY"); } - + @Test public void testFacesGcs() throws Exception { // Act @@ -100,7 +86,7 @@ public void testLabels() throws Exception { String got = bout.toString(); assertThat(got).contains("whiskers"); } - + @Test public void testLabelsGcs() throws Exception { // Act @@ -134,6 +120,17 @@ public void testLandmarksGcs() throws Exception { assertThat(got).contains("Palace of Fine Arts"); } + @Test + public void testLandmarksUrl() throws Exception { + // Act + String[] args = {"landmarks", "https://pbs.twimg.com/media/C4wfMOhVcAAUAgq.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Palace of Fine Arts"); + } + @Test public void testLogos() throws Exception { // Act @@ -213,7 +210,7 @@ public void testProperties() throws Exception { assertThat(got).contains("g:"); assertThat(got).contains("b:"); } - + @Test public void testPropertiesGcs() throws Exception { // Act @@ -227,4 +224,78 @@ public void testPropertiesGcs() throws Exception { assertThat(got).contains("g:"); assertThat(got).contains("b:"); } + + @Test + public void detectWebAnnotations() throws Exception { + // Act + String[] args = {"web", "./resources/landmark.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Palace"); + assertThat(got).contains("Rom"); // Matches Rome and Roman + } + + @Test + public void detectWebAnnotationsGcs() throws Exception { + // Act + String[] args = {"web", "gs://cloud-samples-tests/vision/landmark.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Palace"); + assertThat(got).contains("Rom"); // Matches Rome and Roman + } + + @Test + public void testCropHints() throws Exception { + // Act + String[] args = {"crop", "./resources/wakeupcat.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("vertices {"); + assertThat(got).contains("x: 599"); + assertThat(got).contains("y: 475"); + } + + @Test + public void testCropHintsGcs() throws Exception { + // Act + String[] args = {"crop", "gs://cloud-samples-tests/vision/wakeupcat.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("vertices {"); + assertThat(got).contains("x: 599"); + assertThat(got).contains("y: 475"); + } + + @Test + public void testDocumentText() throws Exception { + // Act + String[] args = {"fulltext", "./resources/text.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("After preparation is complete, the "); + assertThat(got).contains("37%"); + } + + @Test + public void testDocumentTextGcs() throws Exception { + // Act + String[] args = {"fulltext", "gs://cloud-samples-tests/vision/text.jpg"}; + Detect.argsHelper(args, out); + + // Assert + String got = bout.toString(); + assertThat(got).contains("After preparation is complete, the "); + assertThat(got).contains("37%"); + } }