Documentation

How to use the tool, how to run your own instance, and how the method works.

Using the tool

Take two photos of the same subject from the same position, one focused on the foreground, one on the background. The photos need to be of the same scene — if you move the camera between shots, the result won't align correctly.

Upload both on the main page, click Fuse photos, and download the result. JPEG, PNG, and WebP are supported up to 12MB each.

Photos are downsized in your browser to a maximum of 1600px on the long edge before anything is sent. This is not lossy in any meaningful way for focus-stacking — the algorithm works patch-by-patch and captures the relevant structural information well within this resolution — but it keeps the processing time to a few seconds rather than minutes.

Works best with:macro photography, product photography, any scene where you deliberately shot two focus points. Does not align images if they were shot from different positions — that's a separate problem (image registration) not handled here.

API

The fusion API is a separate open-source service (neutrofuse-api) built with FastAPI. This website calls it as a backend. You can call it directly from your own code.

POST /fuse

Fuse two images. Accepts a multipart/form-data body with two fields:

FieldTypeDescription
image_aFileFirst source image
image_bFileSecond source image

Returns the fused image as image/jpeg. On error, returns JSON:

{ "error": "Human-readable message" }

Example

curl -X POST https://your-api-host/fuse \
  -F "image_a=@photo_a.jpg" \
  -F "image_b=@photo_b.jpg" \
  --output fused.jpg

Self-hosting

Both halves of NeutroFuse are MIT-licensed and designed to be self-hosted. The backend API and the fusion algorithm are in neutrofuse-api; this frontend is in neutrofuse-web.

Backend (neutrofuse-api)

git clone https://github.com/YOUR_ORG/neutrofuse-api
cd neutrofuse-api
pip install -r requirements.txt
uvicorn app:app --host 0.0.0.0 --port 8000

Frontend (this repo)

git clone https://github.com/YOUR_ORG/neutrofuse-web
cd neutrofuse-web
npm install

# Create a .env.local file:
echo "NEUTROFUSE_API_URL=http://localhost:8000" > .env.local

npm run dev

For production deployment on Vercel:

  1. Fork or clone this repo to your GitHub account.
  2. Import the repo in the Vercel dashboard.
  3. Set the environment variable NEUTROFUSE_API_URL to the URL of your deployed API service.
  4. Deploy.
The API must be a separate, persistent service — it runs Python/OpenCV, which does not fit Vercel's serverless runtime. Options include Render, Railway, Fly.io, or any VPS. The frontend calls it via the /api/fuse route handler, which proxies the request and enforces size limits and timeouts.

How it works

The full methodology, evaluation, and results are in the research report. A summary:

Neutrosophic confidence

Each 8×8-pixel patch in each source image gets a Truth (T), Indeterminacy (I), and Falsity (F) score derived from local Laplacian-variance sharpness. T is how confident we are this patch is in-focus; I is how undecidable the choice between A and B is. A log-compression step prevents the heavy-tailed sharpness distribution of real photographs from collapsing every patch's confidence near zero.

Hypergraph construction

Patches with similar texture (LBP + gradient-orientation feature vectors) are connected into hyperedges within a local spatial radius. This is the 'neighborhood' the ambiguous patches vote against.

Decision rule

Low-I patches: direct comparison of T_A vs T_B. High-I patches: aggregated vote across the hyperedge, weighted by hyperedge confidence. This defers genuinely ambiguous decisions to structural context rather than guessing.

Smooth composition

The per-patch blend weights are upsampled to pixel resolution using bilinear interpolation between patch centers (not nearest-neighbor), eliminating the blocky artifact that would otherwise be visible at curved edges crossing a sharp/blurred boundary.

Limitations

    No image alignment

    Both photos must be taken from the same position with the camera on a tripod or stable surface. NeutroFuse does not perform image registration. If the photos are misaligned, the fused result will show ghosting.

    Best under 1600px

    The algorithm was evaluated on 520×520 Lytro pairs. Images are downsized client-side to 1600px before processing. Very large images take longer and the patch-level parameters may not be optimally tuned for them.

    Sharpness assumption

    The method assumes at least one of the two sources is sharper than the other at each patch. Scenes where both sources are equally soft everywhere (e.g. both underexposed or both heavily compressed) won't benefit.

    Spatial Frequency tradeoff

    Statistical evaluation on 20 real pairs found that the hyperedge-aggregation mechanism improves edge-preservation quality (Qabf) and information retention (MI) but reduces raw sharpness (Spatial Frequency) by a small, statistically significant amount on most pairs. The mechanism trades pixel-level sharpness at a few patches for better structural coherence — see the report for the mechanism.

Contributing

Contributions are welcome. The best place to start is the GitHub issues list — look for issues tagged good first issue or open a new one describing what you want to change before writing code.

The test suite (195 tests, 187 offline) covers most of the core method. Any change to the fusion pipeline should include updated tests and, where relevant, updated ablation results. The full research report documents the current baseline — changes that shift the headline numbers in either direction should explain why.

neutrofuse-api (the fusion algorithm) and neutrofuse-web (this site) are separate repos. Frontend issues go in neutrofuse-web; algorithm and API issues go in neutrofuse-api.

Licence

NeutroFuse is released under the MIT License. You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, provided the original copyright notice and this permission notice appear in all copies.

MIT License

Copyright (c) 2026 NeutroFuse Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.