A real-time webcam application that applies convolution filters using a 5x5 matrix. This project is designed as a stepping stone for learning WebAssembly (WASM) by starting with a pure JavaScript implementation that can be easily replaced with WASM.
- Real-time video processing using Canvas API
- Image data manipulation with
getImageData()andputImageData() - Convolution algorithm implementation
- Performance optimization techniques
- Clean function signatures designed for WASM interop
- Memory management patterns for image data
- Performance comparison between JS and WASM
- Gradual migration strategy from JS to compiled code
├── index.html # Main application UI
├── style.css # Styling
├── main.js # Application logic and webcam handling
├── convolution.js # Pure JS convolution implementation
└── README.md # This file
- Edge Detection: Sobel, Laplacian operators
- Blur Effects: Box blur, Gaussian blur
- Sharpening: Unsharp mask, high-pass filters
- Custom Effects: Emboss, outline, artistic filters
- Memory Layout: How image data is stored and accessed
- Algorithm Complexity: O(n²) operations on pixel data
- Browser Optimization: Canvas rendering pipeline
- Bottleneck Analysis: CPU vs GPU vs memory bandwidth
- Study the convolution algorithm in
convolution.js - Experiment with different kernel matrices
- Measure performance with browser dev tools
- Understand memory patterns and data flow
- Identify the hot path (convolution function)
- Understand the function signature and data types
- Learn about linear memory and pointer arithmetic
- Study how to pass image data between JS and WASM
- Choose your language (C, Rust, AssemblyScript)
- Set up the build toolchain
- Implement the convolution function
- Create JS bindings and memory management
- Compare performance with the pure JS version
- Add SIMD instructions for vectorized operations
- Implement larger kernel sizes (5x5, 7x7)
- Add multiple filter passes
- Experiment with different memory layouts
npm install
npm run devOpen your browser and:
- Start the webcam
- Modify the matrix values to see different effects
- Open browser dev tools to see performance metrics
Identity (no change):
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
Gaussian Blur (σ≈1.0):
1 4 6 4 1
4 16 24 16 4
6 24 36 24 6
4 16 24 16 4
1 4 6 4 1
(Divide by 256 for normalization)
Edge Detection (Laplacian 5×5):
0 0 -1 0 0
0 -1 -2 -1 0
-1 -2 16 -2 -1
0 -1 -2 -1 0
0 0 -1 0 0
Motion Blur (Diagonal):
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
(Divide by 5 for normalization)
Emboss (45°):
-2 -1 0 1 2
-1 0 1 2 1
0 1 2 1 0
1 2 1 0 -1
2 1 0 -1 -2
(Add offset +128 to bring values into visible range)
Sharpen (Un-sharp mask style):
0 0 -1 0 0
0 -1 -1 -1 0
-1 -1 25 -1 -1
0 -1 -1 -1 0
0 0 -1 0 0
- Use
requestAnimationFrame()for smooth rendering - Consider downscaling video for better performance
- Profile your code to find bottlenecks
- Understand when to use
ImageDatavs direct pixel manipulation
Once you're comfortable with the JavaScript implementation:
- Research WASM toolchains (Emscripten, wasm-pack, etc.)
- Learn about linear memory and how to share data
- Understand the performance characteristics of different approaches
- Experiment with SIMD and other optimization techniques
The goal is to replace the applyConvolution function in convolution.js with a WASM equivalent while keeping the same interface.