andrew 7ad995d8d1
ci / smoke (push) Canceled after 0s
feat(manual-batch): require plate number at manual mode start
Legacy manual batch start locked until plate entered:
- POST /api/batch/start manual branch returns 400 missing_plate when
  plate empty (strip + uppercase, no format regex)
- operator + monitoring start modals gain required plate input,
  confirm button disabled until filled
- operator plate tile also shows for manual batches (was do_manual only)
- do_manual unchanged (plate from DOs)
2026-10-02 15:10:13 +07:00

Karung Counter

Repo: https://git.proit.id/andrew/karung-counting-feedmill-semarang

AI video-analytics system that counts feed sacks (karung-pakan) being loaded onto / unloaded from trucks at a feedmill loading gate. It watches an RTSP camera, detects the truck bed, tracks sacks with persistent IDs, counts line-crossings per truck (batch), persists results to SQLite/CSV, and serves a live Flask dashboard.

Language note: UI strings, logs and comments are largely in Indonesian (karung = sack/bag, truk = truck, muat = load). Class names inside the YOLO models are English (sack, box, truck, person).

Pipeline (production, predict.py)

Frame → TruckDetect → ROI → SackTrack → Stabilize → Count → Dashboard / DB
Stage Module What it does
Stream src/streaming.py RTSP (RTSPSource) or video file (VideoFileSource)
Truck detect src/detection.py (TruckDetector) Dedicated truck model, run every 15 frames
ROI src/truck_roi.py (TruckROITracker) Picks main truck in lane, EMA-smooths bbox, derives counting line
Sack track src/tracking.py (ByteTrackTracker) YOLO + FastTrack/ByteTrack, tuned via cfg/tracker.yaml
Stabilize src/stabilizer.py (BboxStabilizer) EMA bbox smoothing + occlusion hold + height clamps
Count src/counting.py (LineCrossCounter) Zone-based line crossing: loading / unloading / net, 3-layer dedup
Batch src/batch.py (BatchLifecycleManager) 4-state FSM: IDLE → TRUCK_STABILIZING → COUNTING_SACKS ⇄ WAITING_FOR_ACTIVITY
Output src/logger.py, src/dashboard.py CSV logs + on-frame overlay

Full detail: docs/architecture.md.

Quickstart

pip install -r requirements.txt   # Jetson: never pip-install torch from PyPI, use NVIDIA wheels
cp .env.example .env              # then edit RTSP_URL / paths

# Dev / offline (any flags omitted = production defaults):
python predict.py --source path/to/video.mp4 --env .env
python predict.py --source vid.mp4 --no-dashboard --no-db --output-dir /tmp/out --max-frames 500
python predict.py --help          # all flags: --config/--model/--model-mode/--output-json/--sack-conf/--truck-conf/--box-conf/--box-model/--batch-timeout

# Production (Jetson systemd, zero flags):
sudo systemctl restart karung-counter karung-counter-dashboard

Production on the Jetson runs predict.py + counter_dashboard.py as systemd services (see docs/deployment.md) — predict.py is the production pipeline (SQLite persistence, live-frame publishing to /dev/shm, zone polygons); the src/ package is the shared detection/tracking/counting library it builds on (the old v3 src/main.py loop is deprecated). Retired experiments live in archive/.

Models

All weights live in models/ (see models/modelREADME.md for the per-mode detector/filter matrix).

File Classes Role
models/truck-detector.{pt,engine} truck Specialized truck detector (ROI, batch lifecycle)
models/v4-best.{pt,onnx,engine} / models/model_karung_truk.{pt,onnx,engine} sack, truck Combined sack+truck (Modes A/B/C/D truck; Modes A/C sack)
models/karung-dimuat-…-seg-200e.{pt,onnx,engine} person, sack Segmentation model: sacks counted, persons drawn/skipped
models/yolo11n-bbox-100ep-sack+box-20260909-best.{pt,onnx,engine} sack, box Unified sack+box (Modes B/C/D)
models/best.{pt,onnx,engine} sack Sack-only specialist (Mode D sack)

.pt = PyTorch, .engine = TensorRT FP16 (Jetson GPU, what production loads), .onnx = ONNX export artifact. See docs/models.md for the multi-model / multi-class / hybrid support matrix.

Configuration

File Purpose
config.yaml Canonical config: stream, model modes/presets, counting knobs, batch, output paths, camera
.env (see .env.example) Secrets + deployment only: RTSP URL, dashboard host/ports/secret/site
zones.json Calibrated pallet / truck / counting polygons + left/right limits (geometry only)
cfg/tracker.yaml FastTrack/ByteTrack occlusion tuning (buffer 60, re-ID windows)

See docs/configuration.md for every variable.

Dashboard (counter_dashboard.py, port 5000 / office 5721)

Pages in templates/: monitoring.html, operator.html (batch start/stop; DO panel in do_manual), history.html, analytics.html. JSON APIs under /api/* (live video MJPEG, current/previous batch, summary, daily data, batch mode, DO upload/staged/settings, CSV/Excel export). Data source: jetson_counter.db + current_batch.json + batch_mode.json (batch flow: auto | do_manual | manual; model mode in config.yaml).

Batch modes

Mode Who opens/closes batch DO gate
auto (default) AI truck FSM —
do_manual Operator + DO photo scan yes
manual Operator buttons (legacy) no

Office (:5721) switches mode / model mode / require_plate / ocr_engine (403 on operator POST). DO manual flow: open http://<jetson>:5000/operator on a phone → Ambil Foto DO → review/edit OCR fields → Mulai Batch → count → Selesai (soft-warn if zone busy). Discard only when both sack and box nets are 0. ERD: ERD.md.

Repository layout

src/                  Shared library (streaming, detection, tracking, stabilizer,
                      truck_roi, counting, batch, dashboard, logger, config_loader, main)
config.yaml           Canonical config (stream/models/counting/batch/output/camera)
cfg/tracker.yaml      Tracker tuning
predict.py            Single entrypoint: production service + dev CLI (see --help)
counter_dashboard.py  Flask dashboard + APIs  |  templates/*.html  pages
tests/                Pytest smoke tests (counting, batch, config, config_loader)
archive/              Retired experiments (predict_new.py, rpo_iki/, simple_predict.py,
                      check/merge/test scripts) — history preserved, not imported
export_model.py       Export .pt → TensorRT .engine (FP16)  |  export_v4.py  variant
deploy_to_jetson.py   Paramiko sync + service restart
*.service             systemd units (counter, dashboard, mediamtx)
zones.json            Calibrated zone geometry
batch_history_folder/ Per-batch JSON reports
CHANGELOG.md          Release history (dated entries, Keep-a-Changelog style)

Script-by-script reference: docs/scripts.md.

Docs

S
Description
repo sc karung counting feedmill semarang
Readme
95 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 84.7%
HTML 15.3%