diff --git a/vision/beta/cloud-client/pom.xml b/vision/beta/cloud-client/pom.xml index 11ee304116a..c3643869a0d 100644 --- a/vision/beta/cloud-client/pom.xml +++ b/vision/beta/cloud-client/pom.xml @@ -26,7 +26,7 @@ com.google.cloud.samples shared-configuration - 1.0.9 + 1.0.10 @@ -40,7 +40,7 @@ com.google.cloud google-cloud-vision - 1.62.0 + 1.64.0 com.google.cloud diff --git a/vision/beta/cloud-client/resources/kafka.pdf b/vision/beta/cloud-client/resources/kafka.pdf new file mode 100644 index 00000000000..ffa2e2fac2f Binary files /dev/null and b/vision/beta/cloud-client/resources/kafka.pdf differ diff --git a/vision/beta/cloud-client/src/main/java/com/example/vision/AsyncBatchAnnotateImagesGcs.java b/vision/beta/cloud-client/src/main/java/com/example/vision/AsyncBatchAnnotateImagesGcs.java new file mode 100644 index 00000000000..8454227621b --- /dev/null +++ b/vision/beta/cloud-client/src/main/java/com/example/vision/AsyncBatchAnnotateImagesGcs.java @@ -0,0 +1,155 @@ +/* + * Copyright 2019 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; + +// [START vision_async_batch_annotate_images_beta] +import com.google.api.core.ApiFuture; +import com.google.api.gax.paging.Page; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.Storage.BlobListOption; +import com.google.cloud.storage.StorageOptions; +import com.google.cloud.vision.v1p4beta1.AnnotateImageRequest; +import com.google.cloud.vision.v1p4beta1.AsyncBatchAnnotateImagesRequest; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateImagesResponse.Builder; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateImagesResponse; +import com.google.cloud.vision.v1p4beta1.Feature; +import com.google.cloud.vision.v1p4beta1.Feature.Type; +import com.google.cloud.vision.v1p4beta1.GcsDestination; +import com.google.cloud.vision.v1p4beta1.Image; +import com.google.cloud.vision.v1p4beta1.ImageAnnotatorClient; +import com.google.cloud.vision.v1p4beta1.ImageSource; +import com.google.cloud.vision.v1p4beta1.OutputConfig; + +import com.google.longrunning.Operation; +import com.google.protobuf.util.JsonFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class AsyncBatchAnnotateImagesGcs { + + // Performs asynchronous batch annotation of images on Google Cloud Storage + public static void asyncBatchAnnotateImagesGcs(String gcsSourcePath, String gcsDestinationPath) + throws Exception { + // String gcsSourcePath = "gs://YOUR_BUCKET_ID/path_to_your_data"; + // String gcsDestinationPath = "gs://YOUR_BUCKET_ID/path_to_store_annotation"; + + try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) { + List requests = new ArrayList<>(); + + ImageSource imgSource = ImageSource.newBuilder().setImageUri(gcsSourcePath).build(); + + Image image = Image.newBuilder().setSource(imgSource).build(); + + // Set the GCS destination path for where to save the results. + GcsDestination gcsDestination = + GcsDestination.newBuilder().setUri(gcsDestinationPath).build(); + + // Create the configuration for the output with the batch size. + // The batch size sets how many pages should be grouped into each json output file. + OutputConfig outputConfig = + OutputConfig.newBuilder().setGcsDestination(gcsDestination).setBatchSize(2).build(); + + // Select the Features required by the vision API + Feature features = + Feature.newBuilder() + .setType(Type.LABEL_DETECTION) + .setType(Type.TEXT_DETECTION) + .setType(Type.IMAGE_PROPERTIES) + .build(); + + // Build the request + AnnotateImageRequest annotateImageRequest = + AnnotateImageRequest.newBuilder().setImage(image).addFeatures(features).build(); + + requests.add(annotateImageRequest); + AsyncBatchAnnotateImagesRequest request = + AsyncBatchAnnotateImagesRequest.newBuilder() + .addAllRequests(requests) + .setOutputConfig(outputConfig) + .build(); + + ApiFuture future = client.asyncBatchAnnotateImagesCallable().futureCall(request); + // Wait for the request to finish. (The result is not used, since the API saves the result to + // the specified location on GCS.) + Operation response = future.get(180, TimeUnit.SECONDS); + + System.out.println("Waiting for the operation to finish."); + + // Once the request has completed and the output has been + // written to GCS, we can list all the output files. + Storage storage = StorageOptions.getDefaultInstance().getService(); + + // Get the destination location from the gcsDestinationPath + Pattern pattern = Pattern.compile("gs://([^/]+)/(.+)"); + Matcher matcher = pattern.matcher(gcsDestinationPath); + + if (matcher.find()) { + String bucketName = matcher.group(1); + String prefix = matcher.group(2); + + // Get the list of objects with the given prefix from the GCS bucket + Bucket bucket = storage.get(bucketName); + Page pageList = bucket.list(BlobListOption.prefix(prefix)); + + Blob firstOutputFile = null; + + // List objects with the given prefix. + System.out.println("Output files:"); + for (Blob blob : pageList.iterateAll()) { + System.out.println(blob.getName()); + + // Process the first output file from GCS. + // Since we specified batch size = 2, the first response contains + // the first two image requests + if (firstOutputFile == null) { + firstOutputFile = blob; + } + } + + // Get the contents of the file and convert the JSON contents to an + // BatchAnnotateImagesResponse + // object. If the Blob is small read all its content in one request + // (Note: the file is a .json file) + // Storage guide: https://cloud.google.com/storage/docs/downloading-objects + String jsonContents = new String(firstOutputFile.getContent()); + Builder builder = BatchAnnotateImagesResponse.newBuilder(); + JsonFormat.parser().merge(jsonContents, builder); + + // Build the AnnotateFileResponse object + BatchAnnotateImagesResponse batchAnnotateImagesResponse = builder.build(); + + // Here we print the response for the first image + // The response contains more information: + // annotation/pages/blocks/paragraphs/words/symbols/colors + // including confidence score and bounding boxes + System.out.format("\nResponse: %s\n", batchAnnotateImagesResponse.getResponses(0)); + + } else { + System.out.println("No MATCH"); + } + } catch (Exception e) { + System.out.println("Error during asyncBatchAnnotateImagesGcs: \n" + e.toString()); + } + } +} + +// [END vision_async_batch_annotate_images_beta] diff --git a/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFiles.java b/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFiles.java new file mode 100644 index 00000000000..34fc8bfec8c --- /dev/null +++ b/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFiles.java @@ -0,0 +1,110 @@ +/* + * Copyright 2019 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; + +// [START vision_batch_annotate_files_beta] +import com.google.api.core.ApiFuture; +import com.google.cloud.vision.v1p4beta1.AnnotateFileRequest; +import com.google.cloud.vision.v1p4beta1.AnnotateFileResponse; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateFilesRequest; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateFilesResponse; +import com.google.cloud.vision.v1p4beta1.Block; +import com.google.cloud.vision.v1p4beta1.Feature; +import com.google.cloud.vision.v1p4beta1.Feature.Type; +import com.google.cloud.vision.v1p4beta1.ImageAnnotatorClient; +import com.google.cloud.vision.v1p4beta1.InputConfig; +import com.google.cloud.vision.v1p4beta1.Page; +import com.google.cloud.vision.v1p4beta1.Paragraph; +import com.google.cloud.vision.v1p4beta1.Symbol; +import com.google.cloud.vision.v1p4beta1.TextAnnotation; +import com.google.cloud.vision.v1p4beta1.Word; +import com.google.protobuf.ByteString; + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DetectBatchAnnotateFiles { + + // Performs document feature detection on a local PDF/TIFF/GIF file. + public static void detectBatchAnnotateFiles(String filePath) { + // String filePath = "path/to/your_file"; + + try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) { + // Annotate the first two pages and the last one (max 5 pages) + // First page starts at 1, and not 0. Last page is -1. + List pages = Arrays.asList(1, 2, -1); + ByteString pdfBytes = ByteString.readFrom(new FileInputStream(filePath)); + Feature feat = Feature.newBuilder().setType(Type.DOCUMENT_TEXT_DETECTION).build(); + // Other supported mime types : 'image/tiff' or 'image/gif' + InputConfig inputConfig = + InputConfig.newBuilder().setMimeType("application/pdf").setContent(pdfBytes).build(); + AnnotateFileRequest request = + AnnotateFileRequest.newBuilder() + .addFeatures(feat) + .setInputConfig(inputConfig) + .addAllPages(pages) + .build(); + List requests = new ArrayList<>(); + requests.add(request); + + BatchAnnotateFilesRequest batchAnnotateFilesRequest = + BatchAnnotateFilesRequest.newBuilder().addAllRequests(requests).build(); + ApiFuture future = + client.batchAnnotateFilesCallable().futureCall(batchAnnotateFilesRequest); + BatchAnnotateFilesResponse response = future.get(); + + // Getting the first response + AnnotateFileResponse annotateFileResponse = response.getResponses(0); + + // For full list of available annotations, see http://g.co/cloud/vision/docs + TextAnnotation textAnnotation = annotateFileResponse.getResponses(0).getFullTextAnnotation(); + for (Page page : textAnnotation.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(); + System.out.format( + "Symbol text: %s (Confidence: %f)\n", symbol.getText(), symbol.getConfidence()); + } + System.out.format( + "Word text: %s (Confidence: %f)\n\n", wordText, word.getConfidence()); + paraText = String.format("%s %s", paraText, wordText); + } + // Output Example using Paragraph: + System.out.println("\nParagraph: \n" + paraText); + System.out.format("Paragraph Confidence: %f\n", para.getConfidence()); + blockText = blockText + paraText; + } + pageText = pageText + blockText; + } + } + System.out.println("\nComplete annotation:"); + System.out.println(textAnnotation.getText()); + + } catch (Exception e) { + System.out.println("Error during detectPdfText: \n" + e.toString()); + } + } +} +// [END vision_batch_annotate_files_beta] diff --git a/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFilesGcs.java b/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFilesGcs.java new file mode 100644 index 00000000000..5b8de5880ae --- /dev/null +++ b/vision/beta/cloud-client/src/main/java/com/example/vision/DetectBatchAnnotateFilesGcs.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019 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; + +// [START vision_batch_annotate_files_gcs_beta] +import com.google.api.core.ApiFuture; +import com.google.cloud.vision.v1p4beta1.AnnotateFileRequest; +import com.google.cloud.vision.v1p4beta1.AnnotateFileResponse; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateFilesRequest; +import com.google.cloud.vision.v1p4beta1.BatchAnnotateFilesResponse; +import com.google.cloud.vision.v1p4beta1.Block; +import com.google.cloud.vision.v1p4beta1.Feature; +import com.google.cloud.vision.v1p4beta1.Feature.Type; +import com.google.cloud.vision.v1p4beta1.GcsSource; +import com.google.cloud.vision.v1p4beta1.ImageAnnotatorClient; +import com.google.cloud.vision.v1p4beta1.InputConfig; +import com.google.cloud.vision.v1p4beta1.Page; +import com.google.cloud.vision.v1p4beta1.Paragraph; +import com.google.cloud.vision.v1p4beta1.Symbol; +import com.google.cloud.vision.v1p4beta1.TextAnnotation; +import com.google.cloud.vision.v1p4beta1.Word; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DetectBatchAnnotateFilesGcs { + + // Performs document feature detection on a remote PDF/TIFF/GIF file on Google Cloud Storage. + public static void detectBatchAnnotateFilesGcs(String gcsPath) { + // String gcsPath = "gs://Your_BUCKET_ID/path_to_your_data"; + + try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) { + // Annotate the first two pages and the last one (max 5 pages) + // First page starts at 1, and not 0. Last page is -1. + List pages = Arrays.asList(1, 2, -1); + GcsSource gcsSource = GcsSource.newBuilder().setUri(gcsPath).build(); + Feature feat = Feature.newBuilder().setType(Type.DOCUMENT_TEXT_DETECTION).build(); + //Other supported mime types : 'image/tiff' or 'image/gif' + InputConfig inputConfig = + InputConfig.newBuilder().setMimeType("application/pdf").setGcsSource(gcsSource).build(); + AnnotateFileRequest request = + AnnotateFileRequest.newBuilder() + .addFeatures(feat) + .setInputConfig(inputConfig) + .addAllPages(pages) + .build(); + List requests = new ArrayList<>(); + requests.add(request); + + BatchAnnotateFilesRequest batchAnnotateFilesRequest = + BatchAnnotateFilesRequest.newBuilder().addAllRequests(requests).build(); + ApiFuture future = + client.batchAnnotateFilesCallable().futureCall(batchAnnotateFilesRequest); + BatchAnnotateFilesResponse response = future.get(); + + // Getting the first response + AnnotateFileResponse annotateFileResponse = response.getResponses(0); + + // For full list of available annotations, see http://g.co/cloud/vision/docs + TextAnnotation textAnnotation = annotateFileResponse.getResponses(0).getFullTextAnnotation(); + for (Page page : textAnnotation.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(); + System.out.format( + "Symbol text: %s (Confidence: %f)\n", symbol.getText(), symbol.getConfidence()); + } + System.out.format( + "Word text: %s (Confidence: %f)\n\n", wordText, word.getConfidence()); + paraText = String.format("%s %s", paraText, wordText); + } + // Output Example using Paragraph: + System.out.println("\nParagraph: \n" + paraText); + System.out.format("Paragraph Confidence: %f\n", para.getConfidence()); + blockText = blockText + paraText; + } + pageText = pageText + blockText; + } + } + System.out.println("\nComplete annotation:"); + System.out.println(textAnnotation.getText()); + + } catch (Exception e) { + System.out.println("Error during detectPdfText: \n" + e.toString()); + } + } +} +// [END vision_batch_annotate_files_gcs_beta] diff --git a/vision/beta/cloud-client/src/test/java/com/example/vision/DetectIT.java b/vision/beta/cloud-client/src/test/java/com/example/vision/DetectIT.java index 89823c504bf..65d492fe5d1 100644 --- a/vision/beta/cloud-client/src/test/java/com/example/vision/DetectIT.java +++ b/vision/beta/cloud-client/src/test/java/com/example/vision/DetectIT.java @@ -32,13 +32,13 @@ @RunWith(JUnit4.class) @SuppressWarnings("checkstyle:abbreviationaswordinname") public class DetectIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + // private static final String BUCKET = PROJECT_ID; + private static final String BUCKET = "java-docs-samples-testing"; + private static final String OUTPUT_PREFIX = "OCR_PDF_TEST_OUTPUT"; private ByteArrayOutputStream bout; private PrintStream out; private Detect app; - private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); - //private static final String BUCKET = PROJECT_ID; - private static final String BUCKET = "java-docs-samples-testing"; - private static final String OUTPUT_PREFIX = "OCR_PDF_TEST_OUTPUT"; @Before public void setUp() throws IOException { @@ -90,14 +90,45 @@ public void testDetectLocalizedObjectsGcs() throws Exception { public void testDetectHandwrittenOcrGcs() throws Exception { // Act String[] args = { - "handwritten-ocr", - "gs://cloud-samples-data/vision/handwritten.jpg", + "handwritten-ocr", "gs://cloud-samples-data/vision/handwritten.jpg", }; Detect.argsHelper(args, out); // Assert String got = bout.toString(); assertThat(got).contains("Google Cloud Platform"); + } + + @Test + public void testDetectDocumentFeatures() { + // Act + DetectBatchAnnotateFiles.detectBatchAnnotateFiles("./resources/kafka.pdf"); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Samsa"); + } + @Test + public void testDetectDocumentFeaturesGcs() throws Exception { + // Act + DetectBatchAnnotateFilesGcs.detectBatchAnnotateFilesGcs( + "gs://cloud-samples-data/video/kafka.pdf"); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Samsa"); + } + + @Test + public void testAsyncBatchAnnotateImagesGcs() throws Exception { + // Act + AsyncBatchAnnotateImagesGcs.asyncBatchAnnotateImagesGcs( + "gs://cloud-samples-data/vision/label/wakeupcat.jpg", + "gs://" + BUCKET + "/" + OUTPUT_PREFIX + "/"); + + // Assert + String got = bout.toString(); + assertThat(got).contains("red:"); } }