diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..bf58c56 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +# Video processing +UPLOAD_DIR=./uploads +OUTPUT_DIR=./output +MODELS_DIR=./models + +# Web UI +WEB_HOST=0.0.0.0 +WEB_PORT=9000 +SECRET_KEY=change-me + +# Detection defaults +SACK_CONF=0.4 +TRUCK_CONF=0.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f380588 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Python +__pycache__/ +*.py[cod] +*.so +env/ +venv/ +.venv/ + +# Environment & state +.env +*.db + +# Media & outputs (gitignored per global constraints) +*.mp4 +*.avi +*.mkv +*.jpg +*.jpeg +*.png +output/ +uploads/ + +# TensorRT engines are Jetson build artifacts — rebuildable +*.engine + +# Model weights are reused from karung_counter_semarang and stay local +models/ + +# Test artifacts +.pytest_cache/ +.coverage + +# IDE & OS +.idea/ +.vscode/ +.DS_Store +Thumbs.db diff --git a/README.md b/README.md new file mode 100644 index 0000000..66cb955 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Feedmill Recounter + +AI video analysis tool for counting objects (sacks, boxes) in feedmill videos. +Built on top of [karung_counter_semarang](https://git.proit.id/andrew/karung-counting-feedmill-semarang). + +## Features + +- **CLI**: Process videos from the command line with any model + class filter +- **Web UI**: Upload videos, select models, download annotated output (port 9000) +- **Multiple Models**: Run multiple model configurations on the same video for comparison +- **Class Filtering**: Choose which classes to count (sack, box, truck) +- **Annotated Output**: Download MP4 videos with detection overlays for human review + +## Quick Start + +```bash +pip install -e ".[dev]" +recounter --list-models --models-dir ./models +recounter-web +# Open http://localhost:9000 +``` diff --git a/cfg/tracker.yaml b/cfg/tracker.yaml new file mode 100644 index 0000000..701328a --- /dev/null +++ b/cfg/tracker.yaml @@ -0,0 +1,26 @@ +# Custom FastTrack config tuned for sack counting: +# - track_buffer=60: hold lost tracks for 60 frames (~2.4s at 25fps) +# to survive worker occlusion +# - new_track_thresh=0.3: harder to spawn duplicate IDs +# - track_low_thresh=0.05: recover faint detections behind workers +# - active_occ_to_lost_thresh=15: tolerate 15 occluded frames +# - occ_reappear_window=60: re-find tracks after long occlusion +# - enlarge_bbox_occ=1.15: widen search region during occlusion + +tracker_type: bytetrack +track_high_thresh: 0.20 +track_low_thresh: 0.05 +new_track_thresh: 0.30 +track_buffer: 60 +match_thresh: 0.85 +fuse_score: true + +# Occlusion handling (FastTrack-specific) +reset_velocity_offset_occ: 5 +reset_pos_offset_occ: 3 +enlarge_bbox_occ: 1.15 +dampen_motion_occ: 0.4 +active_occ_to_lost_thresh: 15 +occ_cover_thresh: 0.6 +occ_reappear_window: 60 +init_iou_suppress: 0.65 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5c5ffd8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["setuptools>=68.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "feedmill-recounter" +version = "0.1.0" +description = "AI video analysis tool for counting objects in feedmill videos" +requires-python = ">=3.10" +dependencies = [ + "ultralytics", + "opencv-python", + "numpy", + "shapely", + "flask", + "python-dotenv", +] + +[project.optional-dependencies] +dev = ["pytest"] + +[project.scripts] +recounter = "cli:main" +recounter-web = "app:main" + +[tool.pytest.ini_options] +testpaths = ["tests"] diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29