ESP32-S3 CAM

3D Printer Monitor // Dead Pixel Correction

Project Overview

A camera streaming project for monitoring 3D prints with integrated LED strip control, featuring advanced client-side post-processing that fixes dead pixels in real-time without any firmware modifications.

The Breakthrough: We achieved O(1) per-frame complexity for dead pixel correction—meaning performance is constant regardless of image resolution. A 6,000x improvement over the naive approach.

This document chronicles the engineering journey from "there's a white dot on my camera" to a sophisticated real-time image processing pipeline running entirely in your browser.

Hardware Specifications

Component Model / Specification
Microcontroller ESP32-S3 WROOM N16R8 (16MB Flash, 8MB PSRAM)
Camera Sensor OV5640 (5 Megapixel CMOS)
LED Strip WS2812B on GPIO 14
Interface MJPEG over HTTP
Max Resolution 1024x768 (XGA)
Frame Rate ~15-30 FPS depending on quality

Pin Configuration

Function GPIO
XCLK 15
SIOD 4
SIOC 5
D0-D7 11, 9, 8, 10, 12, 18, 17, 16
VSYNC 6
HREF 7
PCLK 13
LED Data 14

Features

Camera & Streaming

  • MJPEG Video Streaming  EReal-time camera feed
  • mDNS Discovery  EAccess via http://3DprinterCam.local
  • Glassmorphism Web UI  EModern, beautiful interface
  • Resolution selection (QVGA to UXGA)
  • Special effects (Negative, Grayscale, Sepia, etc.)

Advanced Post-Processing (Browser-side)

  • Dead Pixel Fix (V7)  EOptimized cached removal of sensor defects
  • Temporal Smoothing  EReal-time noise reduction
  • Live Enhancements  EBrightness, Contrast, and Saturation
  • Algorithm selection (Median, Average, Minimum)
  • Adjustable detection radius (1-15px)
  • Real-time detection map visualization

LED Strip Control

  • Power on/off toggle
  • LED count configuration (1-300)
  • HTML5 color picker
  • Brightness slider (0-100%)

The Dead Pixel Fix Algorithm

Cheap camera modules—like the OV5640 commonly paired with ESP32-S3 boards—often have manufacturing defects. These "hot pixels" are permanently stuck at a bright color.

The Challenge: How do you fix individual broken pixels in a live video stream without modifying the ESP32 firmware or requiring a powerful backend server?

The Naive Approach (Why It Fails)

A 640x480 frame has 307,200 pixels. At 30 FPS, scanning every pixel means 9.2 million checks per second. With ~20 operations per pixel, that's 180+ million operations per second. Your browser freezes.

The Evolution: 7 Versions

V1: Absolute Threshold

If brightness > 250, it's dead. Failed  Edead pixels aren't always pure white.

V2: Vertical Line Fix

Use left/right neighbors for column defects. Failed  Eour defect was a 2x2 cluster.

V3: Immediate Neighbor Outlier

Compare to 8 immediate neighbors. Failed  EJPEG compression creates a "halo" around bright pixels.

V4: 2px Cluster Hop

Sample pixels 2px away. Partial success  Estill catching halo edges.

V5: 4px Jump-Median

Sample 8 neighbors at 4px, use median. Visual success! But performance destroyed.

V6: O(1) Caching Breakthrough

Key insight: Dead pixels don't move. Scan once, cache coordinates, fix only cached spots. 6,000x performance improvement.

V7: Management Suite

Full UI with algorithm selection, radius control, detection map, and recalibration.

The Final Solution

  • Scan once  EOn first frame, find all outlier pixels and cache their (x, y) coordinates.
  • Fix forever  EEvery subsequent frame, only process the ~10-50 cached pixels.
  • O(1) complexity  EProcessing time is constant regardless of image size.

Why O(1) Matters

Imagine you're a librarian asked to find typos in a book:

  • O(n): Read every word, every time. 100,000 words = 100,000 reads.
  • O(1): Read once, write down page numbers on a sticky note. Future requests? Just look at the note.

For video: O(n) means bigger images = slower. O(1) means 640x480 or 4K, same speed.

Thermal Anarchy: Heat Management

Silicon gets angry when it's hot. The ESP32-S3 and OV5640 are high-performance components squeezed into a tiny footprint. Without intervention, they generate enough heat to cause literal visual corruption.

The Pink Creep: As the sensor temperature climbs, a localized "pink aura" begins to bleed into the frame from the edges. Left unchecked, this thermal noise consumes the entire feed until the sensor either halts or sustained damage occurs.

Hard Lessons in Cooling

These modules are cheap, but their thermal overhead is steep. For stable 24/7 monitoring (like 40-hour 3D prints), active cooling or significant passive heat-sinking is mandatory. Failure to manage heat doesn't just ruin the image—it melts the thin plastic housing and kills the hardware.

In the world of cybernetics, heat is the ultimate enemy of uptime. If you don't sink it, you'll sink with it.

AliExpress Marketplace

Acquire the hardware components used in this project through the links below. Note: Always verify version numbers before purchase.

API Endpoints

Endpoint Method Description
/ GET Main web interface
/stream GET MJPEG video stream
/control?var=X&val=Y GET Camera control
/led/power?state=1/0 GET LED power toggle
/led/settings?count=X&color=RRGGBB&brightness=Y GET LED settings

Build & Upload

                    
                        # Using PlatformIO CLI
                        pio run --target upload
                        pio device monitor