From f813014e80c2bc30428f878c7ec4ac9efae35a0b Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Thu, 8 Oct 2026 22:22:40 -0400 Subject: [PATCH] Show AI denoise in the manual on sharp, noisy frames The ISO 8000 Brooklyn Bridge frame was soft at 1:1 before any denoising, so it could not show that Best keeps detail. The section now shows five sharp frames from ISO 4000 to 16000, each at 1:1 where hard edges meet flat areas, Bilinear beside Best: a subway poster, a cathedral portal, a circus clock, a clinic sign and graffiti. Fast is described, not shown. at_develop opens a DNG when the name carries its extension. The scene now fails when Best never lands instead of capturing the undenoised frame twice. --- docs/manual/README.md | 17 ++-- docs/manual/index.html | 15 ++-- docs/manual/media/develop-denoise-best.png | 3 - .../manual/media/develop-denoise-bilinear.png | 3 - .../media/develop-denoise-clock-best.png | 3 + .../media/develop-denoise-clock-bilinear.png | 3 + docs/manual/media/develop-denoise-fast.png | 3 - .../media/develop-denoise-graffiti-best.png | 3 + .../develop-denoise-graffiti-bilinear.png | 3 + .../media/develop-denoise-portal-best.png | 3 + .../media/develop-denoise-portal-bilinear.png | 3 + .../media/develop-denoise-poster-best.png | 3 + .../media/develop-denoise-poster-bilinear.png | 3 + .../media/develop-denoise-sign-best.png | 3 + .../media/develop-denoise-sign-bilinear.png | 3 + tools/manual/scenes.py | 83 +++++++++++-------- 16 files changed, 98 insertions(+), 56 deletions(-) delete mode 100644 docs/manual/media/develop-denoise-best.png delete mode 100644 docs/manual/media/develop-denoise-bilinear.png create mode 100644 docs/manual/media/develop-denoise-clock-best.png create mode 100644 docs/manual/media/develop-denoise-clock-bilinear.png delete mode 100644 docs/manual/media/develop-denoise-fast.png create mode 100644 docs/manual/media/develop-denoise-graffiti-best.png create mode 100644 docs/manual/media/develop-denoise-graffiti-bilinear.png create mode 100644 docs/manual/media/develop-denoise-portal-best.png create mode 100644 docs/manual/media/develop-denoise-portal-bilinear.png create mode 100644 docs/manual/media/develop-denoise-poster-best.png create mode 100644 docs/manual/media/develop-denoise-poster-bilinear.png create mode 100644 docs/manual/media/develop-denoise-sign-best.png create mode 100644 docs/manual/media/develop-denoise-sign-bilinear.png diff --git a/docs/manual/README.md b/docs/manual/README.md index ab19b74..4d572c2 100644 --- a/docs/manual/README.md +++ b/docs/manual/README.md @@ -236,13 +236,18 @@ already used is quick. `Strength` eases it off: below 100 % it puts back some of what was removed, as grain without colour, for a picture that does not look too smooth. -The lamp and railing of a night frame at ISO 8000, at 1:1, by each method: +Five sharp photographs at high ISO, each at 1:1 where hard edges meet +flat areas, as the camera's ordinary conversion gives them and as `Best` +develops them. The grain goes from the flat paper, stone, canvas and paint; the +lines, the lettering and the carving keep their edges: -| Bilinear | Fast | -|---|---| -| ![The railing and the lamp at ISO 8000, as the camera recorded them](media/develop-denoise-bilinear.png) | ![The same, with the Fast network](media/develop-denoise-fast.png) | -| **Best** | | -| ![The same, with the Best network](media/develop-denoise-best.png) | | +| | Bilinear | Best | +|---|---|---| +| ISO 4000 | ![A subway poster's masthead at ISO 4000, at 1:1, as the camera recorded it](media/develop-denoise-poster-bilinear.png) | ![The same with Best](media/develop-denoise-poster-best.png) | +| ISO 8000 | ![The carving round a cathedral door at ISO 8000, at 1:1, as the camera recorded it](media/develop-denoise-portal-bilinear.png) | ![The same with Best](media/develop-denoise-portal-best.png) | +| ISO 12800 | ![A clock's numerals over a circus ring at ISO 12800, at 1:1, as the camera recorded it](media/develop-denoise-clock-bilinear.png) | ![The same with Best](media/develop-denoise-clock-best.png) | +| ISO 16000 | ![Lettering on a white panel at ISO 16000, at 1:1, as the camera recorded it](media/develop-denoise-sign-bilinear.png) | ![The same with Best](media/develop-denoise-sign-best.png) | +| ISO 16000 | ![Graffiti on a white wall at ISO 16000, at 1:1, as the camera recorded it](media/develop-denoise-graffiti-bilinear.png) | ![The same with Best](media/develop-denoise-graffiti-best.png) | It works on raw files from any camera with the usual colour pattern of red, green and blue squares — not on JPEGs, and not yet on Fujifilm's diff --git a/docs/manual/index.html b/docs/manual/index.html index 6f89d4d..599bf9c 100644 --- a/docs/manual/index.html +++ b/docs/manual/index.html @@ -315,11 +315,16 @@ or exported, does not wait a second time, and switching back to a method already used is quick. Strength eases it off: below 100 % it puts back some of what was removed, as grain without colour, for a picture that does not look too smooth.

-

The lamp and railing of a night frame at ISO 8000, at 1:1, by each method:

- - - - +

Five sharp photographs at high ISO, each at 1:1 where hard edges meet +flat areas, as the camera's ordinary conversion gives them and as Best +develops them. The grain goes from the flat paper, stone, canvas and paint; the +lines, the lettering and the carving keep their edges:

+
BilinearFast
The railing and the lamp at ISO 8000, as the camera recorded themThe same, with the Fast network
Best
The same, with the Best network
+ + + + +
BilinearBest
ISO 4000A subway poster's masthead at ISO 4000, at 1:1, as the camera recorded itThe same with Best
ISO 8000The carving round a cathedral door at ISO 8000, at 1:1, as the camera recorded itThe same with Best
ISO 12800A clock's numerals over a circus ring at ISO 12800, at 1:1, as the camera recorded itThe same with Best
ISO 16000Lettering on a white panel at ISO 16000, at 1:1, as the camera recorded itThe same with Best
ISO 16000Graffiti on a white wall at ISO 16000, at 1:1, as the camera recorded itThe same with Best

It works on raw files from any camera with the usual colour pattern of red, green and blue squares — not on JPEGs, and not yet on Fujifilm's diff --git a/docs/manual/media/develop-denoise-best.png b/docs/manual/media/develop-denoise-best.png deleted file mode 100644 index f014d50..0000000 --- a/docs/manual/media/develop-denoise-best.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d7b833d2b3ae0d1cdea29cb8a1a9286e365ff892809db25d34543fce40ce1d37 -size 245983 diff --git a/docs/manual/media/develop-denoise-bilinear.png b/docs/manual/media/develop-denoise-bilinear.png deleted file mode 100644 index 22cd96f..0000000 --- a/docs/manual/media/develop-denoise-bilinear.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3eb87a8ed459a5fc26935a3db6966f31788412b59df8820c4e589ca5745aba6d -size 616810 diff --git a/docs/manual/media/develop-denoise-clock-best.png b/docs/manual/media/develop-denoise-clock-best.png new file mode 100644 index 0000000..f94beb8 --- /dev/null +++ b/docs/manual/media/develop-denoise-clock-best.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e769aecab4b4ace46d55aced7bbac2bee7ed18e999a0b34a8b23daf8c89d4ff5 +size 249515 diff --git a/docs/manual/media/develop-denoise-clock-bilinear.png b/docs/manual/media/develop-denoise-clock-bilinear.png new file mode 100644 index 0000000..91fc329 --- /dev/null +++ b/docs/manual/media/develop-denoise-clock-bilinear.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8773fa933075ab90d872fb27e376c17b61466126cf56cf6d327b006eddd2fb57 +size 506723 diff --git a/docs/manual/media/develop-denoise-fast.png b/docs/manual/media/develop-denoise-fast.png deleted file mode 100644 index 74f7476..0000000 --- a/docs/manual/media/develop-denoise-fast.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65bb6527341429289f984bed5013e0140024eab71458931c11e278611c79c6f5 -size 282951 diff --git a/docs/manual/media/develop-denoise-graffiti-best.png b/docs/manual/media/develop-denoise-graffiti-best.png new file mode 100644 index 0000000..6011ed4 --- /dev/null +++ b/docs/manual/media/develop-denoise-graffiti-best.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96f200f76b263774af1768b43bf7d140f4ceb0241d4985df0ee9b206531006d6 +size 326047 diff --git a/docs/manual/media/develop-denoise-graffiti-bilinear.png b/docs/manual/media/develop-denoise-graffiti-bilinear.png new file mode 100644 index 0000000..4aa1b51 --- /dev/null +++ b/docs/manual/media/develop-denoise-graffiti-bilinear.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c9e5f007791d17cdbedc17971f5d44be9770faba574667d0eab1c5226091a2d +size 524103 diff --git a/docs/manual/media/develop-denoise-portal-best.png b/docs/manual/media/develop-denoise-portal-best.png new file mode 100644 index 0000000..658fdef --- /dev/null +++ b/docs/manual/media/develop-denoise-portal-best.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13090cbe083282698832206c35953b7f1dd44ae778d6afcedc1ffff12e0dd050 +size 255958 diff --git a/docs/manual/media/develop-denoise-portal-bilinear.png b/docs/manual/media/develop-denoise-portal-bilinear.png new file mode 100644 index 0000000..4dc24dc --- /dev/null +++ b/docs/manual/media/develop-denoise-portal-bilinear.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ef7528500e745b72f89be49468f0d29dcd27170d86b0b1fcf6e67ab5677dd83 +size 495026 diff --git a/docs/manual/media/develop-denoise-poster-best.png b/docs/manual/media/develop-denoise-poster-best.png new file mode 100644 index 0000000..2896b76 --- /dev/null +++ b/docs/manual/media/develop-denoise-poster-best.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e292733e17a81c17f09d7e8045f61b78687250075b61b6bd877c3b0d911e5af5 +size 183749 diff --git a/docs/manual/media/develop-denoise-poster-bilinear.png b/docs/manual/media/develop-denoise-poster-bilinear.png new file mode 100644 index 0000000..ed93847 --- /dev/null +++ b/docs/manual/media/develop-denoise-poster-bilinear.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bff075185c94cc900a69261e27b4c7c5c6d877cf4fe655548a14be20805178b +size 466928 diff --git a/docs/manual/media/develop-denoise-sign-best.png b/docs/manual/media/develop-denoise-sign-best.png new file mode 100644 index 0000000..6d6e39a --- /dev/null +++ b/docs/manual/media/develop-denoise-sign-best.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48889e40fb0c9422a345a0b7cef29c967d78f35e274b00b664aa96c35418a958 +size 186957 diff --git a/docs/manual/media/develop-denoise-sign-bilinear.png b/docs/manual/media/develop-denoise-sign-bilinear.png new file mode 100644 index 0000000..02146ad --- /dev/null +++ b/docs/manual/media/develop-denoise-sign-bilinear.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26a54f493f014cc86238a1d6347d9fefd3168f1d50f85ef075c7d1382367693a +size 575455 diff --git a/tools/manual/scenes.py b/tools/manual/scenes.py index 7ec6031..4389fc9 100755 --- a/tools/manual/scenes.py +++ b/tools/manual/scenes.py @@ -63,7 +63,6 @@ ALPS_SKY = '_MG_8330' # an upright alpine frame, its top third sky and clo TOWER = '_MG_8693' # towers shot looking up: verticals that converge ROAD = '_MG_8672' # a road under a sky, with marks on it: masks and repair ROAD_MARK = (0.305, 0.794) # a dark mark on its tarmac -DENOISE = '_MG_8862' # Brooklyn Bridge at ISO 8000: a lit railing, a lamp and a camera against the night # --- the registry ----------------------------------------------------------- SCENES = {} @@ -259,14 +258,17 @@ def cell_width(): def at_develop(photo=CHINATOWN): """`photo` open in develop, on the Photo tool, the All group, the - column at its top, and the edit as it was opened.""" - if dr.present('‹ Library@Button') and dr.present(f'{photo}.CR2'): + column at its top, and the edit as it was opened. A name without an + extension is a CR2.""" + stem, ext = os.path.splitext(photo) + name = photo if ext else f'{photo}.CR2' + if dr.present('‹ Library@Button') and dr.present(name): pass else: at_library() grid_top() - dr.click(*cell(photo)) - dr.wait_for(f'{photo}.CR2', 30) + dr.click(*cell(stem)) + dr.wait_for(name, 30) wait_canvas() for done in ('Done Composing', 'Done Masking', 'Done Repairing'): if dr.present(f'{done}@Button'): @@ -842,43 +844,52 @@ def develop_zoom(): pause(1.2) -# The methods in the order the scene visits them: `Best` is what the -# photograph opens with, then each smaller network, then none. -DENOISE_METHODS = ['Best', 'Fast', 'Bilinear'] -DENOISE_CLOSE_UP = 560 # pixels of canvas, square, around the lamp at 1:1 +# Sharp, noisy frames, each with a point on it at 1:1 where hard edges meet +# flat areas — where a denoiser either keeps the edge or smears it: a slug +# for its pictures, the file, and the point as fractions of the photograph. +DENOISE_FRAMES = [ + ('poster', '_MG_8953', (0.40, 0.31)), # ISO 4000: a subway poster's masthead, lines on paper + ('portal', '_MG_4762', (0.18, 0.22)), # ISO 8000: carving round a cathedral door, smooth stone + ('clock', '_MG_4810', (0.47, 0.39)), # ISO 12800: a circus clock's numerals on flat canvas + ('sign', 'IMG_2515.dng', (0.66, 0.52)), # ISO 16000: lettering and a swoosh on a white panel + ('graffiti', 'IMG_2041.dng', (0.695, 0.655)), # ISO 16000: ink lines and dots on a white wall +] +DENOISE_CLOSE_UP = 480 # pixels of canvas, square, around the point at 1:1 -@scene(media=[f'develop-denoise-{m.lower()}.png' for m in DENOISE_METHODS], +@scene(media=[f'develop-denoise-{slug}-{m}.png' for slug, _, _ in DENOISE_FRAMES + for m in ('bilinear', 'best')], sources=DEVELOP_SRC + ['ui/dr-ui/src/develop/denoise.rs', 'core/dr-denoise/**', 'core/dr-pipeline/src/learned_denoise.rs', 'models/denoise/**']) def develop_denoise(): - """The lit lamp and railing of an ISO 8000 night frame at 1:1, once per - AI Denoise method, each cut to the same square of the canvas. Waits for - each network rather than for a fixed time: on the CPU, which the demo - profile uses, Best takes several times what Fast does.""" - mark = log_size() - at_develop(DENOISE) - a = dr.photo(0.45, 0.55) # the lit lamp, the railing and the skyline over the water - dr.move(*a) - pause(0.3) - dr.x('click', '--repeat', 2, '--delay', 80, 1) - pause(1.5) - group('Detail') - in_column('AI Denoise@Text') - for method in DENOISE_METHODS: - if method != 'Best': - mark = log_size() - dr.click(*in_column(f'{method}@RadioButton')) - if method != 'Bilinear': - t0 = time.time() - while time.time() - t0 < 600 and not denoise_landed(mark): - pause(0.5) + """Each frame at 1:1 on its point, once as Best develops it — what a + raw opens with — and once by Bilinear, the camera's ordinary + conversion, cut to the same square of the canvas. Waits for the network + rather than for a fixed time: on the CPU, which the demo profile uses, + it takes many seconds.""" + for slug, photo, (fx, fy) in DENOISE_FRAMES: + mark = log_size() + at_develop(photo) + a = dr.photo(fx, fy) + dr.move(*a) + pause(0.3) + dr.x('click', '--repeat', 2, '--delay', 80, 1) pause(1.5) - close_up(f'develop-denoise-{method.lower()}', a) - undo_all() - dr.move(*a) - dr.x('click', '--repeat', 2, '--delay', 80, 1) - pause(1.2) + t0 = time.time() + while not denoise_landed(mark): + if time.time() - t0 > 600: + raise TimeoutError(f'{photo}: Best never landed') + pause(0.5) + pause(1.5) + close_up(f'develop-denoise-{slug}-best', a) + group('Detail') + dr.click(*in_column('Bilinear@RadioButton')) + pause(3.0) + close_up(f'develop-denoise-{slug}-bilinear', a) + undo_all() + dr.move(*a) + dr.x('click', '--repeat', 2, '--delay', 80, 1) + pause(1.2) def close_up(name, p, size=DENOISE_CLOSE_UP):