# Spatial Image Enhancer Pro Production-grade public SPA for spatial-domain image enhancement using Django REST Framework, OpenCV, NumPy, React, Tailwind CSS, Celery, Redis, PostgreSQL, Docker Compose, and Caddy. ![screenshot](./screenshot.png) ## Local Development Backend: ```bash cd backend python -m venv .venv .venv\Scripts\activate copy .env.sample .env pip install -r requirements.txt python manage.py migrate python manage.py runserver ``` Frontend: ```bash cd frontend copy .env.sample .env npm install npm run dev ``` Open `http://localhost:5173`. The frontend `.env` uses `VITE_API_BASE=http://localhost:8000`, and the backend `.env` allows that origin via CORS/CSRF settings. ## Docker ```bash copy .env.example .env copy backend\.env.sample backend\.env docker compose up --build ``` Caddy serves the SPA and proxies `/api/*` and `/media/*`. Set `CADDY_DOMAIN`, `DJANGO_ALLOWED_HOSTS`, `DJANGO_CSRF_TRUSTED_ORIGINS`, `CORS_ALLOWED_ORIGINS`, and a strong `DJANGO_SECRET_KEY` before production deployment. For production, use `.env.sample` as the root Compose template and `backend/.env.production.sample` as the backend-only template. ## Backend Structure The Django app follows the HackSoftware Django Styleguide pattern: - API views validate request input and return responses. - `processing/services.py` contains business workflows and writes. - `processing/selectors.py` contains database fetch helpers. - Settings are environment-driven through `backend/.env`. ## Algorithms The app is organized as a small MATLAB-like image workspace. Each operation creates a new image state, so you can compare results, keep useful steps, and delete unwanted states. ### Basic Workspace - **Histogram view** shows how pixel values are distributed. For gray images it uses one intensity histogram; for RGB images it also shows R, G, and B channels. Formula: `p(r_k) = n_k / n`. - **Histogram equalization** improves contrast by spreading gray levels using the cumulative histogram. Formula: `s_k = round(255 * CDF(r_k))`. - **Add images** combines registered images by summing pixels and clipping to display range. Formula: `g = f1 + f2`. - **Subtract images** highlights differences between registered images. Formula: `g = normalize(|f1 - f2|)`. - **Dot product** multiplies registered image pixels element by element. Formula: `g = normalize(f1 * f2)`. - **Average K images** reduces independent noise by averaging registered states. Formula: `g = (1/K) * sum(f_i)`. ### Chapter 3: Spatial Domain - **Negative** inverts intensities. Formula: `s = 255 - r`. - **Log transform** expands darker values more than brighter values. Formula: `s = c log(1 + r)`. - **Power-law / gamma** changes brightness and contrast with an exponent. Formula: `s = c r^gamma`. - **Gray-level dynamic range** stretches a selected intensity range to the full display range. Formula: `[low, high] -> [0, 255]`. - **Gray-level slicing** highlights pixels inside a chosen range. Formula: highlight where `A <= r <= B`. - **Bit-plane slicing** displays one binary bit of each gray value. Formula: `bit_k(r)`. - **Noise filter** adds test noise. Gaussian noise uses `g = f + n`; salt-and-pepper noise randomly sets pixels to `0` or `255`. - **Average N noisy copies** generates `N` independent Gaussian-noisy copies of the current image and averages them into one result. Formula: `result = (1/N) * sum_i(f + n_i)`. - **Periodic noise** adds a repeating sinusoidal row and column pattern. Formula: `g(x,y) = f(x,y) + A sin(2*pi*y/T) + A sin(2*pi*x/T)`. - **Average / box filter** smooths an image with a uniform mask. Formula: `g = imfilter(f, ones(K,K) / K^2)`. - **Weighted average filter** smooths with the slide mask `1/16 * [[1,2,1],[2,4,2],[1,2,1]]`. - **Gaussian filter** smooths using a Gaussian mask controlled by size `K` and variance `Q`. Formula: `G(x,y) = exp(-(x^2+y^2)/(2Q))`. - **Median filter** replaces each pixel with the neighborhood median, useful for salt-and-pepper noise. Formula: `g(x,y) = median(S_xy)`. - **Max filter** replaces each pixel with the local maximum. Formula: `g(x,y) = max(S_xy)`. - **Min filter** replaces each pixel with the local minimum. Formula: `g(x,y) = min(S_xy)`. - **Laplacian sharpening masks** use the taught cross or diagonal sharpening masks to emphasize fine detail. Formula: `g = imfilter(f, selected mask)`. - **Gradient operators** use Sobel or Roberts mask pairs for edges. Formula: `g = |imfilter(f,Gx)| + |imfilter(f,Gy)|`. - **High-boost / edge emphasis** sharpens by subtracting a blurred image from an amplified original. Formula: `f_hb = A f - blurred(f)`, where `A >= 1`. ### Chapter 4: Frequency Domain - **FFT/DFT spectrum view** shows magnitude, log magnitude, or phase of the image in the frequency domain. Formula: `F(u,v) = DFT{f(x,y)}`. Apply it to a periodic-noisy state with `log_magnitude` to see the noise peaks. - **Inverse FFT reconstruction** reconstructs from a previously saved FFT state. Formula: `f = real(ifft2(ifftshift(F)))`. ### Chapter 6: RGB Color Processing - **Convert to grayscale** uses configurable RGB weights, matching MATLAB-style luminance by default. Formula: `gray = 0.299R + 0.587G + 0.114B`. - **RGB channel view** displays one color channel as grayscale. Formula: show `R`, `G`, or `B`. ## API - `POST /api/images/` - `POST /api/process/` - `POST /api/batch/` - `GET /api/jobs/{job_id}/` Images are stored as ephemeral sessions and removed by the cleanup task after the configured TTL.