From 3d907fd76ca23d69bcd7d25367c9c94063490d38 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Tue, 13 Mar 2007 18:29:45 +0100 Subject: add devignetting infrastructure --- src/GipfelWidget.H | 2 ++ src/GipfelWidget.cxx | 31 +++++++++++++++-- src/Stitch.H | 3 ++ src/Stitch.cxx | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/gipfel.cxx | 20 ++++++++--- 5 files changed, 141 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index a17009a..f5254e7 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -126,6 +126,8 @@ class GipfelWidget : public Fl_Widget { int get_pixel(GipfelWidget::sample_mode_t, double a_alph, double a_nick, uchar *r, uchar *g, uchar *b); + double get_angle_off(double view, double nick); + int get_distortion_profile_name(char *buf, int buflen); int save_distortion_params(const char *prof_name); diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index eb40590..e88c0cb 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -31,6 +31,7 @@ #define MAX(A,B) ((A)>(B)?(A):(B)) +#define MIN(A,B) ((A)<(B)?(A):(B)) static double pi_d, deg2rad; @@ -671,6 +672,8 @@ int GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, double a_alph, double a_nick, uchar *r, uchar *g, uchar *b) { double px, py; + uchar r_tmp, g_tmp, b_tmp; + int ret; if (img == NULL) { return 1; @@ -681,12 +684,36 @@ GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, } if (m == GipfelWidget::BILINEAR) { - return get_pixel_bilinear(img, px + ((double) img->w()) / 2.0, + ret = get_pixel_bilinear(img, px + ((double) img->w()) / 2.0, py + ((double) img->h()) / 2.0, r, g, b); } else { - return get_pixel_nearest(img, px + ((double) img->w()) / 2.0, + ret = get_pixel_nearest(img, px + ((double) img->w()) / 2.0, py + ((double) img->h()) / 2.0, r, g, b); } + +#if 0 + if (ret == 0) { +fprintf(stderr, "===> %d\n", ret); + double angle = atan(pow(pow(tan(a_alph - pan->parms.a_center), 2.0) + + pow(tan(a_nick - pan->parms.a_nick), 2.0), 0.5)); + double devign = 1.0 / pow(cos(angle), 1.5); + fprintf(stderr, "===> %lf\n", devign); + + *r = (uchar) MIN(rint((double) r_tmp * devign), 255); + *g = (uchar) MIN(rint((double) g_tmp * devign), 255); + *b = (uchar) MIN(rint((double) b_tmp * devign), 255); + } +#endif + + return ret; +} + +double +GipfelWidget::get_angle_off(double a_alph, double a_nick) { + double angle = atan(pow(pow(tan(a_alph - pan->parms.a_center), 2.0) + + pow(tan(a_nick - pan->parms.a_nick), 2.0), 0.5)); + + return angle; } int diff --git a/src/Stitch.H b/src/Stitch.H index dcfc691..13e7bc0 100644 --- a/src/Stitch.H +++ b/src/Stitch.H @@ -33,6 +33,9 @@ class Stitch { int resample(GipfelWidget::sample_mode_t m, int w, int h, double view_start, double view_end); + + int vignette_calib(GipfelWidget::sample_mode_t m, + int w, int h, double view_start, double view_end); }; #endif diff --git a/src/Stitch.cxx b/src/Stitch.cxx index f21c140..35c8c99 100644 --- a/src/Stitch.cxx +++ b/src/Stitch.cxx @@ -9,11 +9,16 @@ #include #include +#include + #include #include "OutputImage.H" #include "Stitch.H" +#define MIN(A,B) ((A)<(B)?(A):(B)) + + static double pi_d = asin(1.0) * 2.0; static double deg2rad = pi_d / 180.0; @@ -77,6 +82,78 @@ Stitch::set_output(const char *file, OutputImage *img) { return ret; } +int +Stitch::vignette_calib(GipfelWidget::sample_mode_t m, + int w, int h, double view_start, double view_end) { + + view_start = view_start * deg2rad; + view_end = view_end * deg2rad; + + double step_view = (view_end - view_start) / w; + uchar r, g, b; + int y_off = h / 2; + int merged_pixel_set; + double radius = (double) w / (view_end -view_start); + + double V1 = 6.220359, V2 = -13.874930, V3 = 9.992582; + int max_samples = 10000, n_samples = 0; + gsl_matrix *X, *cov; + gsl_vector *yv, *c; + double chisq; + + + + X = gsl_matrix_alloc(max_samples, 3); + yv = gsl_vector_alloc(max_samples); + c = gsl_vector_alloc(3); + cov = gsl_matrix_alloc (3, 3); + + for (int y=0; yget_pixel(m, a_view, a_nick, + &r, &g, &b) == 0) { + l2 = (double) r + g + b; + a2 = fabs(gipf[i]->get_angle_off(a_view, a_nick)); + + if (l1 > 0.0 && n_samples < max_samples) { + gsl_matrix_set(X, n_samples, 0, l1 * a1 - l2 * a2); + gsl_matrix_set(X, n_samples, 1, l1 * a1 * a1 - l2 * a2 * a2); + gsl_matrix_set(X, n_samples, 2, l1 * a1 * a1 * a1 - l2 * a2 * a2 * a2); + gsl_vector_set(yv, n_samples, l1 - l2); + n_samples++; + } + + l1 = l2; + a1 = a2; + } + } + } + } + + gsl_multifit_linear_workspace * work + = gsl_multifit_linear_alloc (n_samples, 3); + + gsl_multifit_linear (X, yv, c, cov, &chisq, work); + gsl_multifit_linear_free (work); + + fprintf(stderr, "===> v1 %lf, v2 %lf, v3 %lf (i %d)\n", + gsl_vector_get(c,0), gsl_vector_get(c,1), gsl_vector_get(c,2), n_samples); + + return 0; +} + + int Stitch::resample(GipfelWidget::sample_mode_t m, int w, int h, double view_start, double view_end) { @@ -89,6 +166,7 @@ Stitch::resample(GipfelWidget::sample_mode_t m, int y_off = h / 2; int merged_pixel_set; double radius = (double) w / (view_end -view_start); + double V1 = 6.220359, V2 = -13.874930; if (merged_image) { merged_image->init(w, h); @@ -111,11 +189,22 @@ Stitch::resample(GipfelWidget::sample_mode_t m, break; } else if (gipf[i]->get_pixel(m, a_view, a_nick, &r, &g, &b) == 0) { + double l2 = (double) r + g + b; + double a2 = fabs(gipf[i]->get_angle_off(a_view, a_nick)); + double devign = ( 1 + a2 * V1 + a2 * a2 * V2); + +fprintf(stderr, "==> %lf\n", devign); + r = (uchar) MIN(rint((double) r * devign), 255); + g = (uchar) MIN(rint((double) g * devign), 255); + b = (uchar) MIN(rint((double) b * devign), 255); + if (single_images[i]) { - single_images[i]->set_pixel(x, r, g, b); + single_images[i]->set_pixel(x, r + , g, b); } if (!merged_pixel_set && merged_image) { - merged_image->set_pixel(x, r, g, b); + merged_image->set_pixel(x, r, g, + b); merged_pixel_set++; } } @@ -142,3 +231,4 @@ Stitch::resample(GipfelWidget::sample_mode_t m, return 0; } + diff --git a/src/gipfel.cxx b/src/gipfel.cxx index 5807ae5..3862761 100644 --- a/src/gipfel.cxx +++ b/src/gipfel.cxx @@ -50,9 +50,10 @@ Fl_Value_Input *i_distortion_k0, *i_distortion_k1, *i_distortion_x0; Fl_Box *b_viewpoint; Fl_Menu_Bar *mb; -#define STITCH_PREVIEW 1 -#define STITCH_JPEG 2 -#define STITCH_TIFF 4 +#define STITCH_PREVIEW 1 +#define STITCH_JPEG 2 +#define STITCH_TIFF 4 +#define STITCH_VIGNETTE_CALIB 8 static int stitch(GipfelWidget::sample_mode_t m ,int stitch_w, int stitch_h, double from, double to, int type, const char *path, int argc, char **argv); @@ -397,7 +398,7 @@ int main(int argc, char** argv) { int err, my_argc; int stitch_flag = 0, stitch_w = 2000, stitch_h = 500; int jpeg_flag = 0, tiff_flag = 0, distortion_flag = 0; - int bilinear_flag = 0; + int bilinear_flag = 0, vignette_flag = 0; double stitch_from = 0.0, stitch_to = 380.0; double dist_k0 = 0.0, dist_k1 = 0.0, dist_x0 = 0.0; char *outpath = "/tmp"; @@ -405,7 +406,7 @@ int main(int argc, char** argv) { err = 0; - while ((c = getopt(argc, argv, ":?d:v:sw:h:j:t:u:br:")) != EOF) { + while ((c = getopt(argc, argv, ":?d:v:sw:h:j:t:u:br:V")) != EOF) { switch (c) { case '?': usage(); @@ -420,6 +421,9 @@ int main(int argc, char** argv) { case 's': stitch_flag++; break; + case 'V': + vignette_flag++; + break; case 'r': stitch_flag++; if (optarg && strcmp(optarg, ":")) { @@ -485,6 +489,8 @@ int main(int argc, char** argv) { type = STITCH_JPEG; } else if (tiff_flag) { type = STITCH_TIFF; + } else if (vignette_flag) { + type = STITCH_VIGNETTE_CALIB; } stitch(bilinear_flag?GipfelWidget::BILINEAR:GipfelWidget::NEAREST, @@ -579,6 +585,10 @@ stitch(GipfelWidget::sample_mode_t m, st->resample(m, stitch_w, stitch_h, from, to); + } else if (type = STITCH_VIGNETTE_CALIB) { + + st->vignette_calib(m, stitch_w, stitch_h, from, to); + } else { win = new Fl_Window(0,0, stitch_w, stitch_h); scroll = new Fl_Scroll(0, 0, win->w(), win->h()); -- cgit v1.2.3