Analysis and Generation of Visual Scenes with Deep Learning

The results of both modules. All figures are files in python_research/data/, regenerated with the current code (Module 1: 11 October 2026; the objects-in-hands demo: 13 October 2026; Module 2: 8 October 2026), on a laptop with an RTX 2060 (6 GB); the frames of the filmed demo (15 October 2026) are in images/python_app/demo/.

Module 1 – Action recognition

Five actions – falling, standing still ("idle"), lifting an object, sitting down, walking – learned from 50 clips of 5 seconds each (10 per action). Evaluated by 5-fold cross-validation, on clips unseen in training. The final model (an LSTM with the velocity of the points computed inside the network, a ~1.9 s time-sampled window) reaches 88.5% window accuracy, 94.0% clip accuracy, a macro F1 of 0.88 and an MCC of 0.86.

Metric (cross-validation)Initial model, 4 actionsFinal model, 4 actionsFinal model, 5 actions
Window accuracy78.4%84.2%88.5%
Clip accuracy (majority vote)80.0%87.5%94.0%
Macro F10.770.830.88
MCC0.710.800.86

The "idle" class (standing still, including with the hands held out, as when holding an object) also improved the other classes, because the model no longer has to fit stillness into an action; it has an F1 of 0.93 itself. On the live path (smoothing and the 60% threshold), on unseen clips, standing still is shown as "idle" 96% of the time and "uncertain" only 2%; 47 of the 50 clips are recognized correctly.

Confusion matrix
The confusion matrix (cross-validation, 5 actions). "Sitting" remains the hardest class (recall 70%, vs 53% without "idle"), confused with "falling" and "lifting_object": all of them end with the person down or bent over.
F1 per class
The F1 score of every action.

Live robustness test

The final model, tested live with the camera in 5 conditions, with timed trials (3 s to get into position, 4 s recorded, the same path as the C++ app). One trial per action in every condition: 25 trials, ~600 frames per condition.

Condition (live test)Frame accuracyCorrect trialsFallingIdleLiftingSittingWalking
normal99.8%5/5100%99%100%100%100%
fast movements (fast)95.8%5/5100%82%100%97%100%
low light (low_light)96.8%5/590%94%100%100%100%
side view (side_angle)92.2%5/568%96%97%100%100%
far from the camera (far_distance)95.3%5/593%83%100%100%100%

All 25 trials are recognized correctly. The hardest condition is the side view, especially falling (68% of the frames), which seen from the side looks like sitting down; "idle" drops to 82–83% with fast movements and far from the camera, sometimes confused with walking. With a single trial per action and condition, the per-action figures are indicative.

Robustness
The frame and trial accuracy for every condition.
Old vs new model
The initial model (v1) vs the final model, on the 4 initial actions, on held-out clips: 67.1% → 99.3% window accuracy (8 clips; the representative figure remains the cross-validation one).

Modules 1 + 2 together – museum objects in your hands

In front of the webcam, whoever holds out their hands gets a museum object in them, at its real size, harmonized with the camera image, in real time and in Full HD (~30 frames per second on an RTX 2060, as many as the camera gives), while the action classifier of Module 1 runs in parallel. Every person gets their own objects:

The hands are found with MediaPipe Hand Landmarker (21 points per hand, with 3D coordinates in metres, which give the real scale) and tied to the person they belong to through the MediaPipe Pose skeleton. The objects are cut out once with YOLOv8m + SAM 2.1 + matting; the harmonization runs in a separate process, on the GPU, as a 3×4 colour matrix fitted to the ensemble of networks, plus the camera's grain; the object keeps the sharpness of its photo.

The object library
The library of 30 objects (The Met, CC0), at one scale, that of their real sizes: in the first row the 12 for one hand, in the next ones the 18 for both hands. For one hand: the hippopotamus "William" (Egyptian faience, 11 cm), three small amphorae (16–21 cm), a lion-shaped aquamanile (~1200, 21 cm), Filippo Negroli's parade helmet (Milan, 1543, 24 cm), an armour gauntlet with gilded bands (Valentin Siebenbürger, ~1535, 29 cm), a flintlock pistol (~1700–1730, 32 cm), a bronze spearhead (1200–800 BCE, 40 cm), a Japanese javelin in its sheath (44 cm), a Mughal dagger with a jade horse-head hilt, in its sheath (49 cm) and a Saxon war hammer (57 cm). For both hands: a celestial globe with clockwork carried by Pegasus (Gerhard Emmoser, 1579, 27 cm), a Greek helmet of the Corinthian type (31 cm), an etched morion (32 cm), a Roman marble bust (42 cm), five large amphorae (46–78 cm), a painted Indian shield (dhal, 52 cm), two horse-head defences (Dutch, ~1620, 54 cm, and Japanese, with horns, 56 cm), a breastplate by Giovan Paolo Negroli (59 cm), the shield of King Henry II of France (64 cm), a Neapolitan presentation sabre with a gilded scabbard (94 cm), a sword with an Ottoman hilt, in its scabbard (102 cm), an infantry armour from Nuremberg (~1600, 125 cm) and a two-handed sword (~1400–1450, 146 cm).

The cut-out also works for objects YOLO does not know (helmets, the breastplate, the bust, the weapons): SAM starts from the largest weak detection in the photo, and where YOLO sees nothing or only a part (the celestial globe: the sphere, without Pegasus and the base; the two-handed sword, the horse-head defences, the armour), the catalog gives the box of the whole object. Small holes that SAM leaves inside an object are filled before the matting, and the soft edge of a cut-out is at most as wide as that of a 1600 px photo: on the 4000 px photos of the swords, the blades would otherwise come out partly see-through. The museum photographs its weapons upright. The swords are turned to lie flat in their cut-outs (the photos stay unchanged), have their real length instead of a height in the catalog and lie across both palms at their full length; the dagger, the spears and the war hammer are held in one hand, standing on the open palm by their lower end or gripped by the handle in a fist. Objects without handles are held in a grip by their widest upper part (the rim of a helmet or of a shield, the ring of the globe), and the bust and the swords as by open hands.

The camera is read at its maximum resolution, Full HD (1920×1080). The hands and the skeletons are found in a 960×540 copy of the frame (the models work on small images anyway), and the objects are drawn into the Full HD image, from cut-outs at the full resolution of the museum's photos (mostly 900–2300 px on the long side; the swords, lying flat, ~3600 px long, from the museum's 4000 px originals), so the incised lines, the engravings and the patterns of the paintings are clearly visible. The grain of the objects is the camera's noise, measured on the Full HD image itself: cameras smooth and compress the image, so their noise does not grow when it is enlarged (the camera used: σ ≈ 0.25 grey levels at 1080p, 0.42 on a 480-row copy).

Real-time drawing. A large vase held close to the camera reaches 1500–1800 px in height, more than the frame. The previous version resized the cut-out in floating point for every new size, and the hands always move, so the size changed almost every frame: drawing such a vase took 62 ms, and the image dropped to 8–10 frames per second. Now the cut-out is prepared once, with its colours extended under the transparent area (pull-push), so that resizing does not bring dark edges in. A vase much smaller than its photo is resized whole with INTER_AREA, as before, and kept while its size and the harmonization do not change; one close to the size of its photo or larger (over ~70%, a large vase held close) is sampled bilinearly every frame, only where it is seen (at these ratios, practically the same as INTER_AREA). The colour is applied once per harmonization update, on the cut-out, and the compositing is done directly in the 8-bit image (blendLinear), in reused arrays. The vases look the same as before (a mean difference of 0.1–0.5 grey levels, a median PSNR of 48–52 dB per vase) and no longer have the dark ring on their edges.

Full HD, a large vase in both hands, its size changing every frameBeforeNow
drawing in Python (median / 90% of the frames)62 / 189 ms8.7 / 12.6 ms
drawing in C++ (Release, median / 90% of the frames)–8.6 / 12.1 ms
three objects in C++ (Release)10 ms3.6–4 ms
the Python demo, with recording (frames per second)8–1025–29
the C++ app, with the camera (frames per second)–27–29

The camera gives 30 frames per second; the limit is now finding the hands (MediaPipe, ~25–30 ms per frame), and after many minutes of running, when the laptop's processor heats up, the values drop by a few frames. The status text is redrawn only when it changes (in Full HD, with antialiasing, it cost ~4–5 ms per frame), and the recording passes the frame to ffmpeg without a copy.

The scene's light, the vases' real colours

The harmonization networks are trained to repair objects whose colours are wrong, so they pull the object's colours towards the scene's. The museum photos, however, have the right colours; compared with the camera's scene, only the light differs. Applied in full, the networks visibly changed the colours of the vases: they washed them out in a sunny square and turned them yellow in a warm hall. That is why, live, the change of brightness and contrast is taken from the networks in full, but only 25% of the change of colour. The measurements are made with exactly the live code (live_harmony_eval.py), on the harmonization benchmark (30 cases from real photos) and on the 8 vases put into 5 real scenes.

Share of the colour change takenfMSE ↓fPSNR ↑fSSIM ↑Vase saturation (mean, min–max)Vases within ±15% of their real saturation
no harmonization62621.3 dB0.8761.00100%
100% (the previous version)18626.8 dB0.9520.84 (0.29–1.60)30%
50%20126.5 dB0.9480.92 (0.61–1.28)58%
25% (default)21926.2 dB0.9450.95 (0.80–1.14)90%
0% (brightness only)24625.7 dB0.9400.99 (0.95–1.05)100%

Brightness and contrast alone bring 81% of the harmonization's gain on the benchmark (from 21.3 to 25.7 dB, out of 26.8 dB). With 25% of the colour change, the vases practically keep the colours of their museum photos, and in a warm light they still get a warm tint. On the benchmark only 0.6 dB is lost, because there the objects have wrong colours by construction. The colour matrix used live is even slightly better than the networks applied pixel by pixel (26.8 dB vs 26.5 dB): as a global transform, it smooths out their local artefacts.

The vases with the whole colour change and with 25%
The same vase as photographed, harmonized with the networks' whole colour change (the previous version) and with 25% (the current live version): in the square, the orange of the amphora is no longer washed out, the terracotta in the museum's courtyard no longer turns purplish, and in the warm hall the jar no longer turns yellow.

The painting and inscriptions of harmonized vases

Once harmonized, a vase used to lose almost all its detail: the painting, the incised lines, the inscriptions. The "camera" match blurred it down to the sharpness measured on the hands holding it, but the skin of the hands is smooth and always reads as blurred, so the blur sat at its cap (1.5 px at 480 rows, i.e. 3.4 px in Full HD) in 55% of the updates, with the median right at the cap. The camera, however, is not blurry: measured on the sharpest edges of its own frames, its transitions take 1.25 px (10–90%), less than those of a vase drawn without any blur (1.75 px). So a vase held in the hands, at the same distance as they are, is no longer blurred: the harmonization changes only its light and tone (the colour matrix, with 25% of the colour change) and adds the camera's grain. In addition, the cut-outs now keep the full resolution of the photos (973–1314 px, not cropped to 1080 px), and the two large amphorae, which the hands bring closest to the camera (up to ~1800 px on screen), are made from the museum's originals downscaled to 2400 px (2031 and 2099 px): on screen they are downscaled, not enlarged.

VaseOn screenDetail kept beforeDetail kept nowSSIM beforeSSIM now
Amphora Small Geometric500 px6%100%0.510.999
Amphora Small Cypriot500 px9%100%0.610.999
Amphora Small Etruscan500 px5%100%0.590.999
Amphora Red Figure1000 px5%113%0.600.995
Jar Terracotta1000 px6%114%0.530.994
Amphora Black Figure1000 px5%111%0.590.996
Amphora Large Attic1500 px7%110%0.700.996
Amphora Large Apulian1500 px7%115%0.690.995

Measured with live_harmony_detail.py: every vase at the size it has in the Full HD demo (one hand ~500 px, two hands ~1000 px, a large amphora held close ~1500 px), in the light of a warm museum hall (the matrix the live harmonization fits there), compared with the museum photo in the same light: the fine detail kept (the energy of the Laplacian, 100% = the photo's) and the structural similarity (SSIM) of the brightness. Over 100% means that the bilinear sampling of large vases seen up close is a touch sharper than the reference filter.

The details of harmonized vases, before and now
Details at 1:1, in the light of a warm museum hall: the museum photo, the harmonized vase before (blurred to match the hands, from 1080 px cut-outs) and now. The horses and harness of the black-figure amphora, the folds and the frieze of the red-figure amphora and the incised lines of the Attic amphora are visible as in the photo.

In the C++ app

The Qt/C++ app shows the objects exactly like the Python demo, with the same rules, automatic rhythm, harmonization and keys (H, O, N, D, S, Q), next to the action recognition, also in Full HD. Python (pose_server.py) does the perception and the decisions, with the same code: the hands, the people, which object appears, where and how it is held, and the harmonization. For every frame, it sends the description of the objects (cut-out, size, position, way of holding, the 3×4 colour matrix, the sharpness and the noise). C++ (object_renderer.cpp) composes the image step by step as in Python, on the very frame in which the hands were found, so that the objects do not lag behind them.

C++ compositing vs Python (same scene, three objects)Pixels drawnMaximum differencePixels differing by more than 1
harmonized (blurring, sharpening, no change of sharpness)48,0362 / 2554
raw (the H key)48,05400
the raw phase of the automatic rhythm, for one object48,0381 / 2550
Full HD: the scene in the small copy, the objects drawn at 1080 rows (harmonized)243,3161 / 2550
Full HD: a large vase close to the camera, 1569 px, taller than the frame (harmonized and raw)519,19600

The test scene contains all three ways of holding (on the palm, with a shadow; at the belly and by the handles, with the hands in front of the object), partial opacity and an object cut by the edge of the frame; the differences of 1–2 levels (4 pixels out of 48,000) come from rounding. The sensor noise added by C++ has the requested deviation (3.98 measured, for 4). Drawing the three objects takes ~0.9 ms at 640×480 and ~4 ms in Full HD (Release); with the camera, the app shows ~27–30 frames per second in Full HD, also with the objects in hand (the camera gives 30; fewer after many minutes of running, when the laptop's processor heats up). The Python server has two frames at a time: while it finds the hands in one, the next one is already read and decoded, and C++ prepares the frame after it while it draws the answer.

Along with the integration, tying the hands to people became robust to the moments when the skeleton model loses a person. A person lost for a moment keeps their identity, and a hand whose body is missing in a frame stays with the person it belonged to. Synthetic scenarios of 5 s each, with the same hands and skeletons, the previous logic vs the new one:

ScenarioPrevious logicNew logic
one person with both hands, the skeleton missed every 3rd framethe large object missing in 45 of 134 framesshown in every frame
one person with both hands, the skeleton missed 2 frames out of 386 changes of the objects shown2 (only the automatic rhythm)
one person, the skeleton lost for 1.3 s3 successive objects (a new identity)the same object, the rhythm continues
two people side by side, one hand each, one of them missed every 3rd frametheir hands form a pair (one shared object) in 89 framesnever: one object each
two people with both hands, missed in turnat most 1 object for both of them, 86 changesone object each, 2 changes

The filmed demo

Frames from the recording of the live objects-in-hands demo, in Full HD (4 min 27 s, 15 October 2026), made with the command:

python ar_objects.py --out demo.mp4 --cycle 6 --alternate 3

Every image is a frame of the video, chosen among the sharpest ones and cropped only at the edges: without the app's status bar and without the rest of the room. The objects are drawn by the app in real time, at their real size. With both hands up, every object stayed 6 s in the hands (3 s harmonized and 3 s raw, with the harmonization on); the label shows the phase of each frame. The images open at full size with a click.

Harmonized and raw, at the same moment

The hippopotamus William, harmonized
harmonized The hippopotamus "William" (Egyptian faience, ~1961–1878 BCE, 11 cm) on the open palm.
The hippopotamus William, raw
raw The same moment, 0.13 s later, with the harmonization switched off (the H key): the colours of the museum photo.
The Corinthian helmet, harmonized
harmonized A Greek helmet of the Corinthian type (bronze, 5th century BCE, 31 cm), held with both hands.
The Corinthian helmet, raw
raw The same helmet 0.8 s later, in the raw phase of the automatic rhythm.

The difference comes from the scene's light: the harmonization takes on the light and contrast of the camera image and only a quarter of the colour change, and the grain of the object is the camera's noise; the painting and the details remain those of the museum photo.

In one hand

Lion-shaped aquamanile
harmonized A lion-shaped aquamanile (copper alloy, ~1200, 21 cm), on the open palm.
Filippo Negroli's helmet
harmonized Filippo Negroli's parade helmet (Milan, 1543, 24 cm).
Armour gauntlet
harmonized An armour gauntlet with gilded bands (Valentin Siebenbürger, Nuremberg, ~1535, 29 cm).
Flintlock pistol
harmonized A flintlock pistol (William Green, ~1700–1730, 32 cm).
Mughal dagger
harmonized A Mughal dagger with a jade horse-head hilt, in its sheath (49 cm), standing on the palm.
War hammer
harmonized A Saxon war hammer (mid-16th century, 57 cm), standing on the palm.
Japanese javelin
harmonized A short Japanese javelin, in its sheath (44 cm).
Bronze spearhead
harmonized A bronze spearhead (1200–800 BCE, 40 cm).

One object in each hand

Hands apart: the hippopotamus and the spearhead
raw The hands more than 70 cm apart: one small object in each, the hippopotamus "William" and the bronze spearhead.

With both hands

Giovan Paolo Negroli's breastplate
harmonized Giovan Paolo Negroli's breastplate (Milan, ~1540–1545, 59 cm), held by its edges.
The shield of Henry II
raw The shield of King Henry II of France (~1555, 64 cm).
Painted Indian shield
harmonized A painted Indian shield (dhal, ~1800, 52 cm).
Etched morion
harmonized An etched morion (Brunswick, ~1560–1565, 32 cm).
Roman marble bust
harmonized A Roman marble bust (81–96 CE, 42 cm).
Dutch horse-head defence
harmonized A Dutch horse-head defence (~1620, 54 cm).
Japanese horse-head defence
harmonized A Japanese horse-head defence, with horns (19th century, 56 cm).
Infantry armour
harmonized An infantry armour (Nuremberg, ~1600, 125 cm): at its real size it goes out of the frame.
Red-figure amphora
harmonized A red-figure amphora (the Nikoxenos Painter, ~500 BCE, 46 cm).
Cypriot amphora
harmonized A Cypriot terracotta amphora (~1900–1600 BCE, 48 cm).
Attic black-figure amphora
raw An Attic black-figure amphora (the Antimenes Painter, ~530–520 BCE, 66 cm), held close to the camera.
Sword with an Ottoman hilt
raw A sword with an Ottoman hilt, in its scabbard (17th century, 102 cm), lying across the palms.
Two-handed sword
harmonized A two-handed sword (~1400–1450, 146 cm), lying across the palms: at its real size it extends beyond the frame.

Module 2 – The new photos

The old photos (low resolution, a vase photographed through a showcase) were replaced with studio photos of real vases from the Open Access collection of The Metropolitan Museum of Art – with a known real height, needed for the automatic scale – and with photos of museum halls from Wikimedia Commons, all reusable in academic work. The author and the licence of every image are in photos/CREDITS.md.

Black-figure amphora
Black-figure amphora, the Rycroft Painter, ca. 510 BCE, 51.1 cm (The Met, CC0)
Red-figure amphora
Amphora, the Nikoxenos Painter, ca. 500 BCE, 45.9 cm (The Met, CC0)
Cypriot amphora
Cypriot terracotta amphora, ca. 1900–1600 BCE, 48.3 cm (The Met, CC0)
The author
The author's photo
Nelson-Atkins
Sculpture gallery, Nelson-Atkins Museum (public domain)
Norton Simon
Asian sculpture gallery, Norton Simon Museum (public domain)
Kielce
National Museum in Kielce (CC BY 4.0, Krzysztof Popławski)
Met
European Sculpture Court, The Met (CC BY 3.0, Jean-Christophe Benoist)
Square
Plac Kościuszki, Tomaszów Mazowiecki (public domain)

Composition: the previous version vs the new one

For the moved object to look as if it belongs in the picture, the new pipeline deals with every cue by which the eye recognizes a composite:

  1. Precise cut-out – SAM 2.1 starts from the box YOLO finds and follows the exact shape of the object (handles, contour), leaving the base out.
  2. Natural edges – matting with a guided filter, and the edge colours cleaned of the old background (no "halo").
  3. The right size and perspective – Depth Anything V2 gives the distance in metres; the object's real height gives its size in the image, and the floor plane gives the perspective of the shadow.
  4. Detail – Real-ESRGAN restores the detail when the object has to be enlarged.
  5. Colour and light – the mean of three networks trained on iHarmony4 (Harmonizer, PCT-Net ViT, PCT-Net CNN).
  6. Sharpness and noise brought to the level of the scene.
  7. A reflection in the glossy floor and a contact shadow in the floor's perspective.

In each pair, the top image is the previous version (YOLO mask, blurred edge, Harmonizer, no super-resolution, reflection or shadow), at the same size and position; the bottom one is the new version. The last panel enlarges the area of the object.

Nelson-Atkins - previous
Previous versionNelson-Atkins Museum.
Nelson-Atkins - new
New versionNelson-Atkins Museum: the amphora at 3.8 m, without the base, with a faint reflection in the glossy floor and a contact shadow.
Norton Simon - previous
Previous versionNorton Simon Museum.
Norton Simon - new
New versionNorton Simon Museum: a dark hall lit with spotlights; the amphora, photographed in a studio, is darkened to match the light of the hall.
Kielce - previous
Previous versionNational Museum in Kielce.
Kielce - new
New versionKielce: the amphora at 5.1 m, in the middle of the hall.
Met - previous
Previous versionThe sculpture court of The Met.
Met - new
New versionThe Met: natural daylight, a stone floor.

The person in three scenes

Met - previous
Previous versionThe Met.
Met - new
New versionThe Met: 1.78 m tall, at a distance of 4.2 m.
Nelson-Atkins - previous
Previous versionNelson-Atkins.
Nelson-Atkins - new
New versionNelson-Atkins: at a distance of 3.2 m, a faint reflection in the parquet.
Square - previous
Previous versionA square, outdoors.
Square - new
New versionThe square: the outdoor depth model, at a distance of 7.4 m.

Scale and perspective from depth

Depth Anything V2 (its metric version) estimates the distance in metres of every background pixel. Knowing the object's real height H and the distance Z at the point where it is placed, its height in the image is h = f · H / Z (a pinhole camera, with an assumed 60° field of view). A plane fitted to the 3D points of the surrounding floor tells how "flattened" the floor appears (its tilt), used for the ellipse of the contact shadow. The first panel shows the depth map (near = bright), with the contact point marked.

Depth Kielce
Kielce: depth → composition → harmonization → reflection and shadow.
Depth square
The square: the outdoor model, the person at 7.4 m.
Object (real height)SceneDistance at the baseHeight in the imageFloor tilt
Black-figure amphora (0.51 m)Nelson-Atkins3.8 m16.0%0.31
Black-figure amphora (0.51 m)Norton Simon3.2 m21.1%0.28
Black-figure amphora (0.51 m)Kielce5.1 m13.2%0.29
Black-figure amphora (0.51 m)The Met3.2 m21.1%0.25
Red-figure amphora (0.46 m)Kielce4.9 m12.5%0.30
Red-figure amphora (0.46 m)Nelson-Atkins3.9 m13.9%0.30
Cypriot amphora (0.48 m)The Met3.4 m19.0%0.23
Cypriot amphora (0.48 m)Norton Simon3.8 m17.3%0.25
Person (1.78 m)The Met4.2 m56.0%0.19
Person (1.78 m)Nelson-Atkins3.2 m64.6%0.36
Person (1.78 m)Square (outdoors)7.4 m28.3%0.24

The "height in the image" is that of the cut-out (the object + a small margin), as a fraction of the background's height. The same amphora appears smaller in the Kielce hall (5.1 m) than next to the camera (3.2 m), without any manual size setting.

Red figure Kielce
The red-figure amphora in the Kielce hall.
Red figure Nelson-Atkins
The red-figure amphora at Nelson-Atkins.
Cypriot amphora Met
The Cypriot amphora in the sculpture court of The Met.
Cypriot amphora Norton Simon
The Cypriot amphora at Norton Simon.

Harmonization and relighting: 11 methods

Colour harmonization does not change the direction of the light on the object. Two recent methods that relight the object were also tested, both running on an RTX 2060 (12–20 s per image, peak memory 4.7 GB and 4.4 GB):

The figures are cropped around the object; the full images are in data/harmonization_results/.

All methods - Kielce
The red-figure amphora in the Kielce hall, with every method.
All methods - Met
The Cypriot amphora in the courtyard of The Met. The classical methods "wash" it in the colour of the floor; Intrinsic makes it greenish, IC-Light orange and saturated; the ensemble and ensemble + re-shading stay natural.
All methods - person
The person in the Nelson-Atkins hall.

Conclusion: on an RTX 2060 both relighting methods run, but neither of them is safe for every object. Intrinsic Harmonization over-corrects the albedo of coloured objects (the orange of terracotta turns olive or greenish); the "ensemble + re-shading" variant keeps the colours and changes only the shading. IC-Light gives the most convincing result on the person (the warm tone of the skin matches the hall), but it saturates the terracotta vases. The default method remains the ensemble, the most accurate on the benchmark.

VGG ablation
The ablation over the VGG16 depth (relu1_2 … relu4_3) for the training-free baseline.

Harmonization benchmark (iHarmony4 protocol)

Real photos in which the object is recoloured at random; every method has to bring it back to its original look, and the untouched photo is the ground truth (30 cases: 6 photos × 5 recolourings). fMSE, fPSNR and fSSIM are computed on the object only.

MethodfMSE ↓fPSNR ↑fSSIM ↑
No harmonization62621.3 dB0.876
Reinhard (classical)208016.1 dB0.785
Histogram matching (classical)264915.0 dB0.714
VGG16 statistics (no training)54322.3 dB0.908
Harmonizer (the previous version)28024.8 dB0.932
PCT-Net ViT27524.6 dB0.930
PCT-Net CNN28224.5 dB0.929
Ensemble: Harmonizer + PCT-Net ViT + CNN19126.5 dB0.949
Intrinsic Harmonization (relighting)100119.9 dB0.836
Ensemble + re-shading119520.2 dB0.869
IC-Light (relighting)74321.2 dB0.866

The ensemble of the three networks remains the best method on every metric (fMSE 191, fPSNR 26.5 dB, fSSIM 0.949): it reduces the error on the object by 32% compared with Harmonizer (the previous version of the pipeline) and by 69% compared with the unharmonized image. The classical methods make the result worse, because they assume the object should have the colours of the background.

The relighting methods score lower on this benchmark, as expected: here the object is only recoloured in its own photo, so its lighting is already right, and any change of shading is penalized. The benchmark measures colour correction, not lighting. For real composites, where the object comes from another light (studio → museum hall), relighting can help visually (for example IC-Light on the person), but it can also exaggerate (the Cypriot amphora becomes too orange). That is why the pipeline keeps the ensemble by default, and relighting remains optional (--harmony intrinsic | reshade | iclight).

fPSNR
The PSNR on the object (higher = better).
fMSE
The mean squared error on the object (lower = better).

Segmentation

YOLOv8 n vs m and SAM
YOLOv8n-seg (nano), YOLOv8m-seg (medium) and the mask refined with SAM 2.1 (green). Nano misses the handles and the neck (IoU 0.82 against medium); SAM starts from the YOLO box, keeps the handles and leaves out the white base (IoU 0.92 with the YOLO mask).
Cut-out
The matted cut-out, on a black background: a clean contour, without traces of the studio background.
Person segmentation
The segmentation of the person.

Inpainting

Inpainting the person
Filling the hole left by the person: TELEA, Navier-Stokes and LaMa. Evaluated against the real pixels (the mask moved to a free area), LaMa reaches 20.1 dB PSNR, against 15.2 dB (TELEA) and 15.6 dB (Navier-Stokes).
Inpainting a museum showcase
The same test on a museum showcase: LaMa 11.7 dB / SSIM 0.30, against an SSIM of 0.18–0.19 for the classical methods.

Shadows and reflection

Contact shadow
A contact shadow (a blurred ellipse under the base, flattened by the floor's perspective) – the default.
Cast shadow
A shadow cast on the floor, at 25°.

The reflection (--reflection 0–1) mirrors the object about its base line, blurred and fading; it can be seen in the enlarged panels of the demos above, on the lacquered parquet and on the glossy floors.

Sources

The photos: photos/CREDITS.md (author, source and licence of every image). The pretrained models and their licences are listed in README.md. Intrinsic Harmonization has an academic-use-only licence.