Flutterの記事を整理し本にしました
- 本稿の記事を含む様々な記事を体系的に整理し本にまとめました
- 今後はこちらを最新化するため、最新情報はこちらをご確認ください
- 25万文字を超える超大作になっています!!
まとめ記事
はじめに
- VisionAPIを使ったことがあったので、それと親しいFirebaseのMLをFlutterと組み合わせて動かしてみました。
概要
Firebase MachineLearning(以下ML)は機械学習の画像認識APIを用いて、判定やクラス分け、ラベリングなどを行う環境を提供します。
自前で学習やモデル作成を行えば、より幅広い機械学習の識別が実現できます。
有効化手順
MLの有効化は、Firebaseの左側のメニューのMachineLearningを選択し、始めるをクリックします。
機械学習には、以下の3種類があります。
- APIs:GCPのVisionAPIのように、画像認識を基本にテキスト認識や、ラベリング、顔検知などを行えます
- Custom:TensorFlowなどのtfliteの学習モデルを使って処理を行えます
- AutoML:CloudAutoMLでGCP上での機械学習と連携することができます。
me
以後は、事前のモデル作成が不要なAPIsについて解説していきます
APIsには、いくつかの種類が用意されていますので、使いたい目的に合わせて使用するAPIを選択します。
処理には、デバイスで行うオンデバイスと、クラウドで行う2種類があります。
APIによって利用できる形態や機能に制約がありますので、ご注意ください。
クラウドベースを行う際には、プランをBlaze
にアップグレードする必要があります。
なお、今回解説するテキスト認識の日本語は、クラウドでないと使えないため、プランをアップグレードしています。
準備
firebase_core: ^1.1.0
firebase_ml_vision: ^0.12.0+1
image_picker: ^0.7.4
MLを使うためのパッケージがfirebase_ml_vision
とfirebase_core
になります。
image_picker
は画像やカメラを選択するために使っています。
実装
デバイス内の画面を選択してテキスト認識(OCR)をするものと、カメラを使って取った写真のラベリングを行うものの2種類を実装しています。
どちらもクラウド側で処理を行っています。
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Text _text;
Image _image;
Future<void> _ocr() async {
PickedFile pickerFile =
await ImagePicker().getImage(source: ImageSource.gallery);
final File imageFile = File(pickerFile.path);
final FirebaseVisionImage visionImage =
FirebaseVisionImage.fromFile(imageFile);
TextRecognizer textRecognizer =
FirebaseVision.instance.cloudTextRecognizer();
final VisionText visionText =
await textRecognizer.processImage(visionImage);
String text = visionText.text;
for (TextBlock block in visionText.blocks) {
print(block.text);
}
// 画面に反映
setState(() {
_text = Text(text);
_image = Image.file(File(pickerFile.path));
});
// リソースの開放
textRecognizer.close();
}
Future<void> _labeling() async {
PickedFile pickerFile =
await ImagePicker().getImage(source: ImageSource.camera);
final File imageFile = File(pickerFile.path);
final FirebaseVisionImage visionImage =
FirebaseVisionImage.fromFile(imageFile);
ImageLabeler labeler = FirebaseVision.instance.imageLabeler();
List<ImageLabel> labels = await labeler.processImage(visionImage);
String text = "";
for (ImageLabel label in labels) {
print(label.text);
text += label.text + " ";
print(label.confidence);
}
// 画面に反映
setState(() {
_text = Text(text);
_image = Image.file(File(pickerFile.path));
});
// リソースの開放
labeler.close();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_text != null) _text,
if (_image != null) SafeArea(child: _image),
],
),
),
floatingActionButton:
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
FloatingActionButton(onPressed: _ocr, child: Icon(Icons.photo_album)),
FloatingActionButton(
onPressed: _labeling, child: Icon(Icons.photo_camera))
]));
}
}
まず、firebaseを利用するために以下の2行で初期化処理をしています。
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
テキスト認識用とラベリング用のボタンがあり、それぞれが_ocr
と_labeling
に対応しています。
基本的な流れは同じですが、使用するAPIによって使用するインスタンスが異なります。
テキスト認識(OCR)×写真ギャラリー
まず、ImagePickerを使って、ギャラリーからOCRで文字を読み取りたい画像を選択します。
その後、VisionImage
とTextRecognizer
のインスタンスを作成し、TextRecognizer
に画像を与えて解析を行います。
そして、結果からtextで文字や詳細情報を取得します。
最後に、画面に表示させたあとリソースを開放しています。
オブジェクトラベリング×カメラ
こちらも、まず、ImagePickerを使って、ギャラリーからOCRで文字を読み取りたい画像を選択します。
その後、VisionImage
とImageLabeler
のインスタンスを作成し、ImageLabeler
に画像を与えて解析を行います。
そして、結果(Labelのリスト)から認識されたラベルテキストを取得します。
最後に、画面に表示させたあとリソースを開放しています。
動作イメージ
ギャラリーのアイコンをタップした後、ストレージから本書の帯を選択したときの例
テキスト認識(OCR)×写真ギャラリー
I/flutter (14560): Flutter実践入門
I/flutter (14560): 環境構築からAndroid/iOS/Webに
I/flutter (14560): 広告を付けて同時にリリース!!
コンソール及び画面に、写真から識別した文字が、1字の誤字もなく高い精度で変換されていることが分かります。
オブジェクトラベリング×カメラ
カメラのアイコンをタップした後、時計を撮影したときの例
I/flutter (18593): Clock
I/flutter (18593): 0.8892788887023926
写真が約90%の確率で時計であると認識されています。
今回は、時計のみの識別ですが、写真のとり方によってはいくつかの選択肢が提示されたりします。
また、複数のオブジェクトが写っている場合は、それぞれに識別が行われます。