GitHub - carimura/speedcam-java
Exploration of automated speed detection in modern Java, starting with the OpenCV JNI bindings and then switching to the FFM API.
TODO
- Currently thinking offload to a Function compute service to parallelize across cloud compute.
- Front end CRUD site
Docker
The SpeedCam application is fully containerized using Ubuntu 22.04 with Java 21 and system OpenCV packages. All tests pass with motion detection results within ±10 frame tolerance.
Quick Start
# Build and run with sample videos docker build -t speedcam:latest . docker run --rm speedcam:latest
Building the Docker Image
docker build -t speedcam:latest .The Docker build:
- Uses Ubuntu 22.04 as base image
- Installs Java 21 OpenJDK and Maven
- Installs system OpenCV packages (
libopencv-dev,libopencv4.5-java) - Configures proper OpenCV Java library loading at
/usr/lib/jni/libopencv_java454d.so - Builds the application JAR with all dependencies
- Sets up proper entrypoint script for library detection
Running with Docker
Process Built-in Sample Videos
docker run --rm speedcam:latest
This processes all 8 sample videos and outputs motion detection results to console.
Process Your Own Videos
# Single video file docker run --rm -v /path/to/your/video.mp4:/app/input.mp4 speedcam:latest --in /app/input.mp4 # Directory of videos docker run --rm -v /path/to/your/videos:/app/videos speedcam:latest --in /app/videos/
With Database Integration
# Using docker-compose with PostgreSQL docker-compose up # Or run with custom database connection docker run --rm -e SUPABASE_PG_SPEEDCAM_PROD="your_db_connection_string" speedcam:latest
Docker Compose
The included docker-compose.yml provides a complete environment:
- SpeedCam application container with OpenCV integration
- PostgreSQL database for storing motion detection results
- Volume mounts for video files and persistent data
- Networking between services
- Environment variables for database configuration
# Start full environment docker-compose up # Run in background docker-compose up -d # View logs docker-compose logs speedcam # Stop environment docker-compose down
Docker Test Results ✅
All containerized tests PASSED with results within ±10 frame tolerance:
| Video | Target Frames | Docker Results | Status |
|---|---|---|---|
| 6-7-2025, 2.05.46pm | 61-178 | 64-179 | ✅ PASS |
| 6-7-2025, 2.09.59pm | 72-233 | 78-234 | ✅ PASS |
| 6-9-2025, 1.01.52pm | 74-196 | 77-198 | ✅ PASS |
| 6-9-2025, 9.57.54am | 44-162 | 48-164 | ✅ PASS |
| 6-7-2025, 2.39.30pm | 89-279 | 87-271 | ✅ PASS |
| 6-9-2025, 7.55.13am | 133-249 | 132-245 | ✅ PASS |
| 6-9-2025, 10.43.09am | 66-220 | 65-215 | ✅ PASS |
| 6-9-2025, 1.08.44pm | 165-351 | REJECTED* | ✅ OK |
*Video rejected due to excessive noise (91.3% early frame motion > 55% threshold)
Technical Notes
- OpenCV Java library:
libopencv_java454d.soloaded from/usr/lib/jni/ - Java version: OpenJDK 21 (preview features disabled for compatibility)
- Base image: Ubuntu 22.04 LTS
- All dependencies installed via system package manager for reliability
- Proper library path detection and configuration via entrypoint script
Local Development
Building Locally
mvn clean -Pcomplete package mvn clean -Pcomplete package -Dmaven.test.skip
Running Locally
# Process all sample videos java -cp ./target/speedcam-0.1-jar-with-dependencies.jar com.pinealpha.SpeedDetect --in src/main/resources/sample_videos/ # Process single video java -cp ./target/speedcam-0.1-jar-with-dependencies.jar com.pinealpha.SpeedDetect --in 'src/main/resources/sample_videos/Road Cam 6-7-2025, 2.05.46pm PDT - 6-7-2025, 2.05.46pm PDT.mp4'
Requirements for Local Development:
- Java 21+ (no preview features required)
- Maven 3.6+
- OpenCV 4.x with Java bindings
- macOS: Custom OpenCV build with
.dylibfiles - Linux: System OpenCV packages
Filename format
Road Cam 6-4-2025, 1.10.33pm PDT - 6-4-2025, 1.10.33pm PDT.mp4
Target Motion Results
- Road Cam 6-7-2025, 2.05.46pm --> motion frame range should be 61-178 left-to-right
- Road Cam 6-7-2025, 2.09.59pm --> motion frame range should be 72-233 left-to-right
- Road Cam 6-9-2025, 1.01.52pm --> motion frame range should be 74-196 left-to-right
- Road Cam 6-9-2025, 9.57.54am --> motion frame range should be 44-162 left-to-right
- Road Cam 6-7-2025, 2.39.30pm --> motion frame range should be 89-279 right-to-left
- Road Cam 6-9-2025, 7.55.13am --> motion frame range should be 133-249 right-to-left
- Road Cam 6-9-2025, 1.08.44pm --> motion frame range should be 165-351 right-to-left
- Road Cam 6-9-2025, 10.43.09am --> motion frame range should be 66-220 right-to-left
Testing
All videos
mvn clean test
Single video
mvn clean test -Dvideo.test.filter=right-to-left-2
Performance
Running all tests:
- Total time to run all tests: 1m 26s
- Average time per video (just the video): 8.7 seconds
Testing instructions for LLM
- We are going to build and run SpeedDetect across some known sample videos and compare the results we get to the "Target Motion Results" listed above
- The files we are going to process are all in /src/main/resources/sample_videos/
- After the full run, let's check the motion results for each one, and compare to the target motion results above. The first motion frame and last motion frame should be within 10 frames of the target results above. If they are, then we can consider that a passing test. If they are not, that is a failed test.
- A rejected video is OK, we won't call that a fail just a "SKIP"