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 @@
+
+
+
+
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