Camera tracking integration
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 16 Sep 2011 14:47:32 +0000 (14:47 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 16 Sep 2011 14:47:32 +0000 (14:47 +0000)
===========================

Implemented "Movie Distort" and "Movie Undistort" nodes which
uses camera undistortion coefficients.

Not perfect for footages shoted on cameras with pixel aspect != 1:
there's extra scaling down and scaling up caused by others areas supposing
frame aspect x be 1 and multiplying height by 1.0/pixel_aspect.
Not so critical but would be nice to solve.

13 files changed:
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/tracking.c
source/blender/editors/space_node/drawnode.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h
source/blender/nodes/composite/nodes/node_composite_moviedistort.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_movieundistort.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
source/blender/nodes/composite/nodes/node_composite_transform.c

index aebf9bee74d905f6ebdee13a30742801d6c183da..60005b396c1fe1ae02729879fefcfe70e0468e02 100644 (file)
@@ -567,6 +567,8 @@ void                        ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
 #define CMP_NODE_MOVIECLIP     262
 #define CMP_NODE_STABILIZE2D   263
 #define CMP_NODE_TRANSFORM     264
+#define CMP_NODE_MOVIEUNDISTORT        265
+#define CMP_NODE_MOVIEDISTORT  266
 
 #define CMP_NODE_GLARE         301
 #define CMP_NODE_TONEMAP       302
index f6509bfe454a0b10d953a88e72e896098a307cbb..d9969b61d5f75c1f6a055e19e4b9bd0300c19a66 100644 (file)
@@ -1849,6 +1849,8 @@ static void registerCompositNodes(ListBase *ntypelist)
        register_node_type_cmp_lensdist(ntypelist);
        register_node_type_cmp_transform(ntypelist);
        register_node_type_cmp_stabilize2d(ntypelist);
+       register_node_type_cmp_moviedistort(ntypelist);
+       register_node_type_cmp_movieundistort(ntypelist);
 }
 
 static void registerShaderNodes(ListBase *ntypelist) 
index 68f69650fb0360ea71b188e83f8c749b35ba7a0d..704a5e1f18f6b72bc66c88508a3f61f66f1b29bb 100644 (file)
@@ -1894,19 +1894,20 @@ ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf)
 {
        ImBuf *resibuf;
        MovieTrackingCamera *camera= &tracking->camera;
+       float aspy= 1.f/tracking->camera.pixel_aspect;
 
        resibuf= IMB_dupImBuf(ibuf);
 
        if(ibuf->rect_float) {
                libmv_undistortFloat(camera->focal,
-                                    camera->principal[0], camera->principal[1],
+                                    camera->principal[0], camera->principal[1] * aspy,
                                     camera->k1, camera->k2, camera->k3,
                                     ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels);
 
                ibuf->userflags|= IB_RECT_INVALID;
        } else {
                libmv_undistortByte(camera->focal,
-                                   camera->principal[0], camera->principal[1],
+                                   camera->principal[0], camera->principal[1] * aspy,
                                    camera->k1, camera->k2, camera->k3,
                                    (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels);
        }
@@ -1918,19 +1919,20 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf)
 {
        ImBuf *resibuf;
        MovieTrackingCamera *camera= &tracking->camera;
+       float aspy= 1.f/tracking->camera.pixel_aspect;
 
        resibuf= IMB_dupImBuf(ibuf);
 
        if(ibuf->rect_float) {
                libmv_distortFloat(camera->focal,
-                                  camera->principal[0], camera->principal[1],
+                                  camera->principal[0], camera->principal[1] * aspy,
                                   camera->k1, camera->k2, camera->k3,
                                   ibuf->rect_float, resibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels);
 
                ibuf->userflags|= IB_RECT_INVALID;
        } else {
                libmv_distortByte(camera->focal,
-                                 camera->principal[0], camera->principal[1],
+                                 camera->principal[0], camera->principal[1] * aspy,
                                  camera->k1, camera->k2, camera->k3,
                                  (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, ibuf->x, ibuf->y, ibuf->channels);
        }
index 662386b589e6f5daaff01cb2b8bac682eea0986c..74e1327d7cbabb9016abdcd4cc422c796759dc33 100644 (file)
@@ -1695,6 +1695,17 @@ static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C),
        uiItemR(layout, ptr, "filter_type", 0, "", 0);
 }
 
+static void node_composit_buts_movieundistort(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+       uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+
+}
+
+static void node_composit_buts_moviedistort(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+       uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+}
+
 /* only once called */
 static void node_composit_set_butfunc(bNodeType *ntype)
 {
@@ -1854,6 +1865,12 @@ static void node_composit_set_butfunc(bNodeType *ntype)
                case CMP_NODE_TRANSFORM:
                        ntype->uifunc= node_composit_buts_transform;
                        break;
+               case CMP_NODE_MOVIEUNDISTORT:
+                       ntype->uifunc= node_composit_buts_movieundistort;
+                       break;
+               case CMP_NODE_MOVIEDISTORT:
+                       ntype->uifunc= node_composit_buts_moviedistort;
+                       break;
                default:
                        ntype->uifunc= NULL;
        }
index e77d378bc9d46f8885c296d107087b6d76d49edf..e053000dec29cd02198dbc88b8bf7044db93054d 100644 (file)
@@ -2445,6 +2445,30 @@ static void def_cmp_stabilize2d(StructRNA *srna)
        RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
 }
 
+static void def_cmp_movieundistort(StructRNA *srna)
+{
+       PropertyRNA *prop;
+
+       prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "id");
+       RNA_def_property_struct_type(prop, "MovieClip");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Movie Clip", "");
+       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
+static void def_cmp_moviedistort(StructRNA *srna)
+{
+       PropertyRNA *prop;
+
+       prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "id");
+       RNA_def_property_struct_type(prop, "MovieClip");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Movie Clip", "");
+       RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
 static void dev_cmd_transform(StructRNA *srna)
 {
        PropertyRNA *prop;
index fc5b8dbce90df00faaddcbe18c2c076f03708aac..d4b0bc66516c7309a6db60861fb6658eed6ea357 100644 (file)
@@ -122,6 +122,8 @@ DefNode( CompositorNode, CMP_NODE_HUECORRECT,     def_cmp_huecorrect,     "HUECO
 DefNode( CompositorNode, CMP_NODE_MOVIECLIP,      def_cmp_movieclip,      "MOVIECLIP",      MovieClip,        "MovieClip",         ""              )
 DefNode( CompositorNode, CMP_NODE_TRANSFORM,      dev_cmd_transform,      "TRANSFORM",      Transform,        "Transform",         ""              )
 DefNode( CompositorNode, CMP_NODE_STABILIZE2D,    def_cmp_stabilize2d,    "STABILIZE2D",    Stabilize,        "Stabelize 2D",      ""              )
+DefNode( CompositorNode, CMP_NODE_MOVIEDISTORT,   def_cmp_moviedistort,   "MOVIEDISTORT",   MovieDistort,     "Movie Distort",     ""              )
+DefNode( CompositorNode, CMP_NODE_MOVIEUNDISTORT, def_cmp_movieundistort, "MOVIEUNDISTORT", MovieUndistort,   "Movie Undistort",   ""              )
                                                                                                                                                    
 DefNode( TextureNode,    TEX_NODE_OUTPUT,         def_tex_output,         "OUTPUT",         Output,           "Output",            ""              )
 DefNode( TextureNode,    TEX_NODE_CHECKER,        0,                      "CHECKER",        Checker,          "Checker",           ""              )
index 84664935b7675ec847026a41d36d21f2fa2542f3..433b84d8a372caaf390644dc0630a492f8881a3c 100644 (file)
@@ -376,19 +376,19 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "k1");
        RNA_def_property_ui_range(prop, -10, 10, .1, 3);
        RNA_def_property_ui_text(prop, "K1", "");
-       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
 
        prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "k2");
        RNA_def_property_ui_range(prop, -10, 10, .1, 3);
        RNA_def_property_ui_text(prop, "K2", "");
-       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
 
        prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "k3");
        RNA_def_property_ui_range(prop, -10, 10, .1, 3);
        RNA_def_property_ui_text(prop, "K3", "");
-       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
 
        /* pixel aspect */
        prop= RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ);
@@ -396,7 +396,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
        RNA_def_property_range(prop, 0.1f, 5000.0f);
        RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2);
        RNA_def_property_ui_text(prop, "Pixel Aspect", "Pixel aspect ratio");
-       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
 }
 
 static void rna_def_trackingMarker(BlenderRNA *brna)
index 29c523572b264596215e6b4a076eaf7fd7c6bf58..199a43131d7c410b8a2b4cd00d0a09d650e66cdb 100644 (file)
@@ -81,6 +81,8 @@ set(SRC
        composite/nodes/node_composite_math.c
        composite/nodes/node_composite_mixrgb.c
        composite/nodes/node_composite_movieclip.c
+       composite/nodes/node_composite_moviedistort.c
+       composite/nodes/node_composite_movieundistort.c
        composite/nodes/node_composite_normal.c
        composite/nodes/node_composite_normalize.c
        composite/nodes/node_composite_outputFile.c
index 5d2fc458f32e5ec61b72c9c7777667d85a1ba7f6..fce9a18c0adee28c971c7c4d2a77a6d1a9bf6edf 100644 (file)
@@ -118,6 +118,8 @@ void register_node_type_cmp_displace(ListBase *lb);
 void register_node_type_cmp_mapuv(ListBase *lb);
 void register_node_type_cmp_transform(ListBase *lb);
 void register_node_type_cmp_stabilize2d(ListBase *lb);
+void register_node_type_cmp_moviedistort(ListBase *lb);
+void register_node_type_cmp_movieundistort(ListBase *lb);
 
 void register_node_type_cmp_glare(ListBase *lb);
 void register_node_type_cmp_tonemap(ListBase *lb);
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistort.c b/source/blender/nodes/composite/nodes/node_composite_moviedistort.c
new file mode 100644 (file)
index 0000000..a56a27f
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_moviedistort.c
+ *  \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+/* **************** Translate  ******************** */
+
+static bNodeSocketTemplate cmp_node_moviedistort_in[]= {
+       {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+static bNodeSocketTemplate cmp_node_moviedistort_out[]= {
+       {       SOCK_RGBA, 0, "Image"},
+       {       -1, 0, ""       }
+};
+
+static void node_composit_exec_moviedistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       if(in[0]->data && node->id) {
+               MovieClip *clip= (MovieClip *)node->id;
+               CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+               CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
+               ImBuf *ibuf;
+
+               ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
+
+               if(ibuf) {
+                       ImBuf *obuf;
+                       MovieClipUser *user= (MovieClipUser *)node->storage;
+                       float aspy= 1.f/clip->tracking.camera.pixel_aspect;
+                       int scaled= 0, width, height;
+
+                       ibuf->rect_float= cbuf->rect;
+
+                       BKE_movieclip_acquire_size(clip, user, &width, &height);
+                       height*= aspy;
+
+                       if(ibuf->x!=width || ibuf->y!=height) {
+                               /* TODO: not sure this is really needed, but distortion coefficients are
+                                        calculated using camera resolution, so if image with other resolution
+                                        is passed to distortion node, it'll be distorted correct (but quality can hurt)
+                                        This is also needed to deal when camera pixel aspect isn't 1. Problems in this case
+                                        are caused because of how aspect x/y are calculating. Currently. projeciton
+                                        matrices and reconstruction stuff are supposing that aspect x is always 1 and
+                                        aspect y is less than 1 (if x resolution is larger than y resolution) */
+
+                               IMB_scaleImBuf(ibuf, width, height);
+                               scaled= 1;
+                       }
+
+                       obuf= BKE_tracking_distort(&clip->tracking, ibuf);
+
+                       if(scaled)
+                               IMB_scaleImBuf(obuf, cbuf->x, cbuf->y);
+
+                       stackbuf->rect= obuf->rect_float;
+                       stackbuf->malloc= 1;
+
+                       obuf->mall&= ~IB_rectfloat;
+                       obuf->rect_float= NULL;
+
+                       IMB_freeImBuf(ibuf);
+                       IMB_freeImBuf(obuf);
+               }
+
+               /* pass on output and free */
+               out[0]->data= stackbuf;
+
+               if(cbuf!=in[0]->data)
+                       free_compbuf(cbuf);
+       }
+}
+
+void register_node_type_cmp_moviedistort(ListBase *lb)
+{
+       static bNodeType ntype;
+
+       node_type_base(&ntype, CMP_NODE_MOVIEDISTORT, "Movie Distort", NODE_CLASS_DISTORT, NODE_OPTIONS);
+       node_type_socket_templates(&ntype, cmp_node_moviedistort_in, cmp_node_moviedistort_out);
+       node_type_size(&ntype, 140, 100, 320);
+       node_type_exec(&ntype, node_composit_exec_moviedistort);
+
+       nodeRegisterType(lb, &ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_movieundistort.c b/source/blender/nodes/composite/nodes/node_composite_movieundistort.c
new file mode 100644 (file)
index 0000000..5890233
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_movieundistort.c
+ *  \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+/* **************** Translate  ******************** */
+
+static bNodeSocketTemplate cmp_node_movieundistort_in[]= {
+       {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+static bNodeSocketTemplate cmp_node_movieundistort_out[]= {
+       {       SOCK_RGBA, 0, "Image"},
+       {       -1, 0, ""       }
+};
+
+static void node_composit_exec_movieundistort(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       if(in[0]->data && node->id) {
+               MovieClip *clip= (MovieClip *)node->id;
+               CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+               CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
+               ImBuf *ibuf;
+
+               ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
+
+               if(ibuf) {
+                       ImBuf *obuf;
+                       MovieClipUser *user= (MovieClipUser *)node->storage;
+                       float aspy= 1.f/clip->tracking.camera.pixel_aspect;
+                       int scaled= 0, width, height;
+
+                       ibuf->rect_float= cbuf->rect;
+
+                       BKE_movieclip_acquire_size(clip, user, &width, &height);
+                       height*= aspy;
+
+                       if(ibuf->x!=width || ibuf->y!=height) {
+                               /* TODO: not sure this is really needed, but distortion coefficients are
+                                        calculated using camera resolution, so if image with other resolution
+                                        is passed to undistortion node, it'll be undistorted correct (but quality can hurt)
+                                        This is also needed to deal when camera pixel aspect isn't 1. Problems in this case
+                                        are caused because of how aspect x/y are calculating. Currently. projeciton
+                                        matrices and reconstruction stuff are supposing that aspect x is always 1 and
+                                        aspect y is less than 1 (if x resolution is larger than y resolution) */
+
+                               IMB_scaleImBuf(ibuf, width, height);
+                               scaled= 1;
+                       }
+
+                       obuf= BKE_tracking_undistort(&clip->tracking, ibuf);
+
+                       if(scaled)
+                               IMB_scaleImBuf(obuf, cbuf->x, cbuf->y);
+
+                       stackbuf->rect= obuf->rect_float;
+                       stackbuf->malloc= 1;
+
+                       obuf->mall&= ~IB_rectfloat;
+                       obuf->rect_float= NULL;
+
+                       IMB_freeImBuf(ibuf);
+                       IMB_freeImBuf(obuf);
+               }
+
+               /* pass on output and free */
+               out[0]->data= stackbuf;
+
+               if(cbuf!=in[0]->data)
+                       free_compbuf(cbuf);
+       }
+}
+
+void register_node_type_cmp_movieundistort(ListBase *lb)
+{
+       static bNodeType ntype;
+
+       node_type_base(&ntype, CMP_NODE_MOVIEUNDISTORT, "Movie Undistort", NODE_CLASS_DISTORT, NODE_OPTIONS);
+       node_type_socket_templates(&ntype, cmp_node_movieundistort_in, cmp_node_movieundistort_out);
+       node_type_size(&ntype, 140, 100, 320);
+       node_type_exec(&ntype, node_composit_exec_movieundistort);
+
+       nodeRegisterType(lb, &ntype);
+}
index eafdf3286adb36457a9efb7e186bf5159945fac0..a0c3a2399fb46ba1ab5d367a6739b8bdaf0697c6 100644 (file)
@@ -28,7 +28,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/nodes/intern/CMP_nodes/CMP_translate.c
+/** \file blender/nodes/composite/nodes/node_composite_stabilize2d.c
  *  \ingroup cmpnodes
  */
 
index 9ee9cf84cc1dbe2733ca91342d9ec2501ed6b6d5..15cee6014a31f1d9e2a951eff835d580440f1aa1 100644 (file)
@@ -28,7 +28,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/nodes/intern/CMP_nodes/CMP_translate.c
+/** \file blender/nodes/composite/nodes/node_composite_transform.c
  *  \ingroup cmpnodes
  */