From c00e603b4bfe336683c713cca80cbba47e639678 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Wed, 7 Mar 2007 22:25:03 +0100 Subject: add GUI stuff for x0 --- src/GipfelWidget.H | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/GipfelWidget.H') diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index 3671a87..a17009a 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -115,9 +115,9 @@ class GipfelWidget : public Fl_Widget { void set_projection(ProjectionLSQ::Projection_t p); - void get_distortion_params(double *k0, double *k1); + void get_distortion_params(double *k0, double *k1i, double *x0); - void set_distortion_params(double k0, double k1); + void set_distortion_params(double k0, double k1, double x0); Hills *get_mountains(); -- cgit v1.2.3 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/GipfelWidget.H') 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 From d09316016e4e0b782d784785641fec91de7d58a6 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Fri, 16 Mar 2007 18:35:35 +0100 Subject: switch to 16 bit color depth internally --- src/GipfelWidget.H | 8 ++++---- src/GipfelWidget.cxx | 49 ++++++++++++++++++---------------------------- src/JPEGOutputImage.H | 2 +- src/JPEGOutputImage.cxx | 8 ++++---- src/OutputImage.H | 4 ++-- src/OutputImage.cxx | 4 ++-- src/PreviewOutputImage.H | 2 +- src/PreviewOutputImage.cxx | 8 ++++---- src/Stitch.H | 2 +- src/Stitch.cxx | 39 +++++++++++++++++++++--------------- src/TIFFOutputImage.H | 2 +- src/TIFFOutputImage.cxx | 8 ++++---- 12 files changed, 66 insertions(+), 70 deletions(-) (limited to 'src/GipfelWidget.H') diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index f5254e7..8cb6d3f 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -39,13 +39,13 @@ class GipfelWidget : public Fl_Widget { int get_rel_track_width(Hill *m); static int get_pixel_nearest(Fl_Image *img, double x, double y, - uchar *r, uchar *g, uchar *b); + int *r, int *g, int *b); static int get_pixel_bilinear(Fl_Image *img, double x, double y, - uchar *r, uchar *g, uchar *b); + int *r, int *g, int *b); static int get_pixel(Fl_Image *img, int x, int y, - uchar *r, uchar *g, uchar *b); + int *r, int *g, int *b); public: typedef enum { @@ -124,7 +124,7 @@ class GipfelWidget : public Fl_Widget { int comp_params(); int get_pixel(GipfelWidget::sample_mode_t, - double a_alph, double a_nick, uchar *r, uchar *g, uchar *b); + double a_alph, double a_nick, int *r, int *g, int *b); double get_angle_off(double view, double nick); diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index e88c0cb..1eb8866 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -670,9 +670,9 @@ GipfelWidget::handle(int event) { int GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, - double a_alph, double a_nick, uchar *r, uchar *g, uchar *b) { + double a_alph, double a_nick, int *r, int *g, int *b) { double px, py; - uchar r_tmp, g_tmp, b_tmp; + int r_tmp, g_tmp, b_tmp; int ret; if (img == NULL) { @@ -691,20 +691,6 @@ GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, 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; } @@ -718,7 +704,7 @@ GipfelWidget::get_angle_off(double a_alph, double a_nick) { int GipfelWidget::get_pixel_nearest(Fl_Image *img, double x, double y, - uchar *r, uchar *g, uchar *b) { + int *r, int *g, int *b) { if (isnan(x) || isnan(y)) { return 1; } else { @@ -728,10 +714,10 @@ GipfelWidget::get_pixel_nearest(Fl_Image *img, double x, double y, int GipfelWidget::get_pixel_bilinear(Fl_Image *img, double x, double y, - uchar *r, uchar *g, uchar *b) { - uchar a_r[4] = {0, 0, 0, 0}; - uchar a_g[4] = {0, 0, 0, 0}; - uchar a_b[4] = {0, 0, 0, 0}; + int *r, int *g, int *b) { + int a_r[4] = {0, 0, 0, 0}; + int a_g[4] = {0, 0, 0, 0}; + int a_b[4] = {0, 0, 0, 0}; float v0 , v1; int fl_x = (int) floor(x); int fl_y = (int) floor(y); @@ -748,15 +734,15 @@ GipfelWidget::get_pixel_bilinear(Fl_Image *img, double x, double y, v0 = a_r[0] * (1 - (x - fl_x)) + a_r[1] * (x - fl_x); v1 = a_r[2] * (1 - (x - fl_x)) + a_r[3] * (x - fl_x); - *r = (uchar) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); + *r = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); v0 = a_g[0] * (1 - (x - fl_x)) + a_g[1] * (x - fl_x); v1 = a_g[2] * (1 - (x - fl_x)) + a_g[3] * (x - fl_x); - *g = (uchar) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); + *g = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); v0 = a_b[0] * (1 - (x - fl_x)) + a_b[1] * (x - fl_x); v1 = a_b[2] * (1 - (x - fl_x)) + a_b[3] * (x - fl_x); - *b = (uchar) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); + *b = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); if (n >= 1) { return 1; @@ -767,7 +753,7 @@ GipfelWidget::get_pixel_bilinear(Fl_Image *img, double x, double y, int GipfelWidget::get_pixel(Fl_Image *img, int x, int y, - uchar *r, uchar *g, uchar *b) { + int *r, int *g, int *b) { if ( img->d() == 0 ) { return 1; } @@ -779,16 +765,16 @@ GipfelWidget::get_pixel(Fl_Image *img, int x, int y, switch (img->count()) { case 1: { // bitmap - const char *buf = img->data()[0]; + const unsigned char *buf = (const unsigned char*) img->data()[0]; switch (img->d()) { case 1: *r = *g = *b = *(buf+index); break; case 3: // 24bit - *r = *(buf+index+0); - *g = *(buf+index+1); - *b = *(buf+index+2); + *r = (int) *(buf+index+0); + *g = (int) *(buf+index+1); + *b = (int) *(buf+index+2); break; default: // ?? printf("Not supported: chans=%d\n", img->d()); @@ -801,8 +787,11 @@ GipfelWidget::get_pixel(Fl_Image *img, int x, int y, return 1; } - return 0; + *r = *r * 255; + *g = *g * 255; + *b = *b * 255; + return 0; } int diff --git a/src/JPEGOutputImage.H b/src/JPEGOutputImage.H index b3554c8..a4b8f47 100644 --- a/src/JPEGOutputImage.H +++ b/src/JPEGOutputImage.H @@ -32,7 +32,7 @@ class JPEGOutputImage : OutputImage { protected: int init_internal(int w, int h); - int set_pixel_internal(int x, char r, char g, char b); + int set_pixel_internal(int x, int r, int g, int b); int next_line_internal(); diff --git a/src/JPEGOutputImage.cxx b/src/JPEGOutputImage.cxx index 6e685d0..bfe4595 100644 --- a/src/JPEGOutputImage.cxx +++ b/src/JPEGOutputImage.cxx @@ -68,10 +68,10 @@ JPEGOutputImage::init_internal(int w1, int h1) { } int -JPEGOutputImage::set_pixel_internal(int x, char r, char g, char b) { - row[x*3+0] = r; - row[x*3+1] = g; - row[x*3+2] = b; +JPEGOutputImage::set_pixel_internal(int x, int r, int g, int b) { + row[x*3+0] = (unsigned char) r; + row[x*3+1] = (unsigned char) g; + row[x*3+2] = (unsigned char) b; return 0; } diff --git a/src/OutputImage.H b/src/OutputImage.H index 7c9f0fd..17955b9 100644 --- a/src/OutputImage.H +++ b/src/OutputImage.H @@ -19,7 +19,7 @@ class OutputImage { virtual int init(int w1, int h1); - int set_pixel(int x, char r, char g, char b); + int set_pixel(int x, int r, int g, int b); int next_line(); @@ -30,7 +30,7 @@ class OutputImage { virtual int init_internal(int w1, int h1); - virtual int set_pixel_internal(int x, char r, char g, char b); + virtual int set_pixel_internal(int x, int r, int g, int b); virtual int next_line_internal(); diff --git a/src/OutputImage.cxx b/src/OutputImage.cxx index ddf8e14..f981f18 100644 --- a/src/OutputImage.cxx +++ b/src/OutputImage.cxx @@ -35,7 +35,7 @@ OutputImage::init_internal(int w1, int h1) { } int -OutputImage::set_pixel(int x, char r, char g, char b) { +OutputImage::set_pixel(int x, int r, int g, int b) { if (!initialized || x < 0 || x >= W) { return 1; } else { @@ -44,7 +44,7 @@ OutputImage::set_pixel(int x, char r, char g, char b) { } int -OutputImage::set_pixel_internal(int x, char r, char g, char b) { +OutputImage::set_pixel_internal(int x, int r, int g, int b) { return 0; } diff --git a/src/PreviewOutputImage.H b/src/PreviewOutputImage.H index 8b41684..cbd55a6 100644 --- a/src/PreviewOutputImage.H +++ b/src/PreviewOutputImage.H @@ -29,7 +29,7 @@ class PreviewOutputImage : OutputImage , public Fl_Widget { protected: int init_internal(int w, int h); - int set_pixel_internal(int x, char r, char g, char b); + int set_pixel_internal(int x, int r, int g, int b); int next_line_internal(); diff --git a/src/PreviewOutputImage.cxx b/src/PreviewOutputImage.cxx index 86dadee..0ae182e 100644 --- a/src/PreviewOutputImage.cxx +++ b/src/PreviewOutputImage.cxx @@ -35,15 +35,15 @@ PreviewOutputImage::init_internal(int w, int h) { int -PreviewOutputImage::set_pixel_internal(int x, char r, char g, char b) { +PreviewOutputImage::set_pixel_internal(int x, int r, int g, int b) { if (!data) { return 1; } long index = (line * w() * d + (x * d)); - *(data+index+0) = r; - *(data+index+1) = g; - *(data+index+2) = b; + *(data+index+0) = (unsigned char) (r / 255); + *(data+index+1) = (unsigned char) (g / 255); + *(data+index+2) = (unsigned char) (b / 255); return 0; } diff --git a/src/Stitch.H b/src/Stitch.H index 9fe3c15..b5fb6fd 100644 --- a/src/Stitch.H +++ b/src/Stitch.H @@ -23,7 +23,7 @@ class Stitch { OutputImage *single_images[MAX_PICS]; OutputImage *merged_image; - uchar color_correct(uchar c, double a, int pic, int color); + int color_correct(int c, double a, int pic, int color); public: Stitch(); diff --git a/src/Stitch.cxx b/src/Stitch.cxx index 3876e77..af0df91 100644 --- a/src/Stitch.cxx +++ b/src/Stitch.cxx @@ -17,7 +17,7 @@ #include "Stitch.H" #define MIN(A,B) ((A)<(B)?(A):(B)) - +#define MAX_VALUE 65025 static double pi_d = asin(1.0) * 2.0; static double deg2rad = pi_d / 180.0; @@ -99,12 +99,12 @@ Stitch::vignette_calib(GipfelWidget::sample_mode_t m, view_end = view_end * deg2rad; double step_view = (view_end - view_start) / w; - uchar r, g, b; + int r, g, b; int y_off = h / 2; int merged_pixel_set; double radius = (double) w / (view_end -view_start); - int max_samples = 5000 * 3, n_samples = 0; + int max_samples = 50000 * 3, n_samples = 0; int ret; int n_vars = 2 + num_pics * 3 ; gsl_matrix *X, *cov; @@ -129,7 +129,7 @@ Stitch::vignette_calib(GipfelWidget::sample_mode_t m, a_view = view_start + x * step_view; merged_pixel_set = 0; double a1, a2; - uchar c1[3], c2[3]; + int c1[3], c2[3]; double c1d[3], c2d[3]; for (int p1=0; p1get_pixel(m, a_view, a_nick, &c1[0], &c1[1], &c1[2]) == 0) { - for (int l = 0; l<3; l++) { c1d[l] = (double) c1[l]; } @@ -159,12 +158,20 @@ Stitch::vignette_calib(GipfelWidget::sample_mode_t m, a2 = gipf[p2]->get_angle_off(a_view, a_nick); if (n_samples < max_samples && - c1[0] < 200 && c1[1] < 200 && c1[2] < 200 && - c2[0] < 200 && c2[1] < 200 && c2[2] < 200 && - c1[0] > 20 && c1[1] > 20 && c1[2] > 20 && - c2[0] > 20 && c2[1] > 20 && c2[2] > 20 && - fabs(c1d[1] / c1d[0] - c2d[1] / c2d[0]) < 0.02 && - fabs(c1d[2] / c1d[0] - c2d[2] / c2d[0]) < 0.02 ) { + c1[0] < MAX_VALUE * 0.8 && + c1[1] < MAX_VALUE * 0.8 && + c1[2] < MAX_VALUE * 0.8 && + c2[0] < MAX_VALUE * 0.8 && + c2[1] < MAX_VALUE * 0.8 && + c2[2] < MAX_VALUE * 0.8 && + c1[0] > MAX_VALUE * 0.2 && + c1[1] > MAX_VALUE * 0.2 && + c1[2] > MAX_VALUE * 0.2 && + c2[0] > MAX_VALUE * 0.2 && + c2[1] > MAX_VALUE * 0.2 && + c2[2] > MAX_VALUE * 0.2) { +// fabs(c1d[1] / c1d[0] - c2d[1] / c2d[0]) < 0.2 && +// fabs(c1d[2] / c1d[0] - c2d[2] / c2d[0]) < 0.2 ) { for (int l = 0; l<3; l++) { if (p1 == 0) { @@ -186,7 +193,7 @@ Stitch::vignette_calib(GipfelWidget::sample_mode_t m, } if (merged_image) { - merged_image->set_pixel(x, 255, 0, 0); + merged_image->set_pixel(x, 65025, 0, 0); merged_pixel_set++; } } @@ -233,15 +240,15 @@ fprintf(stderr, "==> V1 %f V2 %f\n", V1, V2); return 0; } -uchar -Stitch::color_correct(uchar c, double a, int pic, int color) { +int +Stitch::color_correct(int c, double a, int pic, int color) { double cd = (double) c; cd = cd * (color_adjust[pic][color] + V1 * a * a + V2 * a * a * a * a); - return (uchar) MIN(rint(cd), 255.0); + return (int) MIN(rint(cd), 65025.0); } int @@ -252,7 +259,7 @@ Stitch::resample(GipfelWidget::sample_mode_t m, view_end = view_end * deg2rad; double step_view = (view_end - view_start) / w; - uchar r, g, b; + int r, g, b; int y_off = h / 2; int merged_pixel_set; double radius = (double) w / (view_end -view_start); diff --git a/src/TIFFOutputImage.H b/src/TIFFOutputImage.H index 820a281..ce61462 100644 --- a/src/TIFFOutputImage.H +++ b/src/TIFFOutputImage.H @@ -26,7 +26,7 @@ class TIFFOutputImage : OutputImage { protected: int init_internal(int w, int h); - int set_pixel_internal(int x, char r, char g, char b); + int set_pixel_internal(int x, int r, int g, int b); int next_line_internal(); diff --git a/src/TIFFOutputImage.cxx b/src/TIFFOutputImage.cxx index 397caac..4034c97 100644 --- a/src/TIFFOutputImage.cxx +++ b/src/TIFFOutputImage.cxx @@ -61,10 +61,10 @@ TIFFOutputImage::init_internal(int w1, int h1) { } int -TIFFOutputImage::set_pixel_internal(int x, char r, char g, char b) { - row[x*4+0] = r; - row[x*4+1] = g; - row[x*4+2] = b; +TIFFOutputImage::set_pixel_internal(int x, int r, int g, int b) { + row[x*4+0] = (unsigned char) r; + row[x*4+1] = (unsigned char) g; + row[x*4+2] = (unsigned char) b; row[x*4+3] = 255; return 0; -- cgit v1.2.3 From 5432343cc8bd34a77a1584be33abbd53cdd6e373 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Sun, 18 Mar 2007 12:22:50 +0100 Subject: implement bicubic interpolation --- src/GipfelWidget.H | 6 +++++- src/GipfelWidget.cxx | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/gipfel.cxx | 2 +- 3 files changed, 56 insertions(+), 2 deletions(-) (limited to 'src/GipfelWidget.H') diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index 8cb6d3f..ed251ef 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -44,13 +44,17 @@ class GipfelWidget : public Fl_Widget { static int get_pixel_bilinear(Fl_Image *img, double x, double y, int *r, int *g, int *b); + static int get_pixel_bicubic(Fl_Image *img, double x, double y, + int *r, int *g, int *b); + static int get_pixel(Fl_Image *img, int x, int y, int *r, int *g, int *b); public: typedef enum { NEAREST = 0, - BILINEAR = 1 + BILINEAR = 1, + BICUBIC = 2 } sample_mode_t; GipfelWidget(int X,int Y,int W, int H); diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index 1eb8866..2daea2a 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -686,6 +686,9 @@ GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, if (m == GipfelWidget::BILINEAR) { ret = get_pixel_bilinear(img, px + ((double) img->w()) / 2.0, py + ((double) img->h()) / 2.0, r, g, b); + } else if (m == GipfelWidget::BICUBIC) { + ret = get_pixel_bicubic(img, px + ((double) img->w()) / 2.0, + py + ((double) img->h()) / 2.0, r, g, b); } else { ret = get_pixel_nearest(img, px + ((double) img->w()) / 2.0, py + ((double) img->h()) / 2.0, r, g, b); @@ -751,6 +754,53 @@ GipfelWidget::get_pixel_bilinear(Fl_Image *img, double x, double y, } } +static double +interp_cubic(double x, double *v) { + double a0, a1, a2, a3; + double x2 = x * x; + + a0 = v[3] - v[2] - v[0] + v[1]; + a1 = v[0] - v[1] - a0; + a2 = v[2] - v[0]; + a3 = v[1]; + + return a0 * x * x2 +a1 * x2 + a2 * x + a3; +} + +int +GipfelWidget::get_pixel_bicubic(Fl_Image *img, double x, double y, + int *r, int *g, int *b) { + + int fl_x = (int) rint(x); + int fl_y = (int) rint(y); + int ic[3]; + double c[3][4]; + double c1[3][4]; + + for (int iy = 0; iy < 4; iy++) { + for (int ix = 0; ix < 4; ix++) { + if (get_pixel(img, fl_x + ix - 2, fl_y + iy - 2, + &ic[0], &ic[1], &ic[2]) != 0) { + return 1; + } + + for (int l = 0; l < 3; l++) { + c[l][ix] = (double) ic[l]; + } + } + + for (int l = 0; l < 3; l++) { + c1[l][iy] = interp_cubic(x - fl_x, c[l]); + } + } + + *r = (int) rint(interp_cubic(x - fl_x, c1[0])); + *g = (int) rint(interp_cubic(x - fl_x, c1[1])); + *b = (int) rint(interp_cubic(x - fl_x, c1[2])); + + return 0; +} + int GipfelWidget::get_pixel(Fl_Image *img, int x, int y, int *r, int *g, int *b) { diff --git a/src/gipfel.cxx b/src/gipfel.cxx index 410471d..8620641 100644 --- a/src/gipfel.cxx +++ b/src/gipfel.cxx @@ -497,7 +497,7 @@ int main(int argc, char** argv) { type |= STITCH_VIGNETTE_CALIB; } - stitch(bilinear_flag?GipfelWidget::BILINEAR:GipfelWidget::NEAREST, + stitch(bilinear_flag?GipfelWidget::BICUBIC:GipfelWidget::NEAREST, stitch_w, stitch_h, stitch_from, stitch_to, type, outpath, my_argc, my_argv); -- cgit v1.2.3 From eba7fcd8f7f91f7076ee291438d86545fdb9856d Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Sun, 18 Mar 2007 13:15:43 +0100 Subject: remove bilinear interpolation --- src/GipfelWidget.H | 6 +---- src/GipfelWidget.cxx | 67 ++++++++++------------------------------------------ 2 files changed, 14 insertions(+), 59 deletions(-) (limited to 'src/GipfelWidget.H') diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index ed251ef..0ddfbef 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -41,9 +41,6 @@ class GipfelWidget : public Fl_Widget { static int get_pixel_nearest(Fl_Image *img, double x, double y, int *r, int *g, int *b); - static int get_pixel_bilinear(Fl_Image *img, double x, double y, - int *r, int *g, int *b); - static int get_pixel_bicubic(Fl_Image *img, double x, double y, int *r, int *g, int *b); @@ -53,8 +50,7 @@ class GipfelWidget : public Fl_Widget { public: typedef enum { NEAREST = 0, - BILINEAR = 1, - BICUBIC = 2 + BICUBIC = 1 } sample_mode_t; GipfelWidget(int X,int Y,int W, int H); diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index 2daea2a..73be7e2 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -683,10 +683,7 @@ GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, return 1; } - if (m == GipfelWidget::BILINEAR) { - ret = get_pixel_bilinear(img, px + ((double) img->w()) / 2.0, - py + ((double) img->h()) / 2.0, r, g, b); - } else if (m == GipfelWidget::BICUBIC) { + if (m == GipfelWidget::BICUBIC) { ret = get_pixel_bicubic(img, px + ((double) img->w()) / 2.0, py + ((double) img->h()) / 2.0, r, g, b); } else { @@ -715,71 +712,33 @@ GipfelWidget::get_pixel_nearest(Fl_Image *img, double x, double y, } } -int -GipfelWidget::get_pixel_bilinear(Fl_Image *img, double x, double y, - int *r, int *g, int *b) { - int a_r[4] = {0, 0, 0, 0}; - int a_g[4] = {0, 0, 0, 0}; - int a_b[4] = {0, 0, 0, 0}; - float v0 , v1; - int fl_x = (int) floor(x); - int fl_y = (int) floor(y); - int i, n; - - i = 0; - n = 0; - for (int iy = 0; iy <= 1; iy++) { - for (int ix = 0; ix <= 1; ix++) { - n += get_pixel(img, fl_x + ix, fl_y + iy, &(a_r[i]), &(a_g[i]), &(a_b[i])); - i++; - } - } - - v0 = a_r[0] * (1 - (x - fl_x)) + a_r[1] * (x - fl_x); - v1 = a_r[2] * (1 - (x - fl_x)) + a_r[3] * (x - fl_x); - *r = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); - - v0 = a_g[0] * (1 - (x - fl_x)) + a_g[1] * (x - fl_x); - v1 = a_g[2] * (1 - (x - fl_x)) + a_g[3] * (x - fl_x); - *g = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); - - v0 = a_b[0] * (1 - (x - fl_x)) + a_b[1] * (x - fl_x); - v1 = a_b[2] * (1 - (x - fl_x)) + a_b[3] * (x - fl_x); - *b = (int) rint(v0 * (1 - (y - fl_y)) + v1 * (y - fl_y)); - - if (n >= 1) { - return 1; - } else { - return 0; - } -} - -static double -interp_cubic(double x, double *v) { +static inline double +interp_cubic(double x, double x2, double x3, double *v) { double a0, a1, a2, a3; - double x2 = x * x; a0 = v[3] - v[2] - v[0] + v[1]; a1 = v[0] - v[1] - a0; a2 = v[2] - v[0]; a3 = v[1]; - return a0 * x * x2 +a1 * x2 + a2 * x + a3; + return a0 * x3 + a1 * x2 + a2 * x + a3; } int GipfelWidget::get_pixel_bicubic(Fl_Image *img, double x, double y, int *r, int *g, int *b) { - int fl_x = (int) rint(x); - int fl_y = (int) rint(y); + double fl_x = floor(x); + double fl_y = floor(y); + double dx = x - fl_x, dx2 = dx * dx, dx3 = dx2 * dx; + double dy = y - fl_y, dy2 = dy * dy, dy3 = dy2 * dy; int ic[3]; double c[3][4]; double c1[3][4]; for (int iy = 0; iy < 4; iy++) { for (int ix = 0; ix < 4; ix++) { - if (get_pixel(img, fl_x + ix - 2, fl_y + iy - 2, + if (get_pixel(img, (int) fl_x + ix, (int) fl_y + iy, &ic[0], &ic[1], &ic[2]) != 0) { return 1; } @@ -790,13 +749,13 @@ GipfelWidget::get_pixel_bicubic(Fl_Image *img, double x, double y, } for (int l = 0; l < 3; l++) { - c1[l][iy] = interp_cubic(x - fl_x, c[l]); + c1[l][iy] = interp_cubic(dx, dx2, dx3, c[l]); } } - *r = (int) rint(interp_cubic(x - fl_x, c1[0])); - *g = (int) rint(interp_cubic(x - fl_x, c1[1])); - *b = (int) rint(interp_cubic(x - fl_x, c1[2])); + *r = (int) rint(interp_cubic(dy, dy2, dy3, c1[0])); + *g = (int) rint(interp_cubic(dy, dy2, dy3, c1[1])); + *b = (int) rint(interp_cubic(dy, dy2, dy3, c1[2])); return 0; } -- cgit v1.2.3