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.
This commit is contained in:
116
rtdata/images/svg/perspective-horizontal-vertical.svg
Normal file
116
rtdata/images/svg/perspective-horizontal-vertical.svg
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="perspective-horizontal-vertical.svg"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-filename="/tmp/template.png"
|
||||
id="SVGRoot"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<sodipodi:namedview
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-width="1920"
|
||||
showgrid="true"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="12"
|
||||
inkscape:cx="9.5946553"
|
||||
inkscape:zoom="33.833333"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666768"
|
||||
pagecolor="#E0E1E2"
|
||||
id="base">
|
||||
<inkscape:grid
|
||||
dotted="false"
|
||||
empspacing="11"
|
||||
originy="1"
|
||||
originx="1"
|
||||
id="grid1374"
|
||||
type="xygrid" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs815" />
|
||||
<metadata
|
||||
id="metadata818">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Maciej Dworak</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:description>RawTherapee icon.</dc:description>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path829"
|
||||
d="m 16.33328,1.6391557 c 0,0 -0.597535,0.1004573 -0.597535,0.1004573 0,0 -12.5482282,2.1095983 -12.5482282,2.1095983 0,0 -1.3974074,18.5332577 -1.3974074,18.5332577 0,0 20.6576276,-3.472946 20.6576276,-3.472946 0,0 -6.114457,-17.2703671 -6.114457,-17.2703671 m -0.870105,1.2410528 c 0,0 0.721483,2.3092989 0.721483,2.3092989 0,0 -2.653273,0.4460661 -2.653273,0.4460661 0,0 -0.540063,-2.3397989 -0.540063,-2.3397989 0,0 2.471853,-0.4155661 2.471853,-0.4155661 m 1.123451,3.5959084 C 16.586626,6.4761171 18,11 18,11 c 0,0 -3.10975,0.52281 -3.10975,0.52281 0,0 -1.057973,-4.5836339 -1.057973,-4.5836339 0,0 2.754349,-0.463059 2.754349,-0.463059 m 1.969195,6.3029399 c 0,0 1.276331,4.085239 1.276331,4.085239 0,0 -3.570455,0.600263 -3.570455,0.600263 0,0 -0.955389,-4.139196 -0.955389,-4.139196 0,0 3.249513,-0.546306 3.249513,-0.546306 M 11.755396,3.5035576 c 0,0 0.449353,2.3550492 0.449353,2.3550492 0,0 -3.979911,0.6690993 -3.979911,0.6690993 0,0 -0.1772211,-2.4007997 -0.1772211,-2.4007997 0,0 3.7077791,-0.6233488 3.7077791,-0.6233488 M 12.4551,7.1707057 c 0,0 0.880275,4.6135083 0.880275,4.6135083 0,0 -4.6646259,0.784214 -4.6646259,0.784214 0,0 -0.3471735,-4.7031334 -0.3471735,-4.7031334 0,0 4.1315244,-0.6945889 4.1315244,-0.6945889 m 1.22645,6.4278093 c 0,0 0.79492,4.166175 0.79492,4.166175 0,0 -5.3556809,0.900393 -5.3556809,0.900393 0,0 -0.3135109,-4.247109 -0.3135109,-4.247109 0,0 4.8742718,-0.819459 4.8742718,-0.819459 M 6.8116906,4.3346895 c 0,0 0.086511,2.4160496 0.086511,2.4160496 0,0 -2.6532734,0.4460663 -2.6532734,0.4460663 0,0 0.09491,-2.4465501 0.09491,-2.4465501 0,0 2.4718529,-0.4155658 2.4718529,-0.4155658 M 6.946401,8.0968242 c 0,0 0.1694737,4.7330078 0.1694737,4.7330078 0,0 -3.1097505,0.52281 -3.1097505,0.52281 0,0 0.1859267,-4.7927587 0.1859267,-4.7927587 0,0 2.7543503,-0.4630591 2.7543503,-0.4630591 m 0.2361207,6.5943038 c 0,0 0.1530412,4.274086 0.1530412,4.274086 0,0 -3.5704543,0.600261 -3.5704543,0.600261 0,0 0.1678985,-4.328041 0.1678985,-4.328041 0,0 3.2495145,-0.546306 3.2495145,-0.546306"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2a7fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-2.8627202"
|
||||
inkscape:transform-center-y="2.0529462" />
|
||||
<path
|
||||
id="path1484"
|
||||
style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.6 KiB |
@@ -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;
|
||||
};
|
||||
|
@@ -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"));
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <gtkmm.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
@@ -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<rtengine::ImageSource *>(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) {
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user