Cloud VsionのOCR処理を試してみました。
今回はAndroidで撮った写真をOCR処理したかったのですが、サンプルが存在しなかったので、物体認識のサンプルをベースに修正してみることにしました。
#callCloudVison
軽くコードを眺めてみて、なんとなくやってることを把握
どうやらCloud Visonの処理のコアは下記のメソッドで行っている様子(メソッド名から明らかですが…)
private void callCloudVision(final Bitmap bitmap) throws IOException {
// Switch text to loading
mImageDetails.setText(R.string.loading_message);
// Do the real work in an async task, because we need to use the network anyway
new AsyncTask<Object, Void, String>() {
@Override
protected String doInBackground(Object... params) {
try {
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
Vision.Builder builder = new Vision.Builder(httpTransport, jsonFactory, null);
builder.setVisionRequestInitializer(new
VisionRequestInitializer(CLOUD_VISION_API_KEY));
Vision vision = builder.build();
BatchAnnotateImagesRequest batchAnnotateImagesRequest =
new BatchAnnotateImagesRequest();
batchAnnotateImagesRequest.setRequests(new ArrayList<AnnotateImageRequest>() {{
AnnotateImageRequest annotateImageRequest = new AnnotateImageRequest();
// Add the image
Image base64EncodedImage = new Image();
// Convert the bitmap to a JPEG
// Just in case it's a format that Android understands but Cloud Vision
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
byte[] imageBytes = byteArrayOutputStream.toByteArray();
// Base64 encode the JPEG
base64EncodedImage.encodeContent(imageBytes);
annotateImageRequest.setImage(base64EncodedImage);
// add the features we want
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature labelDetection = new Feature();
labelDetection.setType("LABEL_DETECTION");
labelDetection.setMaxResults(10);
add(labelDetection);
}});
// Add the list of one thing to the request
add(annotateImageRequest);
}});
Vision.Images.Annotate annotateRequest =
vision.images().annotate(batchAnnotateImagesRequest);
// Due to a bug: requests to Vision API containing large images fail when GZipped.
annotateRequest.setDisableGZipContent(true);
Log.d(TAG, "created Cloud Vision request object, sending request");
BatchAnnotateImagesResponse response = annotateRequest.execute();
System.out.println(convertResponseToString(response));
return convertResponseToString(response);
} catch (GoogleJsonResponseException e) {
Log.d(TAG, "failed to make API request because " + e.getContent());
} catch (IOException e) {
Log.d(TAG, "failed to make API request because of other IOException " +
e.getMessage());
}
return "Cloud Vision API request failed. Check logs for details.";
}
protected void onPostExecute(String result) {
mImageDetails.setText(result);
}
}.execute();
}
private String convertResponseToString(BatchAnnotateImagesResponse response) {
String message = "I found these things:\n\n";
List<EntityAnnotation> labels = response.getResponses().get(0).getTextAnnotations();
if (labels != null) {
for (EntityAnnotation label : labels) {
message += String.format("%.3f: %s", label.getScore(), label.getDescription());
message += "\n";
}
} else {
message += "nothing";
}
return message;
}
##大まかな処理の流れ
①Cloud Visonに接続するオブジェクトの生成
②画像ファイルをCloud Visonに投入可能な形式に変換
③リクエストの構築
④リクエストをCloud Visonに投げる
⑤結果(Json)を解析
##物体認識からOCR処理(LABEL_DETECTION -> TEXT_DETECTION)
下記の部分で取得したい特徴を指定しているので、ここを変更します。
setTypeのパラメータはOCRのサンプルで確認しました。
// add the features we want
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature labelDetection = new Feature();
labelDetection.setType("LABEL_DETECTION");
labelDetection.setMaxResults(10);
add(labelDetection);
}});
変更後
// add the features we want
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature textDetection = new Feature();
textDetection.setType("TEXT_DETECTION");
textDetection.setMaxResults(10);
add(textDetection);
}});
##JSON解析部分(convertResponseToString)を修正
Cloud Visonのレスポンス一覧が載っているサイトを参考に修正
private String convertResponseToString(BatchAnnotateImagesResponse response) {
String message = "I found these things:\n\n";
List<EntityAnnotation> labels = response.getResponses().get(0).getTextAnnotations();
if (labels != null) {
message += labels.get(0).getDescription();
} else {
message += "nothing";
}
return message;
}
これでとりあえず、Androidで撮った写真内に存在する文字をOCR処理するサンプルが動作します。