Show AI denoise in the manual, on a night frame with no faces
A section after Looking closer: what it is for, the switch and its wait, Keep grain, which cameras it takes and where its noise figures come from. The scene opens the Brooklyn Bridge at ISO 8000 from the face-free demo set at 1:1, switches it on, waits for the result to land and keeps some grain, with a still before and after. It waits on the app's own log line rather than a fixed time: the network takes seconds on a GPU and more on the CPU, which is where the recording X server leaves it (13 s).
This commit is contained in:
@@ -63,6 +63,7 @@ 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 = {}
|
||||
@@ -841,6 +842,68 @@ def develop_zoom():
|
||||
pause(1.2)
|
||||
|
||||
|
||||
@scene(media=['develop-denoise.gif', 'develop-denoise-before.png', 'develop-denoise-after.png'],
|
||||
sources=DEVELOP_SRC + ['ui/dr-ui/src/develop/denoise.rs', 'core/dr-denoise/**',
|
||||
'core/dr-gpu/src/grain.rs', 'models/denoise/**'])
|
||||
def develop_denoise():
|
||||
"""A night frame at ISO 8000 at 1:1, AI Denoise switched on and landed,
|
||||
then some grain kept. Waits for the network rather than for a fixed
|
||||
time: on the CPU it takes several times what it does on a GPU."""
|
||||
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')
|
||||
shot('develop-denoise-before')
|
||||
rec('develop-denoise')
|
||||
pause(0.8)
|
||||
mark = log_size()
|
||||
dr.click(*denoise_switch())
|
||||
t0 = time.time()
|
||||
while time.time() - t0 < 300 and not denoise_landed(mark):
|
||||
pause(0.5)
|
||||
pause(1.5)
|
||||
shot('develop-denoise-after')
|
||||
slide('Keep grain', 60)
|
||||
pause(2.0)
|
||||
cut()
|
||||
undo_all()
|
||||
dr.move(*a)
|
||||
dr.x('click', '--repeat', 2, '--delay', 80, 1)
|
||||
pause(1.2)
|
||||
|
||||
|
||||
def denoise_switch():
|
||||
"""The `Apply` box under the AI Denoise heading — the lens profile's
|
||||
switch is also called Apply, so it is found by where it sits."""
|
||||
head = dr.matches('AI Denoise@Text', within=column())[0]
|
||||
below = [e for e in dr.matches('Apply@CheckBox', within=column()) if e['y'] > head['y']]
|
||||
e = min(below, key=lambda e: e['y'])
|
||||
return int(e['x'] + e['w'] / 2), int(e['y'] + e['h'] / 2)
|
||||
|
||||
|
||||
def log_size():
|
||||
try:
|
||||
return os.path.getsize(f'{dr.HOME}/app.log')
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
|
||||
def denoise_landed(since):
|
||||
"""The app has logged the result landing since `since` bytes into its
|
||||
log. The activity bar's progress has no name to wait on, and the time
|
||||
it takes is the device's — seconds on a GPU, more on the CPU."""
|
||||
try:
|
||||
with open(f'{dr.HOME}/app.log', 'rb') as f:
|
||||
f.seek(since)
|
||||
return b'learned denoise:' in f.read()
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
@scene(media=['develop-wb.gif'], sources=DEVELOP_SRC + ['ui/dr-ui/src/develop/white_balance.rs'])
|
||||
def develop_wb():
|
||||
at_develop()
|
||||
|
||||
Reference in New Issue
Block a user