Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No vignette correction available for NIKON D5600 + AF-S DX Nikkor 35mm f/1.8G but it appears in lensfundb #6989

Open
acamari opened this issue Mar 14, 2024 · 5 comments · May be fixed by #7065
Assignees
Labels
type: bug Something is not doing what it's supposed to be doing
Milestone

Comments

@acamari
Copy link

acamari commented Mar 14, 2024

Vignetting correction checkbox is greyed/disabled out for this camera/lens combination although I see it available in my lensfun db:

NIKON D5600 + AF-S DX Nikkor 35mm f/1.8G

$ less /home/acamari/.local/share/lensfun/updates/version_1/slr-nikon.xml
...
    <camera>
        <maker>Nikon Corporation</maker>
        <maker lang="en">Nikon</maker>
        <model>Nikon D5600</model>
        <model lang="en">D5600</model>
        <mount>Nikon F AF</mount>
        <cropfactor>1.534</cropfactor>
    </camera>
...
    <lens>
        <maker>Nikon</maker>
        <model>Nikon AF-S DX Nikkor 35mm f/1.8G</model>
        <model lang="en">NIKKOR AF-S 35mm f/1.8G DX</model>
        <mount>Nikon F AF</mount>
        <!-- Average crop factor of Nikon APS-C cameras -->
        <cropfactor>1.528</cropfactor>
        <calibration>
            <distortion model="ptlens" focal="35" a="0.003" b="-0.017" c="0.005"/>
            <tca model="linear" focal="35" kr="1.0003" kb="1.0003"/>
            <vignetting model="pa" focal="35" aperture="1.8" distance="10" k1="-0.3298" k2="-0.0595" k3="0.0938"/>
            <vignetting model="pa" focal="35" aperture="1.8" distance="1000" k1="-0.3298" k2="-0.0595" k3="0.0938"/>
            <vignetting model="pa" focal="35" aperture="2.8" distance="10" k1="-0.1367" k2="0.0656" k3="-0.0502"/>
            <vignetting model="pa" focal="35" aperture="2.8" distance="1000" k1="-0.1367" k2="0.0656" k3="-0.0502"/>
            <vignetting model="pa" focal="35" aperture="4" distance="10" k1="-0.1170" k2="0.0027" k3="0.0072"/>
            <vignetting model="pa" focal="35" aperture="4" distance="1000" k1="-0.1170" k2="0.0027" k3="0.0072"/>
            <vignetting model="pa" focal="35" aperture="5" distance="10" k1="-0.1203" k2="0.0086" k3="0.0030"/>
            <vignetting model="pa" focal="35" aperture="5" distance="1000" k1="-0.1203" k2="0.0086" k3="0.0030"/>
            <vignetting model="pa" focal="35" aperture="22" distance="10" k1="-0.1143" k2="-0.0162" k3="0.0186"/>
            <vignetting model="pa" focal="35" aperture="22" distance="1000" k1="-0.1143" k2="-0.0162" k3="0.0186"/>
        </calibration>
    </lens>
...
    <lens>
        <maker>Nikon</maker>
        <model>Nikon AF-S Nikkor 35mm f/1.8G ED</model>
        <model lang="en">NIKKOR AF-S 35mm f/1.8G ED</model>
        <mount>Nikon F AF</mount>
        <cropfactor>1</cropfactor>
        <calibration>
            <!-- Taken with Nikon D750 -->
            <distortion model="ptlens" focal="35" a="0.02498" b="-0.07793" c="0.05642"/>
            <tca model="poly3" focal="35" br="-0.0002043" vr="1.0006177" bb="0.0003032" vb="0.9996507"/>
        </calibration>
    </lens>

I believe somehow rawtherapee or lensfun is getting confused and picking up the second record, the one taken with a FX camera that lacks vignetting data.

acamari@maetel-ubuntu:~$ uname -a
Linux maetel-ubuntu 6.2.0-39-generic #40~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 16 10:53:04 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
acamari@maetel-ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
Codename:       jammy

about/version:

Version: 5.10
Branch: 5.10
Commit: 8adb5439d
Commit date: 2024-02-15
Compiler: cc 9.4.0
Processor: generic x86
System: Linux
Bit depth: 64 bits
Gtkmm: V3.24.2
Lensfun: V0.3.2.0
Build type: release
Build flags:  -std=c++11 -mtune=generic -Werror=unused-label -Werror=delete-incomplete -fno-math-errno -Wno-attributes -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result -Wunused-macros -fopenmp -Werror=unknown-pragmas -O3 -DNDEBUG -ftree-vectorize
Link flags:  -mtune=generic
OpenMP support: ON
MMAP support: ON
Build OS: Linux 5.15.0-1054-azure x86_64
Build date: Fri, 16 Feb 2024 05:18:01 +0000 UTC
Build epoch: 1708060681
Build UUID: fd65a10b-7483-40e7-8afd-fd9c2e5cff2a

To reproduce, open attached NEF file, in neutral profile, go to Transform -> Lens/Geometry -> Profiled lens correction -> Automatically selected (Vignetting is disabled).

Attached files available under Public Domain.

files at (could not upload it here, maybe by filesize?): http://oss.verlet.org/pub/20240313-rtbugnovignette35mm.tgz

$ tar ztf /tmp/rtbugnovignette35mm.tgz 
20230815-tortillas-estrella/_DSC4431.NEF
20230815-tortillas-estrella/_DSC4431.NEF.pp3
rtnovignettecorr.txt          # rawtherape logfile
$
@Lawrence37
Copy link
Collaborator

Confirmed. There is some suspicious usage, or rather non-usage, of the camera specifications when searching for a matching lens profile.

@Lawrence37 Lawrence37 self-assigned this Mar 15, 2024
@Lawrence37 Lawrence37 added the type: bug Something is not doing what it's supposed to be doing label Mar 15, 2024
@Lawrence37 Lawrence37 added this to the v5.11 milestone Mar 15, 2024
@acamari
Copy link
Author

acamari commented Mar 15, 2024

Thanks for looking into it

@Lawrence37
Copy link
Collaborator

I did some testing with the code and managed to fix the problem. I need to clean the patch up and also understand why the camera details weren't used to look up the lens. It looks intentional, but the rationale is not clear.

Patch
diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc
index fc5bb0017..5bf154592 100644
--- a/rtengine/rtlensfun.cc
+++ b/rtengine/rtlensfun.cc
@@ -460,20 +460,38 @@ LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring &
 }
 
 
-LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) const
+LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const
 {
     LFLens ret;
     if (data_ && !name.empty()) {
         MyMutex::MyLock lock(lfDBMutex);
-        if (!camera.data_) {
+        if (!autoMatch) {
             // Only the lens name provided. Try to find exact match by name.
             LFLens candidate;
+            LFLens bestCandidate;
+            const auto isCStringIn = [](const char *str, const char *const *list) {
+                for (auto element = list[0]; element[0]; element++) {
+                    if (!strcmp(str, element)) {
+                        return true;
+                    }
+                }
+                return false;
+            };
             for (auto lens_list = data_->GetLenses(); lens_list[0]; lens_list++) {
                 candidate.data_ = lens_list[0];
-                if (name == candidate.getLens()) {
-                    return candidate;
+                if ((!bestCandidate.data_ ||
+                        (bestCandidate.data_->CropFactor > camera.data_->CropFactor
+                                ? bestCandidate.data_->CropFactor > candidate.data_->CropFactor
+                                : candidate.data_->CropFactor <= camera.data_->CropFactor &&
+                                      bestCandidate.data_->CropFactor < candidate.data_->CropFactor)) &&
+                    name == candidate.getLens() &&
+                    isCStringIn(camera.data_->Mount, candidate.data_->Mounts)) {
+                    bestCandidate.data_ = candidate.data_;
                 }
             }
+            if (bestCandidate.data_) {
+                return bestCandidate;
+            }
         }
         auto found = data_->FindLenses(camera.data_, nullptr, name.c_str());
         for (size_t pos = 0; !found && pos < name.size(); ) {
@@ -562,12 +580,7 @@ std::unique_ptr<LFModifier> LFDatabase::findModifier(
     }
 
     const LFCamera c = findCamera(make, model, lensProf.lfAutoMatch());
-    const LFLens l = findLens(
-        lensProf.lfAutoMatch()
-            ? c
-            : LFCamera(),
-        lens
-    );
+    const LFLens l = findLens(c, lens, lensProf.lfAutoMatch());
 
     bool swap_xy = false;
     if (rawRotationDeg >= 0) {
diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h
index bcce77f34..1d941246f 100644
--- a/rtengine/rtlensfun.h
+++ b/rtengine/rtlensfun.h
@@ -121,7 +121,7 @@ public:
     std::vector<LFCamera> getCameras() const;
     std::vector<LFLens> getLenses() const;
     LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model, bool autoMatch) const;
-    LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const;
+    LFLens findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const;
 
     std::unique_ptr<LFModifier> findModifier(
         const procparams::LensProfParams &lensProf,
diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc
index 0e17b3f40..5f42a1cde 100644
--- a/rtgui/lensprofile.cc
+++ b/rtgui/lensprofile.cc
@@ -251,7 +251,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa
 
     if (pp->lensProf.lfAutoMatch()) {
         if (metadata) {
-            const LFLens l = db->findLens(c, metadata->getLens());
+            const LFLens l = db->findLens(c, metadata->getLens(), true);
             setLensfunLens(l.getLens());
         }
     } else if (pp->lensProf.lfManual()) {
@@ -522,7 +522,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged)
             } else if (metadata) {
                 const LFDatabase* const db = LFDatabase::getInstance();
                 const LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel(), true);
-                const LFLens l = db->findLens(c, metadata->getLens());
+                const LFLens l = db->findLens(c, metadata->getLens(), true);
                 setLensfunCamera(c.getMake(), c.getModel());
                 setLensfunLens(l.getLens());
             }
@@ -808,7 +808,7 @@ void LensProfilePanel::updateLensfunWarning()
             return;
         }
 
-        const LFLens l = db->findLens(LFCamera(), (*itl)[lf->lensfunModelLens.lens]);
+        const LFLens l = db->findLens(c, (*itl)[lf->lensfunModelLens.lens], false);
         const float lenscrop = l.getCropFactor();
         const float camcrop = c.getCropFactor();

@acamari
Copy link
Author

acamari commented Mar 16, 2024

hi, I don't have that much experience with rawtherapee development, should I apply this to head or can I apply this over v5.10? is there any kind of nightly build available? regards

@Lawrence37
Copy link
Collaborator

The patch is intended to be a progress report and solicit feedback from other developers who are interested. If you want to try it, I created the patch on top of the dev branch. However, it might also work on v5.10. There's no automated build available until I create a pull request.

@Lawrence37 Lawrence37 linked a pull request May 3, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something is not doing what it's supposed to be doing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants