こんにちは。短い内容で恐縮ですが、よろしくお願いします。画像が多いだけです。
やってみたこと
- ML Kit Text Recognition v2を使って
- カメラアプリで撮った日本語の字をOCRっぽく認識する
- Androidアプリを作ってみました。
NIVEA Moisture Lip
唇が渇きやすい私にとっての日用必需品。
「UNSCENTED」はどこから?と探してみたら、本体にありました。
「湿」が出ませんでした、残念。「濃」も「氵(さんずい)」が取れちゃってますね。
「ホホバオイル」も「ホfオイル」ですね、残念。
いやいや、それでも縦書きなのに認識したことがすごいです!
でも、「敏感な唇にもやさしい潤い感」は完全にスルーですね。左上の「薬用」も。
ピスタチオ香るチョコレート
100均ショップDAISOに行ったら、なんと!皆さんご存じショコラメゾン「ミュゼ・ドゥ・ショコラ・テオブロマ」の、かの有名なオーナーショコラティエの土屋公二シェフ(「ミスターカカオ」「味覚の魔術師」の異名を持ってます)のチョコが!チョコレート大好きな私はもうそれだけでテンション上がりました!
ほぼ完璧!
「-スト3AP」は何だろう?「土屋公二シェフ監修」の部分かな?
ちなみにカメラで撮影するとき、カメラが自動で土屋公二シェフの顔にピントを合わせようとしたので、ちょっと可笑しかったです。お菓子買ったです。
自分の手書き
書いてるそばから「阝(おおざと)が甘いかな~」とは思っていたんです。
ちなみに、もう一度試行したら「東京券」となりました。はやり「阝」はしっかり大きく書けばよかったと後悔です。
ML Kit Text Recognition v2
テキスト認識だけでなく、顔検出や、バーコード読み取りなどできるそうです。
ここではテキスト認識だけを試してみました。
日本語などサポートするようになった
v2より前は、ラテン文字しかテキスト認識できませんでした。
ですが、v2になってからは、中国語、デバナーガリー語、日本語、韓国語をサポートしたそうです。待ってました!ただし現時点ではまだベータ版です。
オンデバイスで利用可能
クラウドで解析をしてもらう、というのではなく、なんと端末内で完結できるのがすごいところです。
AndroidとiOSをサポートしてます。
開発
Windows 10、Android Studio 2021.2.1です。
端末はASUS製の古いスマホを使いました。
ライブラリー
build.gradleに以下を追記してsync nowです。日本語のだけを取り寄せました。
implementation 'com.google.mlkit:text-recognition-japanese:16.0.0-beta6'
インストール済み標準カメラアプリを利用
自分でカメラ機能を実装するのは面倒くさかったので、インストール済み標準カメラアプリを利用することにします。
Manifestに以下のパーミッションなどを設定します。
<uses-permission android:name="android.permission.CAMERA" />
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
Activityでは、インストール済みカメラアプリを利用するためのActivityResultLauncher
をフィールドとして定義します。
プログラム
Activity1個と、そのレイアウトリソースファイル1枚だけです。
前掲のスクリーンショットでも見えてますが、画面の大半を<ImageView android:id="@+id/imageFromCamera">
、そして画面の下に<Button android:id="@+id/btnInvokeCamera">
を配置しています。
CAMERAパーミッションのリクエストダイアログの対応のコードは、この記事の本題と乖離があるので割愛しています。
public class MainActivity extends AppCompatActivity {
private final ActivityResultLauncher<Void> cameraLauncher = registerForActivityResult(
new ActivityResultContracts.TakePicturePreview(), bitmap -> {
findViewById(R.id.imageFromCamera).setImageBitmap(bitmap);
int rotationDegree = 0;
InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);
// 日本語もサポートした!
TextRecognizer recognizer = TextRecognition.getClient(new JapaneseTextRecognizerOptions.Builder().build());
Task<Text> task = recognizer.process(image)
.addOnSuccessListener(new OnSuccessListener<Text>() {
@Override
public void onSuccess(Text visionText) {
String resultText = visionText.getText(); // 文字列取得!
new AlertDialog.Builder(MainActivity.this).setMessage(resultText).show();
}
});
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ボタン押下でカメラアプリを起動
findViewById(R.id.btnInvokeCamera).setOnClickListener(v -> cameraLauncher.launch(null));
}
}
カメラ起動Launcherから返されたBitmap
を、com.google.mlkit.vision.common.InputImage
のコンストラクタに渡してインスタンス化します。
com.google.mlkit.vision.text.TextRecognizer
インスタンスは、staticメソッドgetClient
から取得します。
今回は日本語で試したかったので、JapaneseTextRecognizerOptions
オブジェクトを引数に渡しています(もしラテン文字だけでいい、というのであれば、名前付き定数TextRecognizerOptions.DEFAULT_OPTIONS
です)。
TextRecognizer
のメソッドprocess
に引数InputImage
を渡して認識してもらいます。
今回は成功したときだけしか実装しました。(addOnSuccessListener
)。失敗したときの処理を実装したければ、addOnFailureListener
メソッドも呼び出します(今回は省略しました)。
OnSuccessListener
は関数型インタフェースですので、ラムダ式で書いた方が短く済みますね。
あとはAlertDialog
にて認識結果のString
を出力させているだけです。
最後に
いつの間にかML Kitが日本語に対応していました。すごいです。
次回はデバナーガリー語に挑戦したいと、思いま…否、ところでデバナーガリー語とは???
ということで、
क्रिसमस की बधाई!
以上です。