Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta feature : Vision : PDF/TIFF/GIF document feature detection #1349

Merged
merged 8 commits into from
Mar 20, 2019
4 changes: 2 additions & 2 deletions vision/beta/cloud-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<parent>
<groupId>com.google.cloud.samples</groupId>
<artifactId>shared-configuration</artifactId>
<version>1.0.9</version>
<version>1.0.10</version>
</parent>

<properties>
Expand All @@ -40,7 +40,7 @@
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vision</artifactId>
<version>1.62.0</version>
<version>1.64.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
Expand Down
Binary file added vision/beta/cloud-client/resources/kafka.pdf
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* 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]

nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
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

nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
public static void asyncBatchAnnotateImagesGcs(String gcsSourcePath, String gcsDestinationPath)
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
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<AnnotateImageRequest> requests = new ArrayList<>();
System.out.println("source: " + gcsSourcePath);
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved

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<Operation> 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<Blob> 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;
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
}
}

// 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]
Original file line number Diff line number Diff line change
@@ -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]

nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
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.

nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
public static void detectBatchAnnotateFiles(String filePath) {
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
// 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<Integer> pages = Arrays.asList(1, 2, -1);
ByteString pdfBytes = ByteString.readFrom(new FileInputStream(filePath));
Feature feat = Feature.newBuilder().setType(Type.DOCUMENT_TEXT_DETECTION).build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add empty line below

// Other supported mime types : 'image/tiff' or 'image/gif'
InputConfig inputConfig =
InputConfig.newBuilder().setMimeType("application/pdf").setContent(pdfBytes).build();
AnnotateFileRequest request =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add empty line above

AnnotateFileRequest.newBuilder()
.addFeatures(feat)
.setInputConfig(inputConfig)
.addAllPages(pages)
.build();
List<AnnotateFileRequest> requests = new ArrayList<>();
requests.add(request);
BatchAnnotateFilesRequest batchAnnotateFilesRequest =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add empty line above

BatchAnnotateFilesRequest.newBuilder().addAllRequests(requests).build();
ApiFuture<BatchAnnotateFilesResponse> 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]
Original file line number Diff line number Diff line change
@@ -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]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: empty line

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: empty line

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<Integer> 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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add space above

InputConfig inputConfig =
InputConfig.newBuilder().setMimeType("application/pdf").setGcsSource(gcsSource).build();
AnnotateFileRequest request =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add space above

AnnotateFileRequest.newBuilder()
.addFeatures(feat)
.setInputConfig(inputConfig)
.addAllPages(pages)
.build();
List<AnnotateFileRequest> requests = new ArrayList<>();
requests.add(request);
BatchAnnotateFilesRequest batchAnnotateFilesRequest =
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
BatchAnnotateFilesRequest.newBuilder().addAllRequests(requests).build();
ApiFuture<BatchAnnotateFilesResponse> future =
client.batchAnnotateFilesCallable().futureCall(batchAnnotateFilesRequest);
BatchAnnotateFilesResponse response = future.get();
client.close();
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
// Getting the first response
AnnotateFileResponse annotateFileResponse = response.getResponses(0);
// For full list of available annotations, see http://g.co/cloud/vision/docs
nirupa-kumar marked this conversation as resolved.
Show resolved Hide resolved
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]
Loading