Spaces:
Sleeping
Sleeping
| title: Fourier Faces | |
| emoji: π | |
| colorFrom: green | |
| colorTo: blue | |
| sdk: docker | |
| pinned: false | |
| # Fourier Epicycles | |
| Upload any image and watch it get redrawn by a bunch of spinning circles. | |
| --- | |
| ## How it works | |
| The pipeline has four stages: | |
| **1. Edge detection** β the image is converted to grayscale and run through OpenCV's Canny edge detector, which gives a binary map of all the boundaries. Up to 2000 edge points are sampled from this. | |
| **2. Point ordering** β the sampled edge points are unordered (just a cloud of dots). A nearest-neighbour traversal walks through them to produce a single connected path, which is what the Fourier transform will be applied to. | |
| **3. Spline fitting** β a parametric spline (scipy `splprep/splev`) is fitted to the ordered points to smooth out the jagged nearest-neighbour path and resample it uniformly in time. If spline fitting fails, it falls back to Gaussian smoothing. | |
| **4. Fourier transform** β the 2D curve is encoded as a complex signal `z = x + iy` and FFT'd. The N largest frequency components (by amplitude) are kept β these become the epicycles. Each circle's radius is the magnitude, its rotation speed is the frequency, and its starting angle is the phase. | |
| The frontend receives the `(magnitude, frequency, phase)` list and animates the epicycles in real time on an HTML canvas. | |
| --- | |
| ## What needs improvement | |
| The results are decent for cartoons and high-contrast images, but fall apart on real photos. Two core problems: | |
| **Edge detection is too sensitive** β Canny thresholds are fixed (`min=100, max=200`), so noisy or low-contrast images produce either way too many edges or almost none. These need to be adaptive, or at least exposed as user-controllable parameters.you could clone it locally and adjust it accordingly. | |
| **Point ordering is wrong** β nearest-neighbour traversal doesn't respect the actual contour structure of the image. It connects points that are spatially close but may be on completely different parts of the shape, creating messy crossing paths before the spline even gets involved. | |
| **Spline fitting doesn't respect curvature** β `splprep` connects all the points but doesn't understand the geometry of the shape. The result is rough and angular in places it should be smooth. BΓ©zier curves were tried and didn't help either. | |
| The real fix is probably to replace the entire edge-sampling + ordering + spline approach with a proper **single-stroke tracing algorithm** β something that generates one continuous outline of the image rather than a cloud of unordered edge pixels. I have been doing some research on single stroke tracing algorithm. If you have something to propose let me know. | |
| --- | |
| ## Run locally | |
| ```bash | |
| git clone https://github.com/Asthag29/Fourier_Transformation.git | |
| cd Fourier_Transformation | |
| uv venv | |
| uv pip install . | |
| uvicorn app:app --port 8000 |