summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2007-03-13 18:29:45 +0100
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2007-03-13 18:29:45 +0100
commit3d907fd76ca23d69bcd7d25367c9c94063490d38 (patch)
tree1ecfd01a624536445be6b436bf791b53086bc556 /src
parent508490f69a9f5e0023deda70b04b785aa041b8e3 (diff)
add devignetting infrastructure
Diffstat (limited to 'src')
-rw-r--r--src/GipfelWidget.H2
-rw-r--r--src/GipfelWidget.cxx31
-rw-r--r--src/Stitch.H3
-rw-r--r--src/Stitch.cxx94
-rw-r--r--src/gipfel.cxx20
5 files changed, 141 insertions, 9 deletions
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 <string.h>
#include <math.h>
+#include <gsl/gsl_multifit.h>
+
#include <Fl/Fl.H>
#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;
@@ -78,6 +83,78 @@ Stitch::set_output(const char *file, OutputImage *img) {
}
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; y<h; y++) {
+ double a_nick = atan((double)(y_off - y)/radius);
+
+ for (int x=0; x<w; x++) {
+ double a_view;
+ a_view = view_start + x * step_view;
+ double l1 = 0.0, l2 = 0.0;
+ double a1, a2;
+
+ for (int i=0; i<MAX_PICS; i++) {
+
+ if (gipf[i] == NULL) {
+ break;
+ } else if (gipf[i]->get_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());