複数回読み取りで精度を上げる
サンプルコード
- iOS: NtimesViewController.swift / NtimesView.swift
- Android: NtimesTextScanActivity.java
OCR の精度を上げるために、複数回連続で同じテキストを読み取ったかを判定する機能を提供しています。
読み取り回数の設定
ModelSettings で連続読み取り回数を設定します。デフォルトは 1 回です。
- iOS (Swift)
- Android (Java)
// 5 回同じ内容を読み取ったら確定
let modelSettings = ModelSettings(textNToConfirm: 5)
// 5 回同じ内容を読み取ったら確定
ModelSettings settings = new ModelSettings();
settings.setNToConfirm(5);
確定状態の判定
Detection の getStatus() メソッドで ScanConfirmationStatus.Confirmed かどうかを確認します。
- iOS (Swift)
- Android (Java)
if status == ScanConfirmationStatus.Confirmed {
let bbox = detection.getBoundingBox()
drawDetection(bbox: bbox, text: text)
}
for (Text detection : scanResult.getTextDetections()) {
String text = detection.getText();
if (detection.getStatus() == ScanConfirmationStatus.Confirmed) {
// 読み取り確定
filteredDetections.add(detection);
}
}
TextMapper
複数回読み取りを行う間に、手ブレやカメラの移動によって読み取り結果が変わると、カウントがリセットされてしまいます。TextMapper を使って読み取り結果を正規化することで、この影響を軽減できます。
TextMapper クラスを継承し、map(iOS)/ apply(Android)メソッドを実装します。以下は郵便番号を読み取る際に英字・記号を数字に変換する例です。
- iOS (Swift)
- Android (Java)
class PostcodeTextMapper: TextMapper {
let regex = /^\D*(\d{3})-(\d{4})\D*$/
override func map(_ text: Text) -> String {
var t = text.getText()
t = t.replacingOccurrences(of: "A", with: "4")
t = t.replacingOccurrences(of: "B", with: "8")
t = t.replacingOccurrences(of: "b", with: "6")
t = t.replacingOccurrences(of: "O", with: "0")
t = t.replacingOccurrences(of: "o", with: "0")
t = t.replacingOccurrences(of: "I", with: "1")
t = t.replacingOccurrences(of: "l", with: "1")
t = t.replacingOccurrences(of: "S", with: "5")
t = t.replacingOccurrences(of: "Z", with: "2")
// ... その他の変換
if let match = t.wholeMatch(of: regex) {
t = String(match.1) + "-" + String(match.2)
}
return t
}
}
設定:
let modelSettings = ModelSettings(textNToConfirm: 5)
modelSettings.setTextMapper(PostcodeTextMapper())
public class PostCodeTextMapper extends TextMapper {
private final Pattern regexPattern;
public PostCodeTextMapper() {
regexPattern = Pattern.compile("^.*((\\d{3})-(\\d{4})).*$");
}
@Override
public String apply(Text text) {
String t = text.getText();
t = t.replace("A", "4");
t = t.replace("B", "8");
t = t.replace("b", "6");
t = t.replace("O", "0");
t = t.replace("o", "0");
t = t.replace("I", "1");
t = t.replace("l", "1");
t = t.replace("S", "5");
t = t.replace("Z", "2");
// ... その他の変換
Matcher m = regexPattern.matcher(t);
if (m.find()) {
t = m.group(1);
}
return t;
}
}
設定:
ModelSettings settings = new ModelSettings();
settings.setNToConfirm(5);
settings.setTextMapper(new PostCodeTextMapper());