darktable-org / darktable-org/darktable

Lensfit: chart-based lens calibration and correction

Open
#21,678 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

feature: new scope: image processing
Dominant language
C
Stars
13.1k
Forks
1.4k
Avg merge
22h 14m
Merged PRs (30d)
198

Description

Lensfit: chart-based lens calibration, built from a photographed grid

Summary

Lensfit is a new view + correction method for measuring a lens's own distortion,
vignetting and TCA from a photograph of a printed grid chart, rather than relying
only on a static Lensfun-style database. It's built and working in my fork; I'm
raising it here first per CONTRIBUTING.md before putting real review time on
anyone's plate.

Fork: https://github.com/cyberhirsch/darktable (branch master, on top of
current upstream master)
Companion database project: https://github.com/cyberhirsch/lensfit

Why not a chessboard / Lensfun-style model

The detector traces each chart line as a continuous curve and intersects traced
curves for lattice points (common/lens_grid.h), rather than looking for
chessboard corners. That, plus a polynomial solve rather than Lensfun's fixed
radial model, is what lets it express anamorphic lenses -- squeeze, and
distortion that isn't rotationally symmetric -- which a purely radial model
can't represent at all. That's the actual motivation: I couldn't get correct
geometry for an anamorphic lens out of the existing correction methods, so I
built a way to measure it directly.

What's included

  • A lens_calib view: photograph a grid chart, the detector finds the lattice,
    a solver fits distortion + optional vignetting + TCA, with live undistort/
    falloff preview and residual readout.
  • A "lensfit database" correction method in the lens iop, alongside the
    existing Lensfun / embedded-metadata / profile / manual methods, so measured
    profiles get used the same way a Lensfun profile would.
  • EXIF auto-matching against a shipped, converted-from-Lensfun database, with
    vendor/model cascading pickers (the shipped set is 1000+ entries).
  • Optional sharing of a calibrated profile back to a companion project
    (github.com/cyberhirsch/lensfit) via a GitHub pull request -- off by default,
    opt-in, no network activity from a stock build.
  • Lensfun XML and OpenEXR STmap export, so a measurement is usable outside
    darktable too.
  • Printable calibration charts (vector PDF, one sheet covers every common
    aspect ratio via nested guides) and self-tests for the detector and solver.

Scope of the change

32 files under src/, ~17.5k insertions. That sounds large but it's almost
entirely new, self-contained files -- the new view, the new iop method, and
their supporting common/lens_* modules. Touches to existing shared files
are small and additive:

  • views/view.h: one new view flag, one new proxy struct (same pattern as the
    existing darkroom/lighttable proxies) -- nothing existing is changed.
  • dtgtk/thumbtable.c: extended one if(view == DARKROOM) check to also
    allow the new view, so its filmstrip double-click behaves consistently.
  • libs/tools/filmstrip.c: one flag added to an existing bitwise-OR list.
  • data/darktableconfig.xml.in: one new preferences tab, all-new keys.

The converted lens database (1290 profiles, ~535k lines) is not vendored
in this diff -- it's a git submodule pinned to a commit in the companion
lensfit repo. git clone --recurse-submodules gets the full, buildable,
testable feature with no extra step and no runtime fetch; this repo's own
history never carries the blobs.

Known open question, raised proactively

The submodule points at my personal GitHub account (cyberhirsch/lensfit).
That's fine for a personal fork, but I don't think an official build should
have a hard dependency on one person's repo staying up. If there's interest in
this feature, I'd want to talk through options -- transferring/mirroring the
database repo somewhere with more than one owner, or making the pin a CMake
option so a distro can point it at their own mirror -- before this goes any
further. Flagging it now rather than leaving it for review to find.

Also open: the converted profiles carry Lensfun's CC-BY-SA-3.0 database
license (tracked per-file in a provenance block, verified consistent across
all 1290), which is a different license than darktable's own code and would
need a real look before anything ships under the project's name.

Try it

git clone --recurse-submodules https://github.com/cyberhirsch/darktable

Build as usual; the lensfit view shows up alongside lighttable/darkroom/map.

Ask

Is this a direction you'd want in darktable at all, and if so, what should
change before it's PR-shaped? Happy to walk through the code, split it up
differently, or rework any of it -- and I'd stay on to maintain it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review the fork's 32-file implementation, starting with common/lens_grid.h and the lens_calib view, then inspect the lens iop integration and the detector and solver self-tests. Build with --recurse-submodules to exercise the feature. Before any contribution, resolve whether the personal lensfit submodule and Lensfun CC-BY-SA database licensing are acceptable, and define a maintainer-approved scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
computer-graphics, computer-vision, desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.