RevelAI

Open source · MIT

Split album page scans into individual photos, then restore them with AI.

You photograph a page of a family album with your phone. The page holds five prints at different sizes and angles, and they are faded, yellowed and scratched. RevelAI separates them and — as a separate step that never touches your originals — restores them.

pip install revelai
revelai split ./album-pages -o ./photos
Run it from your browser How it works Works offline. No API key. Nothing leaves your machine.
On the left, one phone photograph of an album page holding four landscape prints on pale paper. On the right, the same four photographs separated into individual images, each straightened and cropped to its own border.
One photograph of a page in, four deskewed photographs out.

Two stages

Separating and restoring are different jobs, so they are different commands.

Either runs on its own, in whatever order you like. split never depends on enhance.

split

Takes photographs of album pages and returns each individual print, cropped and deskewed, with no quality loss whatsoever.

  • Exactly 1 resampling per photograph
  • Lossless PNG, source ICC profile preserved
  • 16-bit input stays 16-bit
  • Provenance written into the file's metadata

And what it does not do: no colour, brightness, contrast, saturation, sharpening or noise adjustment. It crops and deskews. That is the whole contract.

enhance

Takes separated photographs and returns restored versions, never touching the originals.

  • Classical correction first; a model only for what remains
  • Writes to a different folder, always
  • Filenames are preserved, so the two correspond
  • Records every operation and model version applied

Pointing the output at the input folder is an error, checked before any work starts. Your originals are the only copy nobody has altered.

Detection

Finding the photographs is easy. Finding their edges is the problem.

RevelAI fits one rotated rectangle to each print by line integral, scoring each edge by integrating the image gradient along the whole edge. That lets a long straight line — the real border of the print — outscore any short high-contrast detail inside the picture, and forcing a single rectangle stops one edge sliding onto a neighbouring photograph.
The detector's view of an album page: an orange outline around the page itself, green rectangles tightly around four correctly detected photographs, and a red rectangle around a fifth region that has been flagged for review.
Green is accepted, red is flagged for review, cyan is the crop after the safety inset, orange is the page. Written by --debug-dir.
IoU 0.994–0.997
against synthetic fixtures where the ground truth is exact
< 0.03° error
on the deskew angle
322 tests
all offline; none needs the network or an API key
Linux, macOS and Windows
on Python 3.10–3.13

Why a phone photograph is harder than a scan

Every other tool for this assumes a flatbed scanner with a uniform white background. On a phone photograph the page sits on a table, so the background is the darkest thing in the frame rather than the brightest, and a single global threshold segments the whole page as one object.

The light is uneven too, so the album paper is not one colour. RevelAI fits a smooth illumination surface to the paper first, so that “differs from the paper” means “differs from the paper here”.

Verification

Fifty pages produce two hundred crops. Nobody is going to check them by hand.

Without a check, the honest summary of such a run is “I processed fifty pages and I don’t know whether it came out right.” --verify asks a vision-language model one structured question about every crop, and turns that into something you can act on.
revelai split ./album --verify
Summary  pages read           50  photographs found    200  crops verified       196 of 200 passed      photo_00000042.png: cut off at the left      photo_00000078.png: more than one photograph in the crop  pages needing review 2 Re-run with --review to correct the flagged pages.

The model is asked to judge, never to change anything. Is this exactly one complete photograph? Is it cut off at any edge? Is there a leftover sliver of another photo, or of the page? Which way up is it?

If no API key is set, verification says so and the run continues. A batch that could not be checked is reported as unverified — never as passing.

A vision-language model judges and describes. It is not the thing that restores an image — that is a different kind of model entirely, and it lives in a different stage.

Restoration

Classical first. A model only for what is left.

Most of what is wrong with an old print is that its dye layers faded at different rates. That is a per-channel gain problem, and a per-channel gain fixes it — instantly, offline, deterministically, inventing nothing. On the test fixture it takes the grey deviation of a strongly cast print from 71 to 7, with no model involved.
Two versions of the same synthetic landscape photograph side by side. The left is heavily yellowed with a warm orange cast; the right has neutral greens and blues after classical colour correction.
Before and after classical colour correction. No model, no network, fully deterministic.

The order is the substance

  1. 1Classical colour correction
  2. 2Denoise
  3. 3Dust and scratch removal
  4. 4Colourisation (optional, off by default)
  5. 5Face restoration (optional, off by default)
  6. 6Super-resolution, last, always

Super-resolution goes last because it is a magnifier. Run it first and every defect still in the photograph gets magnified along with the picture.

Privacy

These are family photographs. That shapes the design.

It is not a footnote, and it is not a setting buried three menus deep.

Local by default

The local backend is the default and the whole tool works with no API key at all. Nothing uploaded, no account, no sign-up.

Hosted backends ask first

A hosted backend uploads your photographs to a third party. The first time one is used in a run, the tool says where the images are going and waits for a yes.

Verification is opt-in

--verify and --describe also send images, and they are off unless you ask for them. Only a downscaled copy is sent; the file on disk is never modified.

This website has no upload box, no analytics and no backend. It is a static site — there is nowhere for it to send an image even in principle.

Honest limitations

What it gets wrong, on the front page.

A restoration tool that only advertises its successes is not one you should trust with an album.

Face restoration reconstructs faces. It does not reveal them.

On a low-resolution photograph, the face that comes out may not be that person's face. The model produces a plausible face, not the one that was there.

Colourisation invents the colour.

The result is a plausible guess about what the scene might have looked like. It is not a record of it.

Detection fails on low-contrast pages.

A print faded to nearly the tone of the paper it is mounted on, on a page with a busy texture, may be missed or cropped short.

Prints that touch or overlap may come out as one crop.

Two photographs mounted edge to edge are separated only by a shadow line, and where one print is laid over another the union is an L shape whose borders belong to two different rectangles. Locally there is nothing in the image that says which.

Read all of them in full

Install

Three ways to get it.

The CLI ships through GitHub Packages as a container image, and as wheels attached to each release.

From PyPI

pip install revelai

Then revelai split ./album -o ./photos.

Container

docker run --rm -v "$PWD:/work" ghcr.io/maikotrindade/revelai split ./album

GitHub Packages has no Python registry, so the container registry is the GitHub Packages route.

From source

pip install -e packages/engine

Wheels are also attached to each GitHub Release.

Would rather not use a terminal?

revelai serve --open puts the same two stages behind a page you can point at a folder. It runs on your machine and the photographs still go nowhere — the run page explains exactly what talks to what.

Before you start

How to photograph album pages.

The quality of the input decides everything downstream. Five minutes of care here saves an hour of review later.

Indirect window light. No flash.

A flash puts a hotspot in the middle of the page and a hard reflection on any glossy print.

Phone parallel to the page.

RevelAI corrects rotation in the plane. It cannot undo perspective from a camera held off to one side.

Leave a margin.

Get the whole page in frame with room around it. A print that runs off the edge of the photograph cannot be cropped whole.

Dark, matte background.

A table works. This is what lets the page be found at all.

Half a page at a time.

Photographing half a page doubles the resolution of every print on it. If the album is worth digitising, it is worth two exposures per page.

Watch your own shadow.

Leaning over the page casts a soft-edged shadow across it. RevelAI rejects soft edges as shadows rather than borders, but it is better not to make it guess.

Prior art

Other tools solve part of this, and they are worth your attention.

All of them assume a flatbed scanner with a uniform white background, and none combines splitting with restoration. That is not a criticism — they are built for scans and they do that job.