検出範囲を指定してフィルタリング
CropDetectionFilter を使用して、画像内の特定の範囲のみを検出対象とするフィルタリングを設定できます。テキストとバーコードそれぞれに複数の検出範囲を指定でき、各検出結果がどの範囲に属するかを getCropIndex() で識別できます。
CropRect は ScanOptions で入力画像の切り取り範囲を 1 つ指定する機能です。一方 CropDetectionFilter は ModelSettings で設定する検出後のフィルタリング機能で、テキスト・バーコード別に複数の範囲を指定でき、範囲ごとに検出結果を分類できます。
動作の仕組み
- OCR エンジンが画像全体からテキスト・バーコードを検出する
- 各検出結果が指定した範囲と重なるかを判定する
- 重なる検出結果は範囲の境界にクリップされた状態で返される
- 各検出結果に
cropIndex(範囲のインデックス)が割り当てられる
textCrops / barcodeCrops を空にした場合、その種別の検出結果はフィルタリングされずすべてパススルーされます。
CropDetectionFilter のパラメータ
| パラメータ | 型 (iOS / Android) | デフォルト | 説明 |
|---|---|---|---|
textCrops | [CGRect] / List<RectF> | [] | テキストの検出範囲のリスト |
barcodeCrops | [CGRect] / List<RectF> | [] | バーコードの検出範囲のリスト |
combineHorizontal | Bool / boolean | false | 各範囲内で水平方向に近いテキスト検出を結合するか(テキストのみ有効) |
combineHorizontalRatio / combineHorizontalThreshold | Double / float | 0.9 | 結合判定の閾値(縦方向の IoU) |
各範囲は正規化座標(0.0〜1.0)で指定します。座標系は Detection の getBoundingBox() と同じで、原点は左上です。
iOS の CGRect は (x, y, width, height) で指定しますが、Android の RectF は (left, top, right, bottom) で指定します。同じ領域を表す場合でも記法が異なるので注意してください。
フィルタの作成と設定
CropDetectionFilter を作成し、ModelSettings に設定して useModel に渡します。
- iOS (Swift)
- Android (Java)
// テキストの検出範囲を 2 つ指定
let textCrops = [
CGRect(x: 0.1, y: 0.1, width: 0.8, height: 0.2), // 上部の範囲
CGRect(x: 0.1, y: 0.6, width: 0.8, height: 0.2), // 下部の範囲
]
let cropDetectionFilter = CropDetectionFilter(
textCrops: textCrops,
barcodeCrops: []
)
let modelSettings = ModelSettings()
modelSettings.cropDetectionFilter = cropDetectionFilter
// テキストの検出範囲を 2 つ指定
List<RectF> textCrops = Arrays.asList(
new RectF(0.1f, 0.1f, 0.9f, 0.3f), // 上部の範囲 (left, top, right, bottom)
new RectF(0.1f, 0.6f, 0.9f, 0.8f) // 下部の範囲
);
CropDetectionFilter cropDetectionFilter = new CropDetectionFilter(
textCrops,
Collections.emptyList(), // barcodeCrops
false, // combineHorizontal
0.9f // combineHorizontalThreshold
);
ModelSettings modelSettings = new ModelSettings();
modelSettings.setCropDetectionFilter(cropDetectionFilter);
検出結果の範囲インデックス取得
Detection の getCropIndex() メソッドで、その検出結果がどの検出範囲に属するかを取得できます。インデックスは textCrops と barcodeCrops それぞれ独立して 0 から割り当てられます。フィルタを設定していない場合は -1 が返ります。
- iOS (Swift)
- Android (Java)
let scanResult = try edgeOCR.scan(
sampleBuffer,
scanOption: scanOptions,
viewBounds: viewBounds)
for detection in scanResult.getTextDetections() {
let text = detection.getText()
let cropIndex = detection.getCropIndex()
// cropIndex == 0: 上部の範囲で検出
// cropIndex == 1: 下部の範囲で検出
print("テキスト: \(text), 範囲: \(cropIndex)")
}
ScanResult scanResult = api.scan(image);
for (Text detection : scanResult.getTextDetections()) {
String text = detection.getText();
int cropIndex = detection.getCropIndex();
// cropIndex == 0: 上部の範囲で検出
// cropIndex == 1: 下部の範囲で検出
Log.d("EdgeOCR", "テキスト: " + text + ", 範囲: " + cropIndex);
}
CropSpec で範囲ごとの詳細設定
CropSpec を使うと、範囲ごとに複数の検出結果を返すかどうかを個別に設定できます。
| CropSpec のフィールド | 型 (iOS / Android) | 説明 |
|---|---|---|
rect | CGRect / RectF | 検出範囲 |
returnMultiple | Bool / boolean | true: 範囲内の検出をすべて返す / false: 面積が最大の 1 つだけ返す |
簡易コンストラクタ(textCrops: [CGRect] / List<RectF>)を使用した場合、returnMultiple は自動的に false に設定されます。
- iOS (Swift)
- Android (Java)
let textCropSpecs = [
// 上部の範囲: 複数のテキストを返す
CropDetectionFilter.CropSpec(
rect: CGRect(x: 0.1, y: 0.1, width: 0.8, height: 0.2),
returnMultiple: true
),
// 下部の範囲: 面積が最大の 1 つだけ返す
CropDetectionFilter.CropSpec(
rect: CGRect(x: 0.1, y: 0.6, width: 0.8, height: 0.2),
returnMultiple: false
),
]
let cropDetectionFilter = CropDetectionFilter(
textCropSpecs: textCropSpecs,
barcodeCropSpecs: []
)
List<CropDetectionFilter.CropSpec> textCropSpecs = Arrays.asList(
// 上部の範囲: 複数のテキストを返す
new CropDetectionFilter.CropSpec(
new RectF(0.1f, 0.1f, 0.9f, 0.3f), true),
// 下部の範囲: 面積が最大の 1 つだけ返す
new CropDetectionFilter.CropSpec(
new RectF(0.1f, 0.6f, 0.9f, 0.8f), false)
);
CropDetectionFilter cropDetectionFilter = new CropDetectionFilter(
false, // combineHorizontal
0.9f, // combineHorizontalThreshold
textCropSpecs, // textCropSpecs
Collections.emptyList() // barcodeCropSpecs
);
水平方向の結合
combineHorizontal を true に設定すると、各検出範囲内で水平方向に隣接するテキスト検出を 1 つに結合します。この機能はテキスト検出にのみ適用され、バーコード検出には適用されません。
結合の判定には縦方向の 1 次元 IoU(Intersection over Union)を使用します。2 つの検出の縦方向の IoU が閾値を超える場合、バウンディングボックスが統合されます。
- iOS (Swift)
- Android (Java)
let cropDetectionFilter = CropDetectionFilter(
textCrops: textCrops,
barcodeCrops: [],
combineHorizontal: true,
combineHorizontalRatio: 0.5
)
CropDetectionFilter cropDetectionFilter = new CropDetectionFilter(
textCrops,
Collections.emptyList(),
true, // combineHorizontal: 水平結合を有効化
0.5f // combineHorizontalThreshold: 縦方向 IoU の閾値
);