From 72dfa1b242e3e60be852cc7c2e20c49cc3c18265 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Sat, 18 Jan 2020 14:32:03 -0800 Subject: [PATCH] Add auto perspective correction to GUI Add three buttons for correcting pitch, yaw, or both. Horizontal and/or vertical tilt adjusters are updated with the automatically computed values. --- .../svg/perspective-horizontal-vertical.svg | 116 ++++++++++++++++++ rtgui/lensgeomlistener.h | 1 + rtgui/perspective.cc | 57 +++++++++ rtgui/perspective.h | 10 ++ rtgui/toolpanelcoord.cc | 22 ++++ rtgui/toolpanelcoord.h | 1 + 6 files changed, 207 insertions(+) create mode 100644 rtdata/images/svg/perspective-horizontal-vertical.svg diff --git a/rtdata/images/svg/perspective-horizontal-vertical.svg b/rtdata/images/svg/perspective-horizontal-vertical.svg new file mode 100644 index 000000000..0c5046879 --- /dev/null +++ b/rtdata/images/svg/perspective-horizontal-vertical.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + image/svg+xml + + + + + Maciej Dworak + + + + + + + + RawTherapee icon. + + + + + + + + + + + + + + + + + diff --git a/rtgui/lensgeomlistener.h b/rtgui/lensgeomlistener.h index 7bfa0fb45..810b7ed98 100644 --- a/rtgui/lensgeomlistener.h +++ b/rtgui/lensgeomlistener.h @@ -25,4 +25,5 @@ public: virtual void straightenRequested () = 0; virtual void autoCropRequested () = 0; virtual double autoDistorRequested () = 0; + virtual void autoPerspRequested (bool corr_pitch, bool corr_yaw, double& rot, double& pitch, double& yaw) = 0; }; diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index e895c08c5..6fa524c45 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -28,11 +28,17 @@ using namespace rtengine::procparams; PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("TP_PERSPECTIVE_LABEL")) { + lens_geom_listener = nullptr; + Gtk::Image* ipersHL = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); Gtk::Image* ipersHR = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); Gtk::Image* ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); Gtk::Image* ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small.png")); + Gtk::Image* ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-bottom.png")); + Gtk::Image* ipers_auto_yaw = Gtk::manage (new RTImage ("perspective-horizontal-left.png")); + Gtk::Image* ipers_auto_pitch_yaw = Gtk::manage (new RTImage ("perspective-horizontal-vertical.png")); + Gtk::Image* ipers_cam_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); Gtk::Image* ipers_cam_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); Gtk::Image* ipers_cam_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); @@ -89,6 +95,22 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" -85, 85, 0.1, 0, ipers_cam_yaw_left, ipers_cam_yaw_right)); camera_yaw->setAdjusterListener (this); + auto_pitch = Gtk::manage (new Gtk::Button ()); + auto_pitch->set_image(*ipers_auto_pitch); + auto_pitch->signal_pressed().connect( sigc::bind(sigc::mem_fun(*this, &PerspCorrection::autoCorrectionPressed), auto_pitch) ); + + auto_yaw = Gtk::manage (new Gtk::Button ()); + auto_yaw->set_image(*ipers_auto_yaw); + auto_yaw->signal_pressed().connect( sigc::bind(sigc::mem_fun(*this, &PerspCorrection::autoCorrectionPressed), auto_yaw) ); + + auto_pitch_yaw = Gtk::manage (new Gtk::Button ()); + auto_pitch_yaw->set_image(*ipers_auto_pitch_yaw); + auto_pitch_yaw->signal_pressed().connect( sigc::bind(sigc::mem_fun(*this, &PerspCorrection::autoCorrectionPressed), auto_pitch_yaw) ); + + Gtk::HBox* auto_hbox = Gtk::manage (new Gtk::HBox()); + Gtk::Label* auto_label = Gtk::manage (new Gtk::Label (M("GENERAL_AUTO") + ": ")); + auto_hbox->pack_start(*auto_label, Gtk::PACK_SHRINK); + Gtk::Frame* pca_frame = Gtk::manage (new Gtk::Frame (M("TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME"))); pca_frame->set_label_align(0.025, 0.5); @@ -122,12 +144,17 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" simple->pack_start (*horiz); simple->pack_start (*vert); + auto_hbox->pack_start (*auto_pitch); + auto_hbox->pack_start (*auto_yaw); + auto_hbox->pack_start (*auto_pitch_yaw); + camera_vbox->pack_start (*camera_focal_length); camera_vbox->pack_start (*camera_crop_factor); camera_vbox->pack_start (*camera_shift_horiz); camera_vbox->pack_start (*camera_shift_vert); camera_vbox->pack_start (*camera_pitch); camera_vbox->pack_start (*camera_yaw); + camera_vbox->pack_start (*auto_hbox); camera_frame->add(*camera_vbox); camera_based->pack_start(*camera_frame); @@ -354,6 +381,32 @@ void PerspCorrection::adjusterChanged(Adjuster* a, double newval) } } +void PerspCorrection::autoCorrectionPressed(Gtk::Button* b) +{ + if (!lens_geom_listener) { + return; + } + + double rot = 0; + double pitch = 0; + double yaw = 0; + + if (b == auto_pitch) { + lens_geom_listener->autoPerspRequested(true, false, rot, pitch, yaw); + } else if (b == auto_yaw) { + lens_geom_listener->autoPerspRequested(false, true, rot, pitch, yaw); + } else if (b == auto_pitch_yaw) { + lens_geom_listener->autoPerspRequested(true, true, rot, pitch, yaw); + } + + disableListener(); + camera_pitch->setValue(pitch); + camera_yaw->setValue(yaw); + enableListener(); + + adjusterChanged(camera_pitch, pitch); +} + void PerspCorrection::methodChanged (void) { @@ -431,5 +484,9 @@ void PerspCorrection::setBatchMode (bool batchMode) projection_shift_vert->showEditedCB (); projection_yaw->showEditedCB (); + auto_pitch->set_sensitive(false); + auto_yaw->set_sensitive(false); + auto_pitch_yaw->set_sensitive(false); + method->append (M("GENERAL_UNCHANGED")); } diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 9d19c84b0..fadead7e9 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -21,6 +21,7 @@ #include #include "adjuster.h" +#include "lensgeomlistener.h" #include "toolpanel.h" class PerspCorrection final : @@ -34,6 +35,9 @@ protected: Gtk::VBox* simple; Adjuster* horiz; Adjuster* vert; + Gtk::Button* auto_pitch; + Gtk::Button* auto_yaw; + Gtk::Button* auto_pitch_yaw; Gtk::VBox* camera_based; Adjuster* camera_crop_factor; Adjuster* camera_focal_length; @@ -47,6 +51,7 @@ protected: Adjuster* projection_shift_horiz; Adjuster* projection_shift_vert; Adjuster* projection_yaw; + LensGeomListener* lens_geom_listener; public: @@ -58,7 +63,12 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; + void autoCorrectionPressed (Gtk::Button* b); void methodChanged (void); void setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool camera_angle_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add, bool projection_scale_add); + void setLensGeomListener (LensGeomListener* listener) + { + lens_geom_listener = listener; + } void trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 57f61a09c..a62bc5610 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -26,6 +26,7 @@ #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" #include "../rtengine/improcfun.h" +#include "../rtengine/perspectivecorrection.h" #include "../rtengine/procevents.h" #include "../rtengine/refreshmap.h" @@ -258,6 +259,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit flatfield->setFFProvider (this); lensgeom->setLensGeomListener (this); rotate->setLensGeomListener (this); + perspective->setLensGeomListener (this); distortion->setLensGeomListener (this); crop->setCropPanelListener (this); icm->setICMPanelListener (this); @@ -844,6 +846,26 @@ void ToolPanelCoordinator::straightenRequested () toolBar->setTool (TMStraighten); } +void ToolPanelCoordinator::autoPerspRequested (bool corr_pitch, bool corr_yaw, double& rot, double& pitch, double& yaw) +{ + if (!(ipc && (corr_pitch || corr_yaw))) { + return; + } + + rtengine::ImageSource *src = dynamic_cast(ipc->getInitialImage()); + if (!src) { + return; + } + + rtengine::procparams::ProcParams params; + ipc->getParams(¶ms); + + auto res = rtengine::PerspectiveCorrection::autocompute(src, corr_pitch, corr_yaw, ¶ms, src->getMetaData()); + rot = res.angle; + pitch = res.pitch; + yaw = res.yaw; +} + double ToolPanelCoordinator::autoDistorRequested () { if (!ipc) { diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 4313f6d12..53b27f158 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -301,6 +301,7 @@ public: // rotatelistener interface void straightenRequested () override; void autoCropRequested () override; + void autoPerspRequested (bool corr_pitch, bool corr_yaw, double& rot, double& pitch, double& yaw) override; double autoDistorRequested () override; // spotwblistener interface