diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index a18e616f7..3d384ee62 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -468,8 +468,8 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); // Camera-based. const double f = - ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : 24.0) - * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : 1.0) + ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH) + * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR) * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI; @@ -1162,8 +1162,8 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const double hptanpt = tan(hpteta); // Camera-based. const double f = - ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : 24.0) - * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : 1.0) + ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH) + * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR) * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 5ef95bfa2..c517adf9f 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -949,11 +949,22 @@ struct LensProfParams { * Parameters of the perspective correction */ struct PerspectiveParams { + static constexpr double DEFAULT_CAMERA_CROP_FACTOR = 1; + static constexpr double DEFAULT_CAMERA_FOCAL_LENGTH = 24; + Glib::ustring method; bool render; double horizontal; double vertical; + /** + * Negative and zero values indicate an unspecified crop factor and should + * be interpreted with {@link #DEFAULT_CAMERA_CROP_FACTOR}. + */ double camera_crop_factor; + /** + * Negative and zero values indicate an unspecified focal length and should + * be interpreted with {@link #DEFAULT_CAMERA_FOCAL_LENGTH}. + */ double camera_focal_length; double camera_pitch; double camera_roll; diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index d06243524..317732bd2 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -160,10 +160,10 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" Gtk::Box* camera_vbox = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); - camera_focal_length = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), 0.5, 2000, 0.01, 24)); + camera_focal_length = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), 0.5, 2000, 0.01, PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH)); camera_focal_length->setAdjusterListener (this); - camera_crop_factor = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), 0.1, 30, 0.01, 1)); + camera_crop_factor = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), 0.1, 30, 0.01, PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR)); camera_crop_factor->setAdjusterListener (this); camera_shift_horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL"), -50, 50, 0.01, 0)); @@ -358,13 +358,30 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited) void PerspCorrection::write (ProcParams* pp, ParamsEdited* pedited) { + // If any of these are non-zero, the focal length and crop factor must be + // updated to ensure they won't be auto-filled from metadata later. This + // prevents surprise changes to the perspective correction results. + const bool update_fl = camera_pitch->getValue() != 0 || + camera_yaw->getValue() != 0 || + projection_pitch->getValue() != 0 || + projection_yaw->getValue() != 0; pp->perspective.render = render; pp->perspective.horizontal = horiz->getValue (); pp->perspective.vertical = vert->getValue (); - pp->perspective.camera_crop_factor= camera_crop_factor->getValue (); - pp->perspective.camera_focal_length = camera_focal_length->getValue (); + if (update_fl || pp->perspective.camera_crop_factor > 0 || + std::abs(camera_crop_factor->getValue() - PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR) > 1e-5) { + // Update if update_fl is true or the crop factor has previously been + // set or if the adjuster has changed from the default value. + pp->perspective.camera_crop_factor = camera_crop_factor->getValue (); + } + if (update_fl || pp->perspective.camera_focal_length > 0 || + std::abs(camera_focal_length->getValue() - PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH) > 1e-4) { + // Update if update_fl is true or the focal length has previously been + // set or if the adjuster has changed from the default value. + pp->perspective.camera_focal_length = camera_focal_length->getValue (); + } pp->perspective.camera_pitch = camera_pitch->getValue (); pp->perspective.camera_roll = camera_roll->getValue (); pp->perspective.camera_shift_horiz = camera_shift_horiz->getValue (); @@ -412,8 +429,12 @@ void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdit horiz->setDefault (defParams->perspective.horizontal); vert->setDefault (defParams->perspective.vertical); - camera_crop_factor->setDefault (defParams->perspective.camera_crop_factor); - camera_focal_length->setDefault (defParams->perspective.camera_focal_length); + camera_crop_factor->setDefault(defParams->perspective.camera_crop_factor > 0 + ? defParams->perspective.camera_crop_factor + : PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR); + camera_focal_length->setDefault(defParams->perspective.camera_focal_length > 0 + ? defParams->perspective.camera_focal_length + : PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH); camera_pitch->setDefault (defParams->perspective.camera_pitch); camera_roll->setDefault (defParams->perspective.camera_roll); camera_shift_horiz->setDefault (defParams->perspective.camera_shift_horiz); @@ -636,8 +657,13 @@ void PerspCorrection::trimValues (rtengine::procparams::ProcParams* pp) horiz->trimValue(pp->perspective.horizontal); vert->trimValue(pp->perspective.vertical); - camera_crop_factor->trimValue(pp->perspective.camera_crop_factor); - camera_focal_length->trimValue(pp->perspective.camera_focal_length); + // Only update crop factor and focal length if they have been manually set. + if (pp->perspective.camera_crop_factor > 0) { + camera_crop_factor->trimValue(pp->perspective.camera_crop_factor); + } + if (pp->perspective.camera_focal_length > 0) { + camera_focal_length->trimValue(pp->perspective.camera_focal_length); + } camera_pitch->trimValue(pp->perspective.camera_pitch); camera_roll->trimValue(pp->perspective.camera_roll); camera_shift_horiz->trimValue(pp->perspective.camera_shift_horiz); @@ -679,10 +705,25 @@ void PerspCorrection::setBatchMode (bool batchMode) void PerspCorrection::setFocalLengthValue (const ProcParams* pparams, const FramesMetaData* metadata) { - const double pp_crop_factor = pparams->perspective.camera_crop_factor; - const double pp_focal_length = pparams->perspective.camera_focal_length; - double default_crop_factor = 1.0; - double default_focal_length = 24.0; + double pp_crop_factor = pparams->perspective.camera_crop_factor; + double pp_focal_length = pparams->perspective.camera_focal_length; + double default_crop_factor = PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR; + double default_focal_length = PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH; + + // If any of these values are non-zero, don't set the crop factor or focal + // length from metadata to avoid a surprise change in perspective correction + // results. + if (pparams->perspective.camera_pitch != 0 || + pparams->perspective.camera_yaw != 0 || + pparams->perspective.projection_pitch != 0 || + pparams->perspective.projection_yaw != 0) { + if (pp_crop_factor <= 0) { + pp_crop_factor = PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR; + } + if (pp_focal_length <= 0) { + pp_focal_length = PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH; + } + } // Defaults from metadata. if (metadata && (pp_crop_factor <= 0 || pp_focal_length <= 0)) { @@ -710,13 +751,13 @@ void PerspCorrection::setFocalLengthValue (const ProcParams* pparams, const Fram // Change value if those from the ProcParams are invalid. if (pp_crop_factor > 0) { - camera_crop_factor->setValue(pparams->perspective.camera_crop_factor); + camera_crop_factor->setValue(pp_crop_factor); } else { camera_crop_factor->setDefault(default_crop_factor); camera_crop_factor->setValue(default_crop_factor); } if (pp_focal_length > 0) { - camera_focal_length->setValue(pparams->perspective.camera_focal_length); + camera_focal_length->setValue(pp_focal_length); } else { camera_focal_length->setDefault(default_focal_length); camera_focal_length->setValue(default_focal_length);