diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 6bce68d1a..b19cad59d 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -108,6 +108,7 @@ set(RTENGINESOURCEFILES myfile.cc panasonic_decoders.cc pdaflinesfilter.cc + perspectivecorrection.cc PF_correct_RT.cc pipettebuffer.cc pixelshift.cc diff --git a/rtengine/ashift_dt.c b/rtengine/ashift_dt.c index e25288589..ba2f62271 100644 --- a/rtengine/ashift_dt.c +++ b/rtengine/ashift_dt.c @@ -51,6 +51,7 @@ using namespace std; #define LENSSHIFT_RANGE_SOFT 1 // allowed min/max range for lensshift parameters with manual adjustment #define SHEAR_RANGE 0.2 // allowed min/max range for shear parameter #define SHEAR_RANGE_SOFT 0.5 // allowed min/max range for shear parameter with manual adjustment +#define CAMERA_ANGLE_RANGE_SOFT 80 #define MIN_LINE_LENGTH 5 // the minimum length of a line in pixels to be regarded as relevant #define MAX_TANGENTIAL_DEVIATION 30 // by how many degrees a line may deviate from the +/-180 and +/-90 to be regarded as relevant #define LSD_SCALE 0.99 // LSD: scaling factor for line detection @@ -97,6 +98,8 @@ using namespace std; // implemented by Michael F. Hutt. #include "ashift_nmsimplex.c" +#include "homogeneouscoordinates.h" + //----------------------------------------------------------------------------- // RT: BEGIN COMMENT @@ -292,6 +295,8 @@ typedef struct dt_iop_ashift_params_t float cr; float ct; float cb; + float camera_pitch; + float camera_yaw; } dt_iop_ashift_params_t; typedef struct dt_iop_ashift_line_t @@ -335,10 +340,14 @@ typedef struct dt_iop_ashift_fit_params_t float lensshift_v; float lensshift_h; float shear; + float camera_pitch; + float camera_yaw; float rotation_range; float lensshift_v_range; float lensshift_h_range; float shear_range; + float camera_pitch_range; + float camera_yaw_range; } dt_iop_ashift_fit_params_t; typedef struct dt_iop_ashift_cropfit_params_t @@ -384,6 +393,8 @@ typedef struct dt_iop_ashift_gui_data_t float lensshift_v_range; float lensshift_h_range; float shear_range; + float camera_pitch_range; + float camera_yaw_range; dt_iop_ashift_line_t *lines; int lines_in_width; int lines_in_height; @@ -639,9 +650,16 @@ static void print_roi(const dt_iop_roi_t *roi, const char *label) #define MAT3SWAP(a, b) { float (*tmp)[3] = (a); (a) = (b); (b) = tmp; } +/* static void homography(float *homograph, const float angle, const float shift_v, const float shift_h, const float shear, const float f_length_kb, const float orthocorr, const float aspect, const int width, const int height, dt_iop_ashift_homodir_t dir) +*/ +static void homography(float *homograph, const float angle, const float shift_v, + const float shift_h, const float shear, const float camera_pitch, const + float camera_yaw, const float f_length_kb, const float orthocorr, const + float aspect, const int width, const int height, dt_iop_ashift_homodir_t + dir) { // calculate homograph that combines all translations, rotations // and warping into one single matrix operation. @@ -652,7 +670,11 @@ static void homography(float *homograph, const float angle, const float shift_v, const float u = width; const float v = height; + const float rot = M_PI * angle / 180.0f; + const float pitch = M_PI * camera_pitch / 180.0f; + const float yaw = M_PI * camera_yaw / 180.0f; + /* const float phi = M_PI * angle / 180.0f; const float cosi = cos(phi); const float sini = sin(phi); @@ -675,16 +697,19 @@ static void homography(float *homograph, const float angle, const float shift_v, const float alpha_h = CLAMP(atan(rad_h), -1.5f, 1.5f); const float rt_h = sin(0.5f * alpha_h); const float r_h = fmax(0.1f, 2.0f * (vertifac - 1.0f) * rt_h * rt_h + 1.0f); + */ + const float f = f_length_kb * (sqrt(u*u + v*v) / sqrt(36.0*36.0 + 24.0*24.0)); // three intermediate buffers for matrix calculation ... - float m1[3][3], m2[3][3], m3[3][3]; + float m1[3][3]/*, m2[3][3]*/, m3[3][3]; // ... and some pointers to handle them more intuitively float (*mwork)[3] = m1; - float (*minput)[3] = m2; + //float (*minput)[3] = m2; float (*moutput)[3] = m3; + /* // Step 1: flip x and y coordinates (see above) memset(minput, 0, 9 * sizeof(float)); minput[0][1] = 1.0f; @@ -800,8 +825,43 @@ static void homography(float *homograph, const float angle, const float shift_v, MAT3SWAP(minput, moutput); // multiply mwork * minput -> moutput mat3mul((float *)moutput, (float *)mwork, (float *)minput); + */ + rtengine::homogeneous::Vector center; + center[0] = 0.0f; + center[1] = 0.0f; + center[2] = f; + center[3] = 1.0f; + using rtengine::operator*; + + // Location of image center after rotations. + const rtengine::homogeneous::Vector camera_center_yaw_pitch = + rtengine::homogeneous::rotationMatrix(pitch, rtengine::homogeneous::Axis::X) * + rtengine::homogeneous::rotationMatrix(yaw, rtengine::homogeneous::Axis::Y) * + center; + + const rtengine::homogeneous::Matrix matrix = + // Perspective correction. + rtengine::homogeneous::projectionMatrix(camera_center_yaw_pitch[2], rtengine::homogeneous::Axis::Z) * + rtengine::homogeneous::rotationMatrix(yaw, rtengine::homogeneous::Axis::Y) * + rtengine::homogeneous::rotationMatrix(pitch, rtengine::homogeneous::Axis::X) * + // Rotation. + rtengine::homogeneous::rotationMatrix(rot, rtengine::homogeneous::Axis::Z) * + // Lens/sensor shift and move to z == camera_focal_length. + rtengine::homogeneous::translationMatrix((0.01f * shift_h - 0.5f) * u, (-0.01f * shift_v - 0.5f) * v, f); + + m3[0][0] = matrix[0][0]; + m3[0][1] = matrix[0][1]; + m3[0][2] = matrix[0][3]; + m3[1][0] = matrix[1][0]; + m3[1][1] = matrix[1][1]; + m3[1][2] = matrix[1][3]; + m3[2][0] = matrix[3][0]; + m3[2][1] = matrix[3][1]; + m3[2][2] = matrix[3][3]; + + /* // Step 10: find x/y offsets and apply according correction so that // no negative coordinates occur in output vector float umin = FLT_MAX, vmin = FLT_MAX; @@ -830,6 +890,7 @@ static void homography(float *homograph, const float angle, const float shift_v, MAT3SWAP(minput, moutput); // multiply mwork * minput -> moutput mat3mul((float *)moutput, (float *)mwork, (float *)minput); + */ // on request we either keep the final matrix for forward conversions @@ -1920,10 +1981,16 @@ static double model_fitness(double *params, void *data) float lensshift_v = fit->lensshift_v; float lensshift_h = fit->lensshift_h; float shear = fit->shear; + float camera_pitch = fit->camera_pitch; + float camera_yaw = fit->camera_yaw; float rotation_range = fit->rotation_range; + /* float lensshift_v_range = fit->lensshift_v_range; float lensshift_h_range = fit->lensshift_h_range; float shear_range = fit->shear_range; + */ + float camera_pitch_range = fit->camera_pitch_range; + float camera_yaw_range = fit->camera_yaw_range; int pcount = 0; @@ -1934,6 +2001,7 @@ static double model_fitness(double *params, void *data) pcount++; } + /* if(isnan(lensshift_v)) { lensshift_v = ilogit(params[pcount], -lensshift_v_range, lensshift_v_range); @@ -1951,6 +2019,19 @@ static double model_fitness(double *params, void *data) shear = ilogit(params[pcount], -shear_range, shear_range); pcount++; } + */ + + if(isnan(camera_pitch)) + { + camera_pitch = ilogit(params[pcount], -camera_pitch_range, camera_pitch_range); + pcount++; + } + + if(isnan(camera_yaw)) + { + camera_yaw = ilogit(params[pcount], -camera_yaw_range, camera_yaw_range); + pcount++; + } assert(pcount == fit->params_count); @@ -1960,7 +2041,7 @@ static double model_fitness(double *params, void *data) // generate homograph out of the parameters float homograph[3][3]; - homography((float *)homograph, rotation, lensshift_v, lensshift_h, shear, f_length_kb, + homography((float *)homograph, rotation, lensshift_v, lensshift_h, shear, camera_pitch, camera_yaw, f_length_kb, orthocorr, aspect, width, height, ASHIFT_HOMOGRAPH_FORWARD); // accounting variables @@ -2018,8 +2099,12 @@ static double model_fitness(double *params, void *data) //double sum = sqrt(v + h) * 1.0e6; #ifdef ASHIFT_DEBUG + /* printf("fitness with rotation %f, lensshift_v %f, lensshift_h %f, shear %f -> lines %d, quality %10f\n", rotation, lensshift_v, lensshift_h, shear, count, sum); + */ + printf("fitness with rotation %f, camera_pitch %f, camera_yaw %f -> lines %d, quality %10f\n", + rotation, camera_pitch, camera_yaw, count, sum); #endif return sum; @@ -2050,10 +2135,14 @@ static dt_iop_ashift_nmsresult_t nmsfit(dt_iop_module_t *module, dt_iop_ashift_p fit.lensshift_v = p->lensshift_v; fit.lensshift_h = p->lensshift_h; fit.shear = p->shear; + fit.camera_pitch = p->camera_pitch; + fit.camera_yaw = p->camera_yaw; fit.rotation_range = g->rotation_range; fit.lensshift_v_range = g->lensshift_v_range; fit.lensshift_h_range = g->lensshift_h_range; fit.shear_range = g->shear_range; + fit.camera_pitch_range = g->camera_pitch_range; + fit.camera_yaw_range = g->camera_yaw_range; fit.linetype = ASHIFT_LINE_RELEVANT | ASHIFT_LINE_SELECTED; fit.linemask = ASHIFT_LINE_MASK; fit.params_count = 0; @@ -2086,6 +2175,7 @@ static dt_iop_ashift_nmsresult_t nmsfit(dt_iop_module_t *module, dt_iop_ashift_p fit.rotation = NAN; } + /* if(mdir & ASHIFT_FIT_LENS_VERT) { // we fit vertical lens shift @@ -2112,6 +2202,25 @@ static dt_iop_ashift_nmsresult_t nmsfit(dt_iop_module_t *module, dt_iop_ashift_p pcount++; fit.shear = NAN; } + */ + + if(mdir & ASHIFT_FIT_LENS_VERT) + { + // we fit pitch + fit.params_count++; + params[pcount] = logit(fit.camera_pitch, -fit.camera_pitch_range, fit.camera_pitch_range); + pcount++; + fit.camera_pitch = NAN; + } + + if(mdir & ASHIFT_FIT_LENS_HOR) + { + // we fit yaw + fit.params_count++; + params[pcount] = logit(fit.camera_yaw, -fit.camera_yaw_range, fit.camera_yaw_range); + pcount++; + fit.camera_yaw = NAN; + } if(mdir & ASHIFT_FIT_LINES_VERT) { @@ -2162,14 +2271,23 @@ static dt_iop_ashift_nmsresult_t nmsfit(dt_iop_module_t *module, dt_iop_ashift_p // fit was successful: now consolidate the results (order matters!!!) pcount = 0; fit.rotation = isnan(fit.rotation) ? ilogit(params[pcount++], -fit.rotation_range, fit.rotation_range) : fit.rotation; + /* fit.lensshift_v = isnan(fit.lensshift_v) ? ilogit(params[pcount++], -fit.lensshift_v_range, fit.lensshift_v_range) : fit.lensshift_v; fit.lensshift_h = isnan(fit.lensshift_h) ? ilogit(params[pcount++], -fit.lensshift_h_range, fit.lensshift_h_range) : fit.lensshift_h; fit.shear = isnan(fit.shear) ? ilogit(params[pcount++], -fit.shear_range, fit.shear_range) : fit.shear; + */ + fit.camera_pitch = isnan(fit.camera_pitch) ? ilogit(params[pcount++], -fit.camera_pitch_range, fit.camera_pitch_range) : fit.camera_pitch; + fit.camera_yaw = isnan(fit.camera_yaw) ? ilogit(params[pcount++], -fit.camera_yaw_range, fit.camera_yaw_range) : fit.camera_yaw; #ifdef ASHIFT_DEBUG + /* printf("params after optimization (%d iterations): rotation %f, lensshift_v %f, lensshift_h %f, shear %f\n", iter, fit.rotation, fit.lensshift_v, fit.lensshift_h, fit.shear); + */ + printf("params after optimization (%d iterations): rotation %f, camera_pitch %f, camera_yaw %f\n", + iter, fit.rotation, fit.camera_pitch, fit.camera_yaw); #endif + /* // sanity check: in case of extreme values the image gets distorted so strongly that it spans an insanely huge area. we check that // case and assume values that increase the image area by more than a factor of 4 as being insane. float homograph[3][3]; @@ -2202,12 +2320,17 @@ static dt_iop_ashift_nmsresult_t nmsfit(dt_iop_module_t *module, dt_iop_ashift_p #endif return NMS_INSANE; } + */ // now write the results into structure p p->rotation = fit.rotation; + /* p->lensshift_v = fit.lensshift_v; p->lensshift_h = fit.lensshift_h; p->shear = fit.shear; + */ + p->camera_pitch = fit.camera_pitch; + p->camera_yaw = fit.camera_yaw; return NMS_SUCCESS; } @@ -2291,6 +2414,10 @@ static void model_probe(dt_iop_module_t *module, dt_iop_ashift_params_t *p, dt_i #endif // if 0 //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// RT: BEGIN COMMENT (no crop support yet) +//----------------------------------------------------------------------------- +#if 0 // function to keep crop fitting parameters within constraints static void crop_constraint(double *params, int pcount) { @@ -2383,7 +2510,12 @@ static double crop_fitness(double *params, void *data) // and return -A to allow Nelder-Mead simplex to search for the minimum return -A; } +#endif // if 0 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// RT: BEGIN COMMENT +#if 0 // strategy: for a given center of the crop area and a specific aspect angle // we calculate the largest crop area that still lies within the output image; // now we allow a Nelder-Mead simplex to search for the center coordinates @@ -2561,9 +2693,11 @@ failed: dt_control_log(_("automatic cropping failed")); return; } +#endif // if 0 +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -// RT: BEGIN COMMENT +// RT: BEGIN COMMENT (no crop support yet) //----------------------------------------------------------------------------- #if 0 // manually adjust crop area by shifting its center @@ -2804,8 +2938,10 @@ static int do_fit(dt_iop_module_t *module, dt_iop_ashift_params_t *p, dt_iop_ash g->fitting = 0; + /* // finally apply cropping do_crop(module, p); + */ return TRUE; @@ -3042,7 +3178,7 @@ int process_cl(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_m } float ihomograph[3][3]; - homography((float *)ihomograph, d->rotation, d->lensshift_v, d->lensshift_h, d->shear, d->f_length_kb, + homography((float *)ihomograph, d->rotation, d->lensshift_v, d->lensshift_h, d->shear, d->f_length_kb, d->camera_pitch, d->camera_yaw, d->orthocorr, d->aspect, piece->buf_in.width, piece->buf_in.height, ASHIFT_HOMOGRAPH_INVERTED); // clipping offset diff --git a/rtengine/perspectivecorrection.cc b/rtengine/perspectivecorrection.cc index 724262b15..fe89b7f5f 100644 --- a/rtengine/perspectivecorrection.cc +++ b/rtengine/perspectivecorrection.cc @@ -55,6 +55,8 @@ #include #include "../rtgui/threadutils.h" +#include "colortemp.h" +#include "imagefloat.h" #include "settings.h" namespace rtengine { extern const Settings *settings; } @@ -97,76 +99,12 @@ inline int mat3inv(float *const dst, const float *const src) #include "ashift_dt.c" -procparams::PerspectiveParams import_meta(const procparams::PerspectiveParams &pp, const FramesMetaData *metadata) -{ - procparams::PerspectiveParams ret(pp); - if (metadata && ret.flength == 0) { - double f = metadata->getFocalLen(); - double f35 = metadata->getFocalLen35mm(); - if (f > 0 && f35 > 0) { - ret.flength = f; - ret.cropfactor = f35 / f; - } else if (f > 0) { - ret.flength = f; - } - } - return ret; -} - } // namespace -PerspectiveCorrection::PerspectiveCorrection(): - ok_(false), - scale_(1.0), - offx_(0.0), - offy_(0.0) -{ -} - - -void PerspectiveCorrection::init(int width, int height, const procparams::PerspectiveParams ¶ms, bool fill, const FramesMetaData *metadata) -{ - if (params.enabled) { - auto pp = import_meta(params, metadata); - homography((float *)ihomograph_, params.angle, params.vertical / 100.0, -params.horizontal / 100.0, params.shear / 100.0, params.flength * params.cropfactor, 100.f, params.aspect, width, height, ASHIFT_HOMOGRAPH_INVERTED); - - ok_ = true; - calc_scale(width, height, pp, fill); - } else { - ok_ = false; - } -} - - -inline void PerspectiveCorrection::correct(double &x, double &y, double scale, double offx, double offy) -{ - if (ok_) { - float pin[3], pout[3]; - pout[0] = x; - pout[1] = y; - pout[0] *= scale; - pout[1] *= scale; - pout[0] += offx; - pout[1] += offy; - pout[2] = 1.f; - mat3mulv(pin, (float *)ihomograph_, pout); - pin[0] /= pin[2]; - pin[1] /= pin[2]; - x = pin[0]; - y = pin[1]; - } -} - - -void PerspectiveCorrection::operator()(double &x, double &y) -{ - correct(x, y, scale_, offx_, offy_); -} - - namespace { +/* std::vector get_corners(int w, int h) { int x1 = 0, y1 = 0; @@ -180,9 +118,10 @@ std::vector get_corners(int w, int h) }; return corners; } +*/ void init_dt_structures(dt_iop_ashift_params_t *p, dt_iop_ashift_gui_data_t *g, - const procparams::PerspectiveParams *params) + const procparams::ProcParams *params) { dt_iop_ashift_params_t dp = { 0.0f, @@ -199,7 +138,9 @@ void init_dt_structures(dt_iop_ashift_params_t *p, dt_iop_ashift_gui_data_t *g, 0.0f, 1.0f, 0.0f, - 1.0f + 1.0f, + 0.0f, + 0.0f }; *p = dp; @@ -223,6 +164,8 @@ void init_dt_structures(dt_iop_ashift_params_t *p, dt_iop_ashift_gui_data_t *g, g->lensshift_v_range = LENSSHIFT_RANGE_SOFT; g->lensshift_h_range = LENSSHIFT_RANGE_SOFT; g->shear_range = SHEAR_RANGE_SOFT; + g->camera_pitch_range = CAMERA_ANGLE_RANGE_SOFT; + g->camera_yaw_range = CAMERA_ANGLE_RANGE_SOFT; g->lines_suppressed = 0; g->lines_version = 0; g->show_guides = 0; @@ -242,17 +185,18 @@ void init_dt_structures(dt_iop_ashift_params_t *p, dt_iop_ashift_gui_data_t *g, g->crop_cx = g->crop_cy = 1.0f; if (params) { - p->rotation = params->angle; - p->lensshift_v = params->vertical / 100.0; - p->lensshift_h = -params->horizontal / 100.0; - p->shear = params->shear / 100.0; - p->f_length = params->flength; - p->crop_factor = params->cropfactor; - p->aspect = params->aspect; + p->rotation = params->rotate.degree; + p->lensshift_v = params->perspective.camera_shift_vert; + p->lensshift_h = params->perspective.camera_shift_horiz; + p->f_length = params->perspective.camera_focal_length; + p->crop_factor = params->perspective.camera_crop_factor; + p->camera_pitch = params->perspective.camera_pitch; + p->camera_yaw = params->perspective.camera_yaw; } } +/* void get_view_size(int w, int h, const procparams::PerspectiveParams ¶ms, double &cw, double &ch) { double min_x = RT_INFINITY, max_x = -RT_INFINITY; @@ -278,47 +222,27 @@ void get_view_size(int w, int h, const procparams::PerspectiveParams ¶ms, do cw = max_x - min_x; ch = max_y - min_y; } +*/ } // namespace -void PerspectiveCorrection::calc_scale(int w, int h, const procparams::PerspectiveParams ¶ms, bool fill) +PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *src, bool corr_pitch, bool corr_yaw, const procparams::ProcParams *pparams, const FramesMetaData *metadata) { - double cw, ch; - get_view_size(w, h, params, cw, ch); - - if (!fill) { - scale_ = max(cw / double(w), ch / double(h)); - offx_ = (cw - w * scale_) * 0.5; - offy_ = (ch - h * scale_) * 0.5; - } else { - dt_iop_ashift_params_t p; - dt_iop_ashift_gui_data_t g; - init_dt_structures(&p, &g, ¶ms); - dt_iop_module_t module = { &g, false }; - g.buf_width = w; - g.buf_height = h; - p.cropmode = ASHIFT_CROP_ASPECT; - do_crop(&module, &p); - offx_ = p.cl * cw; - offy_ = p.ct * ch; - scale_ = (p.cr - p.cl) * cw/double(w); - } -} - - -procparams::PerspectiveParams PerspectiveCorrection::autocompute(ImageSource *src, Direction dir, const procparams::ProcParams *pparams, const FramesMetaData *metadata) -{ - auto pcp = import_meta(pparams->perspective, metadata); + auto pcp = procparams::PerspectiveParams(pparams->perspective); procparams::PerspectiveParams dflt; + /* pcp.horizontal = dflt.horizontal; pcp.vertical = dflt.vertical; pcp.angle = dflt.angle; pcp.shear = dflt.shear; + */ + pcp.camera_pitch = dflt.camera_pitch; + pcp.camera_yaw = dflt.camera_yaw; dt_iop_ashift_params_t p; dt_iop_ashift_gui_data_t g; - init_dt_structures(&p, &g, &pcp); + init_dt_structures(&p, &g, pparams); dt_iop_module_t module; module.gui_data = &g; module.is_raw = src->isRAW(); @@ -336,9 +260,11 @@ procparams::PerspectiveParams PerspectiveCorrection::autocompute(ImageSource *sr neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); neutral.icm.outputProfile = ColorManagementParams::NoICMString; - src->getImage(src->getWB(), tr, img.get(), pp, neutral.exposure, neutral.raw); + src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw); src->convertColorSpace(img.get(), pparams->icm, src->getWB()); + neutral.commonTrans.autofill = false; // Ensures crop factor is correct. + // TODO: Ensure image borders of rotated image do not get detected as lines. neutral.rotate = pparams->rotate; neutral.distortion = pparams->distortion; neutral.lensProf = pparams->lensProf; @@ -371,16 +297,12 @@ procparams::PerspectiveParams PerspectiveCorrection::autocompute(ImageSource *sr } dt_iop_ashift_fitaxis_t fitaxis = ASHIFT_FIT_NONE; - switch (dir) { - case HORIZONTAL: - fitaxis = ASHIFT_FIT_HORIZONTALLY; - break; - case VERTICAL: - fitaxis = ASHIFT_FIT_VERTICALLY; - break; - default: + if (corr_pitch && corr_yaw) { fitaxis = ASHIFT_FIT_BOTH_SHEAR; - break; + } else if (corr_pitch) { + fitaxis = ASHIFT_FIT_VERTICALLY; + } else if (corr_yaw) { + fitaxis = ASHIFT_FIT_HORIZONTALLY; } // reset the pseudo-random seed for repeatability -- ashift_dt uses rand() @@ -388,7 +310,11 @@ procparams::PerspectiveParams PerspectiveCorrection::autocompute(ImageSource *sr srand(1); auto res = do_get_structure(&module, &p, ASHIFT_ENHANCE_EDGES) && do_fit(&module, &p, fitaxis); - procparams::PerspectiveParams retval = pparams->perspective; + Params retval = { + .angle = p.rotation, + .pitch = p.camera_pitch, + .yaw = p.camera_yaw + }; // cleanup the gui if (g.lines) free(g.lines); @@ -396,16 +322,16 @@ procparams::PerspectiveParams PerspectiveCorrection::autocompute(ImageSource *sr if (g.points_idx) free(g.points_idx); free(g.buf); - if (res) { - retval.horizontal = -p.lensshift_h * 100; - retval.vertical = p.lensshift_v * 100; - retval.angle = p.rotation; - retval.shear = p.shear * 100; + if (!res) { + retval.angle = pparams->rotate.degree; + retval.pitch = pparams->perspective.camera_pitch; + retval.yaw = pparams->perspective.camera_yaw; } return retval; } +/* void PerspectiveCorrection::autocrop(int width, int height, bool fixratio, const procparams::PerspectiveParams ¶ms, const FramesMetaData *metadata, int &x, int &y, int &w, int &h) { auto pp = import_meta(params, metadata); @@ -429,5 +355,6 @@ void PerspectiveCorrection::autocrop(int width, int height, bool fixratio, const w = (p.cr - p.cl) * cw; h = (p.cb - p.ct) * ch; } +*/ } // namespace rtengine diff --git a/rtengine/perspectivecorrection.h b/rtengine/perspectivecorrection.h index 1b52941b2..bf7cfa08d 100644 --- a/rtengine/perspectivecorrection.h +++ b/rtengine/perspectivecorrection.h @@ -28,28 +28,16 @@ namespace rtengine { class PerspectiveCorrection { public: - PerspectiveCorrection(); - void init(int width, int height, const procparams::PerspectiveParams ¶ms, bool fill, const FramesMetaData *meta); - void operator()(double &x, double &y); - - enum Direction { - HORIZONTAL, - VERTICAL, - BOTH + struct Params + { + double angle; + double pitch; + double yaw; }; - static procparams::PerspectiveParams autocompute(ImageSource *src, Direction dir, const procparams::ProcParams *pparams, const FramesMetaData *metadata); - static void autocrop(int width, int height, bool fixratio, const procparams::PerspectiveParams ¶ms, const FramesMetaData *metadata, int &x, int &y, int &w, int &h); + static Params autocompute(ImageSource *src, bool corr_pitch, bool corr_yaw, const procparams::ProcParams *pparams, const FramesMetaData *metadata); -private: - void correct(double &x, double &y, double scale, double offx, double offy); - void calc_scale(int w, int h, const procparams::PerspectiveParams ¶ms, bool fill); - - bool ok_; - double scale_; - double offx_; - double offy_; - float ihomograph_[3][3]; + //static void autocrop(int width, int height, bool fixratio, const procparams::PerspectiveParams ¶ms, const FramesMetaData *metadata, int &x, int &y, int &w, int &h); }; } // namespace rtengine