A comprehensive real-time surf monitoring application that combines computer vision, machine learning, and oceanographic data to provide live surf conditions and automated surfer detection.
- Frontend, Backend, & Scripts READMEs (way more detail)
- Overview
- Why Did I Build This?
- Features
- System Architecture
- Demo GIFs
- Custom Trained Computer Vision & Machine Learning Model in Action
- Technology Stack
- Project Structure
- Quick Start
- Configuration
- Computer Vision & Machine Learning Model Performance
- API Documentation
- Testing
- Deployment
- Contributing
- License
- Author
- Acknowledgments & References
For more comprehensive, specific, and thorough documentation on Frontend, Backend, and Scripts:
Surf Reporter is a full-stack web application designed to enhance surf monitoring through real-time buoy data metrics combined with computer vision and machine learning. The system processes HLS (HTTP Live Streaming) video from surf cameras worldwide, detects surfers using a custom-trained machine learning model, and integrates real-time wave data from CDIP (Coastal Data Information Program) buoys to provide comprehensive surf and wave conditions for users.
I built this personal project to grow my skills and knowledge in computer science and data science through something that feels close to home. As a UCSB student living in Isla Vista, California, surfing isn’t just a hobby; it’s woven into the community and daily life around me.
I’ve always noticed how popular companies like Surfline use live surf cameras and data to help surfers, but most of their features are hidden behind steep paywalls. I wanted to do something different: build my own application that taps into live surf cameras, leverages computer vision and machine learning, and keeps everything completely free and open for anyone to use.
This project became a way to blend what I’m passionate about, technology and surfing, into something real, useful, and shareable.
- Real-time surfer detection using custom computer vision models via Roboflow
- Live oceanographic buoy data from CDIP buoy network
- Multi-stream, concurrent video processing with automatic health monitoring
- Responsive web interface
- Professional-grade data visualization and analytics
- Custom-Trained Model: Purpose-built surfer detection algorithm with 65.4% mAP@50, 69.3% precision, 63.9% recall
- Real-Time Processing: Live inference and optimized frame processing on multiple live video streams simultaneously
- Roboflow Integration: Cloud-based machine learning pipeline for scalable object detection and classification
- Automated Health Monitoring: Automatic stream processing with error handling, recovery, and logging
- Live Buoy Data: Real-time wave conditions from CDIP THREDDS servers accessed via OPenDAP
- Comprehensive Data Metrics: Wave height, peak period, direction, average period, zero-crossing period, and peak PSD (Power Spectral Density)
- Data Quality Validation: Automatic filtering of invalid, corrupted, and weak data points
- Historical Data Analysis: Time series data processing and trend analysis on varying data metrics
- Responsive Design: Optimized for desktop, tablet, and mobile devices
- Accessibility Features: Scalable fonts (80%-150%), high contrast ratios, and dark/light theme
- Real-Time Updates: Live data refresh with configurable intervals
- Interactive Visualizations: Professional charts and data presentations
┌─────────────────────────────────────────────────────────────────┐
│ React Frontend │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Dashboard │ │ Settings │ │ About │ │
│ │ Page │ │ Page │ │ Page │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │Video Panel │ │Wave Data │ │Chart Panel │ │
│ │ │ │Panel │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────┼───────────────────────────────────────┘
│ RESTful API
┌─────────────────────────┼───────────────────────────────────────┐
│ Flask Backend │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │Video │ │Surf Data │ │Frontend │ │
│ │Analysis │ │Routes │ │Routes │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │LiveStream │ │CDIP THREDDS │ │
│ │Analyzer │ │Integration │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────┼───────────────────────────────────────┘
│
┌─────────────────────────┼───────────────────────────────────────┐
│ External Services │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │HLS Streams │ │Roboflow API │ │CDIP Buoys │ │
│ │(Surf Cams) │ │(ML Model) │ │(Wave Data) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Dashboard
Settings Page & About Page
- React: Modern hooks-based architecture with functional components
- JavaScript: ES6+ features and best practices
- CSS: Custom properties, responsive and flexible layouts, dual theme support
- Recharts: Professional data visualization library
- Custom Hooks: Reusable logic for data fetching and state management
- Python: Primary programming language
- Flask: Lightweight web framework optimized for API services
- FFmpeg: Professional video stream processing, conversion, and frame extraction
- OpenCV: Computer vision library for image processing and analysis
- ML & CV Inference: Real-time object detection via Roboflow InferencePipeline
- Threading: Concurrent processing for multiple streams
- Roboflow: Cloud-based object detection and classification platform
- Custom Computer Vision Pipeline: Purpose-built, custom surfer detection algorithm
- Real-time Inference: Live model inference on live video streams
- Performance Optimized: Efficient frame processing and analysis
- xarray: Multi-dimensional array processing for NetCDF data
- pandas: Data manipulation and time series analysis
- NumPy: Numerical computing and array operations
- OPeNDAP: Direct integration for CDIP THREDDS data server
backend/
├── analysis/
│ ├── live_stream_analyzer.py
│ └── roboflow_utils.py
├── routes/
│ ├── frontend.py
│ ├── surf_data.py
│ └── video_analysis.py
├── .env
├── .gitignore
├── app.py
├── backend_tests.py
├── config.py
├── requirements.txt
└── webcam_configs.py
frontend/
├── node_modules/
├── public/
│ ├── videos/
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src/
│ ├── components/
│ │ ├── About_Page.js
│ │ ├── Chart_Panel.js
│ │ ├── Dashboard_Page.js
│ │ ├── Historical_Data_Panel.js
│ │ ├── Settings_Page.js
│ │ ├── Video_Panel.js
│ │ └── Wave_Data_Panel.js
│ ├── constants/
│ │ ├── Buoy_Options.js
│ │ └── Webcam_Options.js
│ ├── hooks/
│ │ ├── useVideoData.js
│ │ └── useWaveData.js
│ ├── utils/
│ │ ├── getCurrentWaveData.js
│ │ └── prepareChartData.js
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ └── index.js
├── logo.svg
├── reportWebVitals.js
├── setupTests.js
├── .gitignore
├── package.json
├── package-lock.json
├── postcss.config.js
└── README.md
scripts/
├── CV_pipeline_TEST.py
├── CV_pipeline_TEST2.py
├── frame_extraction.py
└── README.md
- Python 3.8 or higher
- Node.js 16 or higher
- FFmpeg installed and accessible in PATH
- Roboflow API key and workspace access
- Sufficient hardware for concurrent stream processing
-
Clone the repository
git clone https://github.com/RyanFabrick/ML-CV-Surf-Forecast.git cd ML-CV-Surf-Forecast -
Backend Setup
cd backend python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt # Configure environment variables cp .env.example .env # Edit .env with your Roboflow credentials
-
Frontend Setup
cd ../frontend npm install -
Start the Application
# Terminal 1 - Backend cd backend python app.py # Terminal 2 - Frontend cd frontend npm start
-
Access the Application
- Frontend: http://localhost:3000
- Backend API: http://localhost:5000
The application requires several environment variables to be configured for proper operation. These variables handle external service integration, API authentication, and system behavior.
Create a .env file in the backend/ directory with the following variables:
# Roboflow API Configuration
ROBOFLOW_API_KEY=your_roboflow_api_key_here
ROBOFLOW_WORKSPACE=your_workspace_name
ROBOFLOW_WORKFLOW_ID=your_workflow_id
# Flask Application Settings
FLASK_ENV=development
FLASK_DEBUG=True
API_PORT=5000
# Stream Processing Configuration
FFMPEG_TIMEOUT=30
MAX_CONCURRENT_STREAMS=5
FRAME_RATE=1ROBOFLOW_API_KEY
- Purpose: Authentication key for accessing Roboflow's machine learning inference services
- Why needed: Enables real-time surfer detection through the custom-trained computer vision model
- How to obtain: Sign up at Roboflow, create a workspace, and generate an API key from your account settings
ROBOFLOW_WORKSPACE
- Purpose: Identifies your specific Roboflow workspace containing the trained model
- Why needed: Directs API calls to the correct model deployment environment
- Format: Usually your username or organization name
ROBOFLOW_WORKFLOW_ID
- Purpose: Specifies the exact workflow/model version to use for inference
- Why needed: Ensures consistent model performance and version control
- How to obtain: Found in your Roboflow project dashboard under workflow settings
FLASK_ENV
- Purpose: Sets the Flask application environment mode
- Default:
development - Options:
development,production,testing
FLASK_DEBUG
- Purpose: Enables/disables Flask debug mode for development
- Default:
Truefor development - Production: Set to
Falsefor production deployments
API_PORT
- Purpose: Specifies the port for the Flask backend server
- Default:
5000 - Note: Ensure this port is available and not blocked by firewall
FFMPEG_TIMEOUT
- Purpose: Maximum time (seconds) to wait for FFmpeg stream processing
- Default:
30 - Why needed: Prevents hanging processes when streams are unavailable
MAX_CONCURRENT_STREAMS
- Purpose: Limits the number of simultaneous video streams processed
- Default:
5 - Why needed: Prevents resource exhaustion and maintains system stability
FRAME_RATE
- Purpose: Frames per second for video analysis processing
- Default:
1(one frame per second) - Why needed: Balances detection accuracy with computational efficiency
The application automatically connects to CDIP (Coastal Data Information Program) THREDDS data server via OpenDAP protocol. No additional configuration is required for buoy data access.
Supported Buoy Networks:
- Real-time oceanographic data from 100+ CDIP buoys
- Automatic data quality validation and filtering
- Historical data access for trend analysis
Stream URLs are preconfigured in backend/webcam_configs.py. The application supports HLS (HTTP Live Streaming) sources from:
Default Sources:
- The Surfers View camera network
Adding Custom Streams:
# In webcam_configs.py
WEBCAM_CONFIGS = {
'custom_location': {
'name': 'Custom Surf Spot',
'url': 'https://your-hls-stream-url.com/playlist.m3u8',
'location': 'Custom Location, State'
}
}Hardware Requirements:
- CPU: Sufficient enough for multiple, concurrent stream processing
- RAM: Sufficient enough for multiple, concurrent stream processing
- Storage: Recommended 2GB free space for dependencies and temporary files
- Network: Stable broadband connection
Software Dependencies:
- FFmpeg: Required for video stream processing and format conversion
- Python: Version 3.8 or higher
- Node.js: Version 16 or higher for frontend development
After configuration, verify your setup:
# Test backend configuration
cd backend
python -c "from config import Config; print('✓ Backend configuration loaded')"
# Test Roboflow API connection
python -c "from roboflow import Roboflow; rf = Roboflow(api_key='your_key'); print('✓ Roboflow connected')"
# Test FFmpeg installation
ffmpeg -version
# Start application
python app.py- Never commit
.envfiles to version control - Use environment-specific configurations for development/production
- Rotate API keys regularly for security
- Restrict API key permissions to minimum required scope
- Use HTTPS in production for secure data transmission
Common Issues:
- Missing API Key: Ensure ROBOFLOW_API_KEY is set and valid
- Stream Connection Failures: Verify internet connectivity and stream URLs
- FFmpeg Errors: Confirm FFmpeg is installed and accessible in PATH
- Port Conflicts: Ensure configured ports (5000, 3000) are available
My custom-trained computer vision model on Roboflow achieves the following metrics:
- mAP@50: 65.4%
- Precision: 69.3%
- Recall: 63.9%
- Training Dataset: 200+ annotated surf images
- Real-time Processing: Configurable FPS (frames per second) on live streams
GET /api/video-analysis?webcam_id=<webcam_id>Returns real-time surfer detection results with confidence scores and stream status.
GET /api/surfdata?buoy_id=<buoy_id>Fetches comprehensive oceanographic data from CDIP buoy networks.
GET /video_feed/<webcam_id>Streams processed video feed with ML overlay (MJPEG format).
cd backend
python -m pytest tests/ -v --cov=. --cov-report=htmlcd frontend
npm test# Backend
cd backend
docker build -t surf-reporter-backend .
docker run -p 5000:5000 surf-reporter-backend
# Frontend
cd frontend
docker build -t surf-reporter-frontend .
docker run -p 3000:3000 surf-reporter-frontend- Load balancing for multiple backend instances
- SSL/TLS configuration
- Resource monitoring and scaling
- Health check endpoints
- Automated backup and recovery
This project was developed as a personal learning project. For future questions and/or suggestions:
- Open an issue describing the enhancement or bug
- Fork the repository and create a feature branch
- Follow coding standards
- Write tests for new functionality
- Update documentation as needed
- Submit a pull request with detailed description of changes
This project is open source and available under the MIT License.
Ryan Fabrick
- Statistics and Data Science (B.S) Student, University of California Santa Barbara
- GitHub: https://github.com/RyanFabrick
- LinkedIn: www.linkedin.com/in/ryan-fabrick
- Email: [email protected]
- CDIP (Coastal Data Information Program) - Buoy oceanographic data source
- The Surfers View - Live surf camera feed provider
- Roboflow - Computer vision and machine learning model training infrastructure
- FFmpeg - Professional video stream processing and frame extraction capabilities
- Flask Community - Excellent web framework
- React Community - Super helpful and clear documentation
Built with ❤️ for the surfing community
This personal project demonstrates my full-stack development skills, machine learning and computer vision integration, real-time data processing, and modern web technologies and development. I designed this as a portfolio piece showcasing my technical capabilities across multiple domains.




