#!/usr/bin/env bash # Test-only tool: runs the full container pipeline (1_preprocess_image.sh, # 2_ocr_image.sh, 3_extract_data.sh) over every *.jpg in a test-data # directory, then compares the results against that directory's # ground-truth spreadsheet (benzin_kosten.ods). Everything - # preprocessing, OCR, structuring, and the comparison itself - runs # inside the tooling container; nothing here depends on a host Python # environment. # # For an input directory /, two sibling directories are # created (mirroring /): # /-scratch// - intermediate step output # (01_gray.png, 02_bilateral.png, # 03_final.png, ocr.txt) for # inspecting each step on its own # /-result// - final extracted.json per receipt, # plus summary.txt with the overall # ground-truth comparison # # Usage: ./test_batch.sh -in set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" ROOT="$(pwd)" fail() { echo "FAIL: $*" >&2; exit 1; } IN_DIR="" while [ $# -gt 0 ]; do case "$1" in -in) IN_DIR="${2:-}"; shift 2 ;; *) fail "unknown argument: $1" ;; esac done [ -n "$IN_DIR" ] || fail "usage: $0 -in " [ -d "$IN_DIR" ] || fail "input directory not found: $IN_DIR" IN_ABS="$(realpath "$IN_DIR")" ODS_PATH="$(find "$IN_ABS" -maxdepth 1 -name '*.ods' | head -n1)" [ -n "$ODS_PATH" ] || fail "no .ods ground-truth file found in $IN_ABS" PARENT_DIR="$(dirname "$IN_ABS")" BASE_NAME="$(basename "$IN_ABS")" SCRATCH_DIR="$PARENT_DIR/$BASE_NAME-scratch" RESULT_DIR="$PARENT_DIR/$BASE_NAME-result" mkdir -p "$SCRATCH_DIR" "$RESULT_DIR" shopt -s nullglob IMAGES=("$IN_ABS"/*.jpg) [ "${#IMAGES[@]}" -gt 0 ] || fail "no .jpg files found in $IN_ABS" echo "== Running pipeline over ${#IMAGES[@]} receipts ==" for img in "${IMAGES[@]}"; do name="$(basename "${img%.jpg}")" receipt_scratch="$SCRATCH_DIR/$name" receipt_result="$RESULT_DIR/$name" mkdir -p "$receipt_scratch" "$receipt_result" echo "--- $name ---" ./1_preprocess_image.sh -in "$img" -out "$receipt_scratch" >/dev/null ./2_ocr_image.sh -in "$receipt_scratch/03_final.png" -out "$receipt_scratch" >/dev/null ./3_extract_data.sh -in "$receipt_scratch/ocr.txt" -out "$receipt_result" >/dev/null done echo echo "== Comparing against ground truth ==" 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" ODS_DIR="$(dirname "$ODS_PATH")" ODS_FILE="$(basename "$ODS_PATH")" GROUP_ADD_ARGS=(--group-add "$(stat -c %g "$ODS_DIR")") RESULT_GID="$(stat -c %g "$RESULT_DIR")" [ "$RESULT_GID" = "$(stat -c %g "$ODS_DIR")" ] || GROUP_ADD_ARGS+=(--group-add "$RESULT_GID") docker run --rm \ --user "$(id -u):$(id -g)" \ "${GROUP_ADD_ARGS[@]}" \ -v "$ODS_DIR:/data/gt:ro" \ -v "$RESULT_DIR:/data/results:ro" \ "$IMAGE" \ python3 /opt/app/src/compare_ground_truth.py -gt "/data/gt/$ODS_FILE" -results /data/results \ | tee "$RESULT_DIR/summary.txt" echo echo "== Done ==" echo "Intermediate step output: $SCRATCH_DIR//" echo "Final results + summary: $RESULT_DIR//, $RESULT_DIR/summary.txt"