メインコンテンツまでスキップ

検出範囲を指定してフィルタリング

CropDetectionFilter を使用して、画像内の特定の範囲のみを検出対象とするフィルタリングを設定できます。テキストとバーコードそれぞれに複数の検出範囲を指定でき、各検出結果がどの範囲に属するかを getCropIndex() で識別できます。

CropRect との違い

CropRectScanOptions で入力画像の切り取り範囲を 1 つ指定する機能です。一方 CropDetectionFilterModelSettings で設定する検出後のフィルタリング機能で、テキスト・バーコード別に複数の範囲を指定でき、範囲ごとに検出結果を分類できます。

動作の仕組み

  1. OCR エンジンが画像全体からテキスト・バーコードを検出する
  2. 各検出結果が指定した範囲と重なるかを判定する
  3. 重なる検出結果は範囲の境界にクリップされた状態で返される
  4. 各検出結果に cropIndex(範囲のインデックス)が割り当てられる
注記

textCrops / barcodeCrops を空にした場合、その種別の検出結果はフィルタリングされずすべてパススルーされます。

CropDetectionFilter のパラメータ

パラメータ型 (iOS / Android)デフォルト説明
textCrops[CGRect] / List<RectF>[]テキストの検出範囲のリスト
barcodeCrops[CGRect] / List<RectF>[]バーコードの検出範囲のリスト
combineHorizontalBool / booleanfalse各範囲内で水平方向に近いテキスト検出を結合するか(テキストのみ有効)
combineHorizontalRatio / combineHorizontalThresholdDouble / float0.9結合判定の閾値(縦方向の IoU)

各範囲は正規化座標(0.0〜1.0)で指定します。座標系は DetectiongetBoundingBox() と同じで、原点は左上です。

iOS と Android の座標の違い

iOS の CGRect(x, y, width, height) で指定しますが、Android の RectF(left, top, right, bottom) で指定します。同じ領域を表す場合でも記法が異なるので注意してください。

フィルタの作成と設定

CropDetectionFilter を作成し、ModelSettings に設定して useModel に渡します。

// テキストの検出範囲を 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

検出結果の範囲インデックス取得

DetectiongetCropIndex() メソッドで、その検出結果がどの検出範囲に属するかを取得できます。インデックスは textCropsbarcodeCrops それぞれ独立して 0 から割り当てられます。フィルタを設定していない場合は -1 が返ります。

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)")
}

CropSpec で範囲ごとの詳細設定

CropSpec を使うと、範囲ごとに複数の検出結果を返すかどうかを個別に設定できます。

CropSpec のフィールド型 (iOS / Android)説明
rectCGRect / RectF検出範囲
returnMultipleBool / booleantrue: 範囲内の検出をすべて返す / false: 面積が最大の 1 つだけ返す

簡易コンストラクタ(textCrops: [CGRect] / List<RectF>)を使用した場合、returnMultiple は自動的に false に設定されます。

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: []
)

水平方向の結合

combineHorizontaltrue に設定すると、各検出範囲内で水平方向に隣接するテキスト検出を 1 つに結合します。この機能はテキスト検出にのみ適用され、バーコード検出には適用されません。

結合の判定には縦方向の 1 次元 IoU(Intersection over Union)を使用します。2 つの検出の縦方向の IoU が閾値を超える場合、バウンディングボックスが統合されます。

let cropDetectionFilter = CropDetectionFilter(
textCrops: textCrops,
barcodeCrops: [],
combineHorizontal: true,
combineHorizontalRatio: 0.5
)