[gegl/soc-2011-ops] Added lens-correct op, implemented also lensfun library
- From: Robert Sasu <sasurobert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2011-ops] Added lens-correct op, implemented also lensfun library
- Date: Tue, 16 Aug 2011 20:14:30 +0000 (UTC)
commit a86e72553f2cc26016a9a387ff887126d67ae086
Author: Robert Sasu <sasu robert gmail com>
Date: Tue Aug 16 23:14:03 2011 +0300
Added lens-correct op, implemented also lensfun library
operations/workshop/lens-correct.c | 219 ++++++++++++++++++++++++++++--------
1 files changed, 170 insertions(+), 49 deletions(-)
---
diff --git a/operations/workshop/lens-correct.c b/operations/workshop/lens-correct.c
index cd559b5..6e7a4be 100644
--- a/operations/workshop/lens-correct.c
+++ b/operations/workshop/lens-correct.c
@@ -19,13 +19,20 @@
*/
#include "config.h"
+#include "lensfun.h"
#include <glib/gi18n-lib.h>
#ifdef GEGL_CHANT_PROPERTIES
-gegl_chant_string (type, _("Lens type:"),"none",
+gegl_chant_string (maker, _("Maker:"),"none",
+ _("Write lens maker correctly"))
+gegl_chant_string (Camera, _("Camera:"),"none",
+ _("Write camera name correctly"))
+gegl_chant_string (Lens, _("Lens:"),"none",
_("Write your lens model with majuscules"))
+gegl_chant_double (focal, _("Focal of the camera"), 0.0, 300.0, 20.0,
+ _("Calculate b value from focal"))
gegl_chant_boolean (center, _("Center"), TRUE,
_("If you want center"))
@@ -38,9 +45,6 @@ gegl_chant_double (rscale, _("Scale"), 0.001, 10.0, 0.5,
gegl_chant_boolean (correct, _("Autocorrect d values"), TRUE,
_("Autocorrect D values for lens correction models."))
-gegl_chant_double (focal, _("Focal of the camera"), 0.0, 300.0, 0.0,
- _("Calculate b value from focal"))
-
gegl_chant_double (red_a, _("Model red a:"), -1.0, 1.0, 0.0,
_("Correction parameters for each color channel"))
gegl_chant_double (red_b, _("Model red b:"), -1.0, 1.0, 0.0,
@@ -93,66 +97,182 @@ make_lens (LensCorrectionModel *lens,
GeglChantO *o,
GeglRectangle boundary)
{
- lens->BB.x = boundary.x;
- lens->BB.y = boundary.y;
- lens->BB.width = boundary.width;
- lens->BB.height = boundary.height;
+ lens->BB.x = boundary.x;
+ lens->BB.y = boundary.y;
+ lens->BB.width = boundary.width;
+ lens->BB.height = boundary.height;
+
+ if (o->center)
+ {
+ o->cx = (boundary.x + boundary.width) / 2;
+ o->cy = (boundary.y + boundary.height) / 2;
+ }
+
+ lens->cx = o->cx;
+ lens->cy = o->cy;
+
+ lens->rscale = o->rscale;
+
+ lens->red.a = o->red_a;
+ lens->red.b = o->red_b;
+ lens->red.c = o->red_c;
+
+ if (o->correct)
+ lens->red.d = 1 - o->red_a - o->red_b - o->red_c;
+ else
+ lens->red.d = o->red_d;
+
+ lens->green.a = o->green_a;
+ lens->green.b = o->green_b;
+ lens->green.c = o->green_c;
+
+ if (o->correct)
+ lens->green.d = 1 - o->green_a - o->green_b - o->green_c;
+ else
+ lens->green.d = o->green_d;
+
+ lens->blue.a = o->blue_a;
+ lens->blue.b = o->blue_b;
+ lens->blue.c = o->blue_c;
+
+ if (o->correct)
+ lens->blue.d = 1 - o->blue_a - o->blue_b - o->blue_c;
+ else
+ lens->blue.d = o->blue_d;
+
+ lens->alpha.a = o->alpha_a;
+ lens->alpha.b = o->alpha_b;
+ lens->alpha.c = o->alpha_c;
+
+ if (o->correct)
+ lens->alpha.d = 1 - o->alpha_a - o->alpha_b - o->alpha_c;
+ else
+ lens->alpha.d = o->red_d;
+
+ if (o->focal!=0.0)
+ {
+ gdouble f = o->focal;
+ lens->red.b = lens->green.b = lens->blue.b = lens->alpha.b
+ = 0.000005142 * f*f*f - 0.000380839 * f*f + 0.009606325 * f - 0.075316854;
+ }
+}
- if (o->center)
- {
- o->cx = (boundary.x + boundary.width) / 2;
- o->cy = (boundary.y + boundary.height) / 2;
- }
+static gboolean
+find_make_lens(LensCorrectionModel *lens,
+ GeglChantO *o,
+ GeglRectangle boundary)
+{
+ struct lfDatabase *ldb;
+ const lfCamera **cameras;
+ const lfLens **lenses;
+ const lfCamera *camera;
+ const lfLens *onelen;
+
+ struct lfLensCalibDistortion **dist;
+
+ gint i, j=0;
+ gfloat aux = G_MAXINT;
+
+ lens->BB.x = boundary.x;
+ lens->BB.y = boundary.y;
+ lens->BB.width = boundary.width;
+ lens->BB.height = boundary.height;
- lens->cx = o->cx;
- lens->cy = o->cy;
+ if (o->center)
+ {
+ o->cx = (boundary.x + boundary.width) / 2;
+ o->cy = (boundary.y + boundary.height) / 2;
+ }
- lens->rscale = o->rscale;
+ lens->cx = o->cx;
+ lens->cy = o->cy;
- lens->red.a = o->red_a;
- lens->red.b = o->red_b;
- lens->red.c = o->red_c;
+ lens->rscale = o->rscale;
- if (o->correct)
- lens->red.d = 1 - o->red_a - o->red_b - o->red_c;
- else
- lens->red.d = o->red_d;
+ ldb = lf_db_new ();
+ if (!ldb)
+ return FALSE;
- lens->green.a = o->green_a;
- lens->green.b = o->green_b;
- lens->green.c = o->green_c;
+ lf_db_load (ldb);
- if (o->correct)
- lens->green.d = 1 - o->green_a - o->green_b - o->green_c;
- else
- lens->green.d = o->green_d;
+ cameras = lf_db_find_cameras (ldb, o->maker, o->Camera);
+ if (!cameras)
+ return FALSE;
+ camera = cameras[0];
- lens->blue.a = o->blue_a;
- lens->blue.b = o->blue_b;
- lens->blue.c = o->blue_c;
+ lf_free (cameras);
- if (o->correct)
- lens->blue.d = 1 - o->blue_a - o->blue_b - o->blue_c;
- else
- lens->blue.d = o->blue_d;
+ lenses = lf_db_find_lenses_hd (ldb, camera, o->maker, o->Lens, 0);
+ if (!lenses)
+ return FALSE;
+ onelen = lenses[0];
- lens->alpha.a = o->alpha_a;
- lens->alpha.b = o->alpha_b;
- lens->alpha.c = o->alpha_c;
+ dist = onelen->CalibDistortion;
- if (o->correct)
- lens->alpha.d = 1 - o->alpha_a - o->alpha_b - o->alpha_c;
- else
- lens->alpha.d = o->red_d;
+ for (i=0; lenses[i]; i++)
+ if (lenses[i]->MinFocal < o->focal && o->focal < lenses[i]->MaxFocal)
+ break;
- if (o->focal!=0.0)
+ dist = lenses[i]->CalibDistortion;
+
+ if (!dist)
+ return FALSE;
+
+ for (i=0; dist[i]; i++)
+ {
+ if (dist[i]->Focal == o->focal)
+ {
+ lens->red.a = lens->green.a = lens->blue.a = lens->alpha.a
+ = dist[i]->Terms[0];
+ lens->red.b = lens->green.b = lens->blue.b = lens->alpha.b
+ = dist[i]->Terms[1];
+ lens->red.c = lens->green.c = lens->blue.c = lens->alpha.c
+ = dist[i]->Terms[2];
+
+ lens->red.d = 1 - lens->red.a - lens->red.b - lens->red.c;
+ lens->green.d = 1 - lens->green.a - lens->green.b - lens->green.c;
+ lens->blue.d = 1 - lens->blue.a - lens->blue.b - lens->blue.c;
+ lens->alpha.d = 1 - lens->alpha.a - lens->alpha.b - lens->alpha.c;
+
+ aux = -G_MAXINT;
+ break;
+ }
+ else if (i > 0)
+ {
+ if (aux > fabs (dist[i]->Focal - o->focal
+ + dist[i-1]->Focal - o->focal))
+ {
+ aux = fabs (dist[i]->Focal + dist[i-1]->Focal - 2 * o->focal);
+ j = i;
+ }
+ }
+ }
+ lf_free (lenses);
+
+ if (aux != -G_MAXINT)
{
- gdouble f = o->focal;
+ gfloat aux[3];
+ for (i=0; i<3; i++)
+ aux[i] = (dist[j]->Terms[i] - dist[j-1]->Terms[i]) / 2.0;
+
+ lens->red.a = lens->green.a = lens->blue.a = lens->alpha.a
+ = aux[0];
lens->red.b = lens->green.b = lens->blue.b = lens->alpha.b
- = 0.000005142 * f*f*f - 0.000380839 * f*f + 0.009606325 * f - 0.075316854;
+ = aux[1];
+ lens->red.c = lens->green.c = lens->blue.c = lens->alpha.c
+ = aux[2];
+
+ lens->red.d = 1 - lens->red.a - lens->red.b - lens->red.c;
+ lens->green.d = 1 - lens->green.a - lens->green.b - lens->green.c;
+ lens->blue.d = 1 - lens->blue.a - lens->blue.b - lens->blue.c;
+ lens->alpha.d = 1 - lens->alpha.a - lens->alpha.b - lens->alpha.c;
+
}
+
+ return TRUE;
}
+
static GeglRectangle
get_bounding_box (GeglOperation *operation)
{
@@ -283,12 +403,13 @@ process (GeglOperation *operation,
GeglRectangle boundary = *gegl_operation_source_get_bounding_box
(operation, "input");
- gint x, y;
+ gint x, y, found = FALSE;
gfloat *src_buf, *dst_buf;
src_buf = g_new0 (gfloat, result->width * result->height * 4);
dst_buf = g_new0 (gfloat, result->width * result->height * 4);
- make_lens (&lens, o, boundary);
+ found = find_make_lens (&lens, o, boundary);
+ if (!found) make_lens (&lens, o, boundary);
gegl_buffer_get (input, 1.0, result, babl_format ("RGBA float"),
src_buf, GEGL_AUTO_ROWSTRIDE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]