Skip to content

Repository files navigation

Car Speed Detector (Flutter)

A test Flutter app that uses the phone camera to detect cars in real time (on-device TensorFlow Lite) and estimate their speed. Built for Android first, structured so an iOS clone is a small step (see iOS port plan below).

WARNING - Accuracy honesty: Speed from a single phone camera is an estimate, not a radar reading. It depends on calibration, camera angle, and steady framing. Treat results as approximate.

What it does

  • Live camera stream -> on-device object detection (SSD MobileNet v1, COCO).
  • Filters to vehicles (car, truck, bus, motorcycle).
  • Tracks each vehicle across frames (centroid tracker) and estimates km/h.
  • Draws bounding boxes + speed labels over the preview.
  • A calibration screen to set the pixel->meter scale.

Project layout

lib/
  main.dart                  app entry, camera enumeration
  models/
    recognition.dart         a detected box + label + score + track id
    calibration.dart         meters-per-pixel scale
  services/
    detector.dart            TFLite SSD MobileNet wrapper
    image_utils.dart         CameraImage (YUV/BGRA) -> RGB, resize, rotate
    tracker.dart             centroid tracker (assigns stable ids)
    speed_estimator.dart     pixel motion + calibration -> km/h (smoothed)
  screens/
    home_screen.dart         menu + permissions
    detection_screen.dart    live camera + inference loop + overlay
    calibration_screen.dart  mark a known distance to set the scale
  widgets/
    box_painter.dart         draws boxes + speed labels
assets/models/               put ssd_mobilenet.tflite here (+ labels.txt)
scripts/download_model.sh    fetches the model
android/app/src/main/AndroidManifest.xml  camera permission

Setup & run

You need the Flutter SDK (3.19+) and an Android device/emulator with a camera.

# 1. From the project root, generate the platform folders (android/ios/...).
#    This fills in Gradle files, MainActivity, etc. that aren't checked in here.
flutter create .

# 2. Get the model (~4 MB).
bash scripts/download_model.sh

# 3. Install dependencies.
flutter pub get

# 4. Apply the two Gradle tweaks in android/app/build.gradle.notes
#    (minSdkVersion 21 + noCompress 'tflite').

# 5. Run on a connected device (a real phone is best for the camera).
flutter run

If flutter create . overwrites AndroidManifest.xml, re-add the <uses-permission android:name="android.permission.CAMERA" /> line.

How speed estimation works

The camera only sees pixels moving, not meters. To turn pixel motion into km/h:

  1. Calibrate - on the calibration screen you mark a real-world distance you know (a lane is ~3.7 m, a sedan is ~4.5 m long). The app converts the marker separation into model-input pixels and computes meters-per-pixel.
  2. Track - each vehicle gets a stable id and a short history of center positions with timestamps.
  3. Estimate - speed = (pixelDisplacement * metersPerPixel) / deltaTime, converted to km/h and exponentially smoothed.

Why it's approximate (and how to improve it)

This is a planar / single-scale model. Sources of error:

  • Perspective: objects farther away move fewer pixels for the same real speed. One global meters-per-pixel is only right near the calibration line.
  • Camera angle: shots not perpendicular to traffic distort distances.
  • Square resize: frames are squashed to 300x300, mildly distorting motion.
  • Frame rate: low fps widens the time step and adds noise.

To improve: use a homography (map 4 known ground points to a top-down plane) instead of a single scale, mount the phone steadily, shoot perpendicular to traffic, and raise camera resolution/fps. Reference-grade speed needs stereo depth or a calibrated fixed camera.

Performance notes

  • Inference runs on the main isolate, throttled by a busy-flag (skips frames while one is processing). Simple and stable for a test app. For higher fps, move Detector.detect into a background Isolate and pass the interpreter address - listed in the roadmap.
  • ResolutionPreset.medium balances detection quality and speed.

iOS port plan

The app is already ~90% portable because the logic lives in Dart.

Area Android (now) iOS (clone)
Camera camera plugin, YUV420 same plugin; frames arrive as BGRA8888 - already handled in image_utils.dart
Inference tflite_flutter same package; bundle the same .tflite
Permissions manifest CAMERA add NSCameraUsageDescription to ios/Runner/Info.plist
UI / tracking / speed pure Dart unchanged

Steps to clone:

  1. flutter create . already scaffolds ios/. Open it once.
  2. Add to ios/Runner/Info.plist:
    <key>NSCameraUsageDescription</key>
    <string>Used to detect cars and estimate their speed.</string>
  3. Set the iOS deployment target to 12.0+ in Xcode (tflite_flutter needs it).
  4. iOS delivers bgra8888 frames, which ImageUtils.convertCameraImage already branches on.
  5. flutter run -d <ios device>.

No Swift/Kotlin platform code is required for the core features.

Roadmap / TODO

  • Move inference to a background isolate for higher fps.
  • Replace single-scale calibration with a 4-point homography.
  • Swap SSD MobileNet for YOLOv8n (update output decode + NMS).
  • Record clips with overlaid speed for later review.
  • Direction-aware speed (sign of motion, lane assignment).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages