#!/usr/bin/env bash # Combines steps 1+2 (preprocess + OCR) adaptively: tries preprocess.py's # variants cheapest-first (0=baseline, same as 1_preprocess_image.sh's # default, up to 3=most elaborate), scoring each variant's OCR text with # tooling-container/src/plausibility.py and stopping at the first one # that looks receipt-consistent - no LLM call involved, so this costs # nothing extra over the single-variant path for the receipts the # baseline already reads correctly. See tooling-container/src/adaptive.py # and testing/2026_10_04_gimp_highpass_nlfilter_experiment.md for why. # # Writes /variant/{01_gray,...,0X_final}.png and its own ocr.txt # for every variant tried (for inspection - which variant was kept is in # the printed summary) and /ocr.txt (the winning variant's OCR # text, ready for ./3_extract_data.sh). # # Usage: ./12_adaptive_preprocess_ocr.sh -in -out set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" ROOT="$(pwd)" fail() { echo "FAIL: $*" >&2; exit 1; } IN_PATH="" OUT_DIR="" while [ $# -gt 0 ]; do case "$1" in -in) IN_PATH="${2:-}"; shift 2 ;; -out) OUT_DIR="${2:-}"; shift 2 ;; *) fail "unknown argument: $1" ;; esac done [ -n "$IN_PATH" ] && [ -n "$OUT_DIR" ] \ || fail "usage: $0 -in -out " [ -f "$IN_PATH" ] || fail "input file not found: $IN_PATH" command -v docker >/dev/null 2>&1 || fail "docker not found in PATH" IMAGE="${REGISTRY_IMAGE:-fuelish/tools}" if [ -f "$ROOT/registry.env" ]; then # shellcheck disable=SC1091 source "$ROOT/registry.env" IMAGE="${REGISTRY_IMAGE:-$IMAGE}" fi VERSION="$(<"$ROOT/tooling-container/VERSION")" IMAGE="$IMAGE:$VERSION" docker image inspect "$IMAGE" >/dev/null 2>&1 \ || fail "$IMAGE not found locally - run ./build-image.sh first" IN_ABS="$(realpath "$IN_PATH")" IN_DIR="$(dirname "$IN_ABS")" IN_FILE="$(basename "$IN_ABS")" mkdir -p "$OUT_DIR" OUT_ABS="$(realpath "$OUT_DIR")" GROUP_ADD_ARGS=(--group-add "$(stat -c %g "$IN_DIR")") OUT_GID="$(stat -c %g "$OUT_ABS")" [ "$OUT_GID" = "$(stat -c %g "$IN_DIR")" ] || GROUP_ADD_ARGS+=(--group-add "$OUT_GID") echo "== Adaptively preprocessing + OCRing $IN_FILE ==" docker run --rm \ --user "$(id -u):$(id -g)" \ "${GROUP_ADD_ARGS[@]}" \ -v "$IN_DIR:/data/in:ro" \ -v "$OUT_ABS:/data/out" \ "$IMAGE" \ python3 /opt/app/src/adaptive.py -in "/data/in/$IN_FILE" -out /data/out echo "== Done ==" echo "Next: ./3_extract_data.sh -in $OUT_ABS/ocr.txt -out $OUT_ABS"