[gegl/soc-2011-ops] Added lens-correct op, implemented also lensfun library



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]