jetson 07289a419a perf: throttle tracker to every 2nd frame, sup interval 10, 720p output option
- detect_interval=2 on both pipelines; stabilizer 10-frame hold bridges
  skipped frames (GPU inference cut ~half during active batch)
- sup_det_interval 5 -> 10 (still <= stabilizer hold / synthetic max_age)
- preview_every_n default 2 -> 5
- AnnotatedVideoWriter: codec auto-chain gstreamer_nvenc -> avc1 -> mp4v,
  max_height downscale (even dims, INTER_AREA); backend logged
- output_max_height plumbed Job -> web checkbox (720p) -> CLI --output-height
- README: 720p option, CLI flag
- 153 tests pass (+13)
2026-09-29 15:58:55 +07:00

Feedmill Recounter

AI video analysis tool for counting objects (sacks, boxes) in feedmill videos. Built on top of karung_counter_semarang.

Features

  • CLI: Process videos from the command line with any model + class filter
  • Web UI: Upload videos, select models, download annotated output on port 9050
  • Live Preview: MJPEG streaming — watch processing in real-time (15+ FPS at 640p)
  • Multiple Models: Run multiple model configurations on the same video for comparison
  • Model Groups: Models grouped by stem (e.g., best.pt, best.engine) with format dropdown
  • Class Filtering: Choose which classes to count (sack, box, truck)
  • Auto Truck Detection: Automatically loads truck-detector when selected model lacks truck class
  • Counting Zone Modes: Auto truck detection, fixed zone presets (zones.json), or auto-detect then freeze
  • Sack/Box Counts: Separate in/out counts per object class in results
  • Video Reuse: Re-analyze previously uploaded videos without re-uploading
  • Annotated Output: Download MP4 videos with detection overlays for human review
  • 720p Output Option: Downscale annotated MP4 to 720p for smaller files / faster encode
  • Async Processing: Background job queue — upload and poll status
  • Abort: Cancel running jobs mid-processing

Quick Start

pip install -e ".[dev]"

# List available models
recounter --list-models --models-dir ./models

# Process a single video via CLI
recounter --video input.mp4 --model v4-best.pt --filter sack --output-dir ./output

# Start web UI
recounter-web
# Open http://localhost:9050

CLI Reference

recounter --video PATH          Input video file
         --model NAME           Model filename (repeatable for multiple)
         --all-models           Run all discovered models
         --list-models          List available models and exit
         --filter NAME          Class filter (repeatable): sack, box, truck
         --sack-conf FLOAT      Sack confidence threshold (default: 0.4)
         --truck-conf FLOAT     Truck confidence threshold (default: 0.5)
         --output PATH          Output path (single model only)
         --output-dir DIR       Output directory (default: ./output)
         --output-height INT    Downscale annotated output to this height (e.g. 720)
         --models-dir DIR       Models directory (default: ./models)

Web UI

  • Port: 9050 (configurable via WEB_PORT env)
  • Upload: Drag-and-drop or click to upload video, or select from previously uploaded videos
  • Model Selection: Grouped cards with format dropdown (.engine / .pt / .onnx) and class filter
  • Live Preview: Real-time MJPEG stream during processing
  • Job Status: Auto-refreshing progress page with abort button
  • Download: Annotated MP4 per model result

API Endpoints

Endpoint Method Description
/ GET Upload form with model groups
/upload POST Start processing job
/upload/reuse POST Re-analyze an existing uploaded video
/status/<job_id> GET Job status with results
/jobs GET All jobs listing
/download/<job_id>/<filename> GET Download output video
/preview/thumb/<job_id> GET Thumbnail JPEG for a job's video
/api/preview/<job_id> GET MJPEG live stream during processing
/api/models GET List model groups (JSON)
/api/videos GET List uploaded videos (JSON)
/api/videos/<filename> DELETE Delete an uploaded video
/api/jobs GET List all jobs (JSON)
/api/jobs/<job_id> GET Job detail (JSON)
/api/jobs/<job_id>/cancel POST Cancel a running job
/api/jobs/<job_id>/samples GET Sample frame paths (JSON)

Configuration

Variable Default Description
WEB_HOST 0.0.0.0 Flask bind address
WEB_PORT 9050 Flask port
FLASK_DEBUG false Flask debug mode
MODELS_DIR ./models Model weights directory
UPLOAD_DIR ./uploads Uploaded videos directory
OUTPUT_DIR ./output Annotated output directory

Project Structure

src/
├── interfaces.py         # Detection dataclass + protocols
├── detection.py          # YOLO detectors with class filtering
├── tracking.py           # ByteTrack/FastTrack tracker
├── synthetic_track.py    # Synthetic IDs for untracked detections
├── stabilizer.py         # Bbox smoothing + occlusion hold
├── truck_roi.py          # Truck ROI detection + EMA smoothing
├── zone_config.py        # Fixed-zone presets (zones.json) + scaling
├── counting.py           # Line-crossing counter
├── batch.py              # Batch lifecycle state machine
├── dashboard.py          # Frame annotation overlay
├── video_writer.py       # Annotated video writer
├── model_registry.py     # Model discovery, grouping, class metadata
├── pipeline.py           # Video processing pipeline
├── preview.py            # Video probing, thumbnails, sample frames
└── job.py                # Async job queue

Model Formats

Models are grouped by stem name. Each group has available formats:

Format Extension Speed Notes
TensorRT .engine Fastest Preferred on Jetson (GPU-optimized)
PyTorch .pt Medium Works everywhere
ONNX .onnx Medium Requires onnxruntime (not available on Jetson)

Format preference order: .engine > .pt > .onnx

Truck Detection

The pipeline requires truck detection to start counting. If the selected model lacks a "truck" class (e.g., best.engine which only has "sack"), the system automatically loads the truck-detector model for truck detection.

Models with "truck" class: v4-best, model_karung_truk Models without "truck" class: best, karung-dimuat, yolo11n-bbox (auto-loads truck-detector)

Counting Zone

The web upload form offers three zone modes:

  • Auto-detect Truck (default): truck detector finds the main truck each ~15 frames, ROI + counting line follow it (EMA-smoothed with 10px deadband, sticky truck pick)
  • Fixed Zone: static zone from zones.json presets, scaled from reference resolution to video resolution; never moves; presets editable via tools/calibrate_zone.py
  • Auto-detect + Freeze: auto-detects the truck then locks the ROI permanently after 3 consecutive detections (geometry fixed, truck-presence still tracked for batch state machine)

In multi-model runs, model #1 (primary, alphabetical order) is tracked every frame; supplementary models run every 5th frame; detections from supplementary models get synthetic track IDs so counts and overlays stay stable.

S
Description
Multi model AI counter with class filtering for feedmill recounting
Readme
583 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 72.1%
HTML 11.7%
JavaScript 8.6%
CSS 7.6%