Repository navigation
fix(flatfield): store the gain in sensor layout and turn it by each frame's EXIF orientation - #1359
Merged
marcinz606 merged 2 commits intoOct 11, 2026
Conversation
…rame's EXIF orientation A profile was baked from its reference after the decode had applied the reference's EXIF orientation, and applied to each frame after the frame's own orientation, with cv2.resize stretching the gain to fit. A camera on a copy stand tags frames close to randomly (one Canon session here wrote tag 1 on 7 frames and tag 8 on 6), so a frame tagged differently from its flat got the gain upside down or squashed across the turn. On a synthetic rig that leaves a 103-104% spread on tag 6/8 frames, worse than the 73% uncorrected. The bake now undoes the reference's orientation, and every apply site takes the decode's own tag first: preview and test strip renders, rendered thumbnails, export, Linear Output, Roll Analysis, Auto-crop all frames, Auto Skew, stitch parts and the lens path. The tag reaches the canvas render with the decode metadata, beside the camera matrix. `orientation` is a required argument of apply_flatfield, so a new call site cannot leave it out. A startup migration moves existing profiles to sensor layout. It works out the tag the bake applied, not the one read today: a JXL decode applies none, and a tag only LibRaw reads (CR3, RAF, read since fb1d733) is trusted only when the gain's aspect shows the bake made that quarter turn. A profile whose reference cannot be read, or whose bake tag cannot be told, is left unmarked, applies as baked, and is tried again on the next launch. Check Flat Field takes the open frame's tag. THUMBNAIL_RENDER_VERSION is bumped: frames with a Flat Field and a tag different from their reference render differently.
The check sat in the camera's orientation while the frame on the canvas was turned or flipped, so a portrait frame showed a landscape check and a dark corner in the check did not match the same corner in the photo. It now takes the frame's quarter turns and flips, after its EXIF orientation. Fine rotation, keystone and crop are left out, so the edges, where falloff shows, stay in view.
thetalkingdrum
force-pushed
the
fix/flatfield-exif-orientation
branch
from
October 11, 2026 14:38
58d201f to
2afa59f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
A Flat Field profile only corrects frames whose EXIF orientation tag matches the reference's. Cameras on a copy stand point straight down, so their tilt sensor tags frames close to randomly. In one sample set, a single Canon session wrote tag 1 on 7 frames and tag 8 on the other 6. With a mismatched tag, the gain is applied upside down (tag 3), or squashed across the turn by
cv2.resize(tags 6 and 8). The frame then ends up more uneven than with no correction at all. On a synthetic rig the spread goes from 73% uncorrected to 103–104%.The cause: the bake decodes the reference with its EXIF orientation already applied, and every apply site multiplies the frame after its own orientation is applied. The embedded lens correction already does this the right way: it turns back to sensor layout before applying its maps.
The fix
orientationis a required argument ofapply_flatfield, so a new call site can't leave it out.Trade-offs
THUMBNAIL_RENDER_VERSIONgoes 2 → 3, asCLAUDE.mdrequires for changed pixels.mainhas already moved it from 0.63.0's 1, so users updating to 0.64 re-check their thumbnails once either way, as long as this lands before 0.64.Testing
make allpasses.