A computer vision system that automatically reads analog pressure gauges using a Raspberry Pi camera. It captures images of physical gauges, detects the needle position, converts the angle to pressure values (PSI/BAR), and tracks readings over time with graphical analysis.
- Captures gauge images every 20 minutes using a Pi camera with LED lighting
- Detects the circular gauge face and needle position using OpenCV
- Calculates the needle angle and converts it to pressure (PSI/BAR)
- Stores readings in a SQLite database with timestamps
- Plots time-series graphs showing pressure trends over time
- Filters outlier readings automatically
Perfect for monitoring pressure systems, boilers, compressors, or any analog gauge that needs logging.
# Clone this repo, then deploy everything:
./deploy_to_pi.sh
# Or specify custom host:
PI_HOST=pi@raspberrypi.local ./deploy_to_pi.shThis script automatically:
- Installs all dependencies (uv, sqlite3, pigpio, libcamera)
- Copies all required files
- Configures and starts both services
- Verifies the deployment
# Process captured images and generate plots
uv run gauge_cli.py --plot --pressure-unit bar --average --all-time
# Remove outlier readings
uv run filter_large_angles.py --mark-as-failuresTwo systemd services work together:
-
dial_capture.service - Image capture
- Runs continuously, sleeps until next capture time
- Captures at :00, :20, :40 minutes past each hour
- Controls LED via GPIO for consistent lighting
- Saves JPEGs to
/home/jack/dial_images/
-
gauge_processor.service - Image processing
- Checks for new images every 5 minutes
- Processes images (10-20 min per image on Pi)
- Deletes processed images to save space
- Updates database and plots
- Load image and convert to grayscale
- Detect circular gauge using Hough circles
- Extract gauge region and apply threshold
- Detect needle using line detection
- Calculate angle from vertical (0-360°)
- Convert angle to pressure using calibration
- Store results in database
SQLite database (gauge_data.db) with two tables:
gauge_results- Successful readings (angle, pressure, timestamp)detection_failures- Failed detection attempts
Edit gauge_config.toml to adjust:
[gauge.detection]
binary_threshold = 140 # Image threshold for needle detection
min_radius = 100 # Minimum gauge size in pixels
max_radius = 1000 # Maximum gauge size in pixels
[gauge.pressure]
min_angle = 31 # Angle at 0 pressure
max_angle = 265 # Angle at max pressure
max_psi = 58
max_bar = 4.0# Check service status
ssh jack@pi4light "sudo systemctl status dial_capture.service gauge_processor.service"
# Watch live processing logs
ssh jack@pi4light "sudo journalctl -u gauge_processor.service -f"
# View recent readings
ssh jack@pi4light "sqlite3 gauge_data.db 'SELECT datetime(timestamp), angle, pressure_bar FROM gauge_results ORDER BY timestamp DESC LIMIT 10;'"
# Check disk space
ssh jack@pi4light "df -h /home/jack"Main processing tool with options:
--plot- Generate time-series plots--pressure-unit [angle|psi|bar]- Display units--time-window N- Days to include (default: 7)--all-time- Plot all historical data--average- Enable time-based averaging--average-period [minute|hour|day]- Averaging granularity--force- Reprocess all images
Outlier detection:
--threshold- Maximum valid angle (default: 200°)--mark-as-failures- Move outliers to failures table
For faster processing on a more powerful machine:
# Windows - Process images locally
.\read_it.ps1
# Windows - Sync database from Pi and view combined data
.\sync_from_pi.ps1
# Windows - Quick view of Pi's current plot
.\view_plot_from_pi.ps1
# Linux/Mac
scp jack@pi4light:./dial_images/*.jpg ./dial_images/
uv run gauge_cli.py --plot --pressure-unit bar --average --all-timeThe sync_from_pi.ps1 script:
- Downloads new readings from the Pi's database
- Merges with your local database (no duplicates)
- Regenerates plots with all historical data
- Opens the updated plot automatically
This allows you to maintain a complete historical record locally while the Pi continues to delete processed images to save space.
On Raspberry Pi:
- Images:
/home/jack/dial_images/ - Database:
/home/jack/gauge_data.db - Plots:
/home/jack/gauge_plots.png - Scripts:
/home/jack/ - Services:
/etc/systemd/system/
Processing seems stuck:
# Check if actively processing (high CPU usage is normal)
ssh jack@pi4light "ps aux | grep gauge_cli"
# Restart if needed
ssh jack@pi4light "sudo systemctl restart gauge_processor.service"No images being captured:
# Check capture service
ssh jack@pi4light "sudo systemctl status dial_capture.service"
ssh jack@pi4light "sudo journalctl -u dial_capture.service -n 50"Database errors:
# Install sqlite3 if missing
ssh jack@pi4light "sudo apt-get install -y sqlite3"- Image processing takes 10-20 minutes per image on Raspberry Pi
- CPU usage can reach 300%+ during processing (normal)
- Each image is ~1MB, processed images are deleted automatically
- Database and plots are retained indefinitely
deploy_to_pi.sh- Automated deployment scriptcapture_images.sh- Camera capture with LED controlcontinuous_gauge_processor.sh- Processing loopgauge_cli.py- Main image processing toolgauge_lib.py- Core detection algorithmsgauge_config.py- Configuration loadergauge_config.toml- User settingsfilter_large_angles.py- Outlier detectionsync_database_from_pi.py- Database synchronizationsync_from_pi.ps1- Windows script to sync and view dataview_plot_from_pi.ps1- Quick plot viewingread_it.ps1- Local image processing- Service files and installation scripts