]> granicus.if.org Git - libvpx/commitdiff
Global Motion block-based
authorSpencer Egart <spencere@google.com>
Thu, 12 Feb 2015 00:00:15 +0000 (16:00 -0800)
committerSpencer Egart <spencere@google.com>
Wed, 18 Feb 2015 19:52:39 +0000 (11:52 -0800)
Uses block-based motion fields with ransac to find transformation between
frames.

Change-Id: I6293fbb690cdad854a1140fb6af76b326abfe964

vp9/encoder/vp9_global_motion.c
vp9/encoder/vp9_global_motion.h
vp9/encoder/vp9_motionmodel.c
vp9/encoder/vp9_motionmodel.h

index 6570e0c14d1a060ef3bad4aad2fe353edf532b90..6d4e821d79e26be4785b658ffabfd74e888ad5ae 100644 (file)
 #include <math.h>
 #include <assert.h>
 
-#include "vp9_corner_detect.h"
-#include "vp9_corner_match.h"
-#include "vp9_ransac.h"
-#include "vp9_global_motion.h"
+
+#include "vpx_mem/vpx_mem.h"
+#include "vp9/encoder/vp9_segmentation.h"
+#include "vp9/encoder/vp9_mcomp.h"
+#include "vp9/common/vp9_blockd.h"
+#include "vp9/common/vp9_reconinter.h"
+#include "vp9/common/vp9_reconintra.h"
+#include "vp9/common/vp9_systemdependent.h"
+#include "vp9/encoder/vp9_corner_detect.h"
+#include "vp9/encoder/vp9_corner_match.h"
+#include "vp9/encoder/vp9_ransac.h"
+#include "vp9/encoder/vp9_global_motion.h"
+#include "vp9/encoder/vp9_motionmodel.h"
 
 // #define VERBOSE
 
@@ -337,3 +346,103 @@ int vp9_compute_global_motion_multiple_feature_based(TransformationType type,
   free(inlier_map);
   return num_models;
 }
+
+// Returns number of models actually returned: 1 - if success, 0 - if failure
+int vp9_compute_global_motion_single_block_based(struct VP9_COMP *cpi,
+                                                 TransformationType type,
+                                                 YV12_BUFFER_CONFIG *frm,
+                                                 YV12_BUFFER_CONFIG *ref,
+                                                 int blocksize,
+                                                 double *H) {
+  VP9_COMMON *const cm = &cpi->common;
+  int num_correspondences = 0;
+  int *correspondences;
+  int num_inliers;
+  int *inlier_map = NULL;
+
+  int i;
+  MV motionfield[4096];
+  double confidence[4096];
+
+  get_frame_motionfield(cpi, frm, ref, blocksize, motionfield, confidence);
+  correspondences = (int *)malloc(4 * cm->mb_rows * cm->mb_cols *
+                                  sizeof(*correspondences));
+  for (i = 0; i < cm->mb_rows * cm->mb_cols; i ++) {
+      int x = (i % cm->mb_cols) * blocksize + blocksize/2;
+      int y = (i / cm->mb_cols) * blocksize + blocksize/2;
+      if (confidence[i] > CONFIDENCE_THRESHOLD) {
+        correspondences[num_correspondences*4]   = x;
+        correspondences[num_correspondences*4+1] = y;
+        correspondences[num_correspondences*4+2] = motionfield[i].col + x;
+        correspondences[num_correspondences*4+3] = motionfield[i].row + y;
+        num_correspondences++;
+      }
+  }
+
+  inlier_map = (int *)malloc(num_correspondences * sizeof(*inlier_map));
+  num_inliers = compute_global_motion_single(type, correspondences,
+                                             num_correspondences, H,
+                                             inlier_map);
+#ifdef VERBOSE
+  printf("Inliers = %d\n", num_inliers);
+  printf("Error Score (inliers) = %g\n",
+         compute_error_score(type, correspondences, 4, correspondences + 2, 4,
+                             num_correspondences, H, inlier_map));
+#endif
+  free(correspondences);
+  free(inlier_map);
+  return (num_inliers > 0);
+}
+
+// Returns number of models actually returned
+int vp9_compute_global_motion_multiple_block_based(struct VP9_COMP *cpi,
+                                                   TransformationType type,
+                                                   YV12_BUFFER_CONFIG *frm,
+                                                   YV12_BUFFER_CONFIG *ref,
+                                                   int blocksize,
+                                                   int max_models,
+                                                   double inlier_prob,
+                                                   double *H) {
+  VP9_COMMON *const cm = &cpi->common;
+  int num_correspondences = 0;
+  int *correspondences;
+  int num_inliers;
+  int num_models = 0;
+  int *inlier_map = NULL;
+
+  int i;
+  MV motionfield[4096];
+  double confidence[4096];
+  get_frame_motionfield(cpi, frm, ref, blocksize, motionfield, confidence);
+  correspondences = (int *)malloc(4 * cm->mb_rows * cm->mb_cols *
+                                  sizeof(*correspondences));
+
+  for (i = 0; i < cm->mb_rows * cm->mb_cols; i ++) {
+      int x = (i % cm->mb_cols) * blocksize + blocksize/2;
+      int y = (i / cm->mb_cols) * blocksize + blocksize/2;
+      if (confidence[i] > CONFIDENCE_THRESHOLD) {
+        correspondences[num_correspondences*4]   = x;
+        correspondences[num_correspondences*4+1] = y;
+        correspondences[num_correspondences*4+2] = motionfield[i].col + x;
+        correspondences[num_correspondences*4+3] = motionfield[i].row + y;
+        num_correspondences++;
+      }
+  }
+
+  inlier_map = (int *)malloc(num_correspondences * sizeof(*inlier_map));
+  num_inliers = compute_global_motion_multiple(type, correspondences,
+                                               num_correspondences, H,
+                                               max_models, inlier_prob,
+                                               &num_models, inlier_map);
+#ifdef VERBOSE
+  printf("Models = %d, Inliers = %d\n", num_models, num_inliers);
+  if (num_models)
+    printf("Error Score (inliers) = %g\n",
+           compute_error_score(type, correspondences, 4, correspondences + 2, 4,
+                               num_correspondences, H, inlier_map));
+#endif
+  (void) num_inliers;
+  free(correspondences);
+  free(inlier_map);
+  return num_models;
+}
index aea8d8ac65534418b663552273cc7656ed6f26f8..37a2fa2f3d96a0cf0e5c136459b72e60408382ff 100644 (file)
 #define USE_FAST_CORNER
 #define MAX_CORNERS 4096
 
+struct VP9_COMP;
+
+const int CONFIDENCE_THRESHOLD = 40;
+
 typedef enum {
-  UNKNOWN = -1,
+  UNKNOWN_TRANSFORM = -1,
   HOMOGRAPHY,  // homography, 8-parameter
   AFFINE,      // affine, 6-parameter
   ROTZOOM      // simplified affine with rotation and zoom only, 4-parameter
@@ -66,4 +70,22 @@ int vp9_compute_global_motion_multiple_feature_based(TransformationType type,
                                                      double inlier_prob,
                                                      double *H);
 
+// Returns number of models actually returned: 1 - if success, 0 - if failure
+int vp9_compute_global_motion_single_block_based(struct VP9_COMP *cpi,
+                                                 TransformationType type,
+                                                 YV12_BUFFER_CONFIG *frm,
+                                                 YV12_BUFFER_CONFIG *ref,
+                                                 int blocksize,
+                                                 double *H);
+
+// Returns number of models actually returned: 1 - if success, 0 - if failure
+int vp9_compute_global_motion_multiple_block_based(struct VP9_COMP *cpi,
+                                                   TransformationType type,
+                                                   YV12_BUFFER_CONFIG *frm,
+                                                   YV12_BUFFER_CONFIG *ref,
+                                                   int blocksize,
+                                                   int max_models,
+                                                   double inlier_prob,
+                                                   double *H);
+
 #endif  // VP9_ENCODER_VP9_GLOBAL_MOTION_H
index 3c3e015881a43df14da22fbcb216acffe1c302d6..89e20458cc05b78865b85794122d99ce0a12f588 100644 (file)
@@ -214,12 +214,12 @@ static void get_mb_motionfield(VP9_COMP *cpi,
   xd->plane[0].dst.stride = tmp_dst_stride;
 }
 
-static void get_frame_motionfield(VP9_COMP *cpi,
-                                           YV12_BUFFER_CONFIG *buf,
-                                           YV12_BUFFER_CONFIG *ref,
-                                           int blocksize,
-                                           MV *motionfield,
-                                           double *confidence) {
+void get_frame_motionfield(struct VP9_COMP *cpi,
+                           YV12_BUFFER_CONFIG *buf,
+                           YV12_BUFFER_CONFIG *ref,
+                           int blocksize,
+                           MV *motionfield,
+                           double *confidence) {
   MACROBLOCK *const x = &cpi->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   VP9_COMMON *const cm = &cpi->common;
index abad772b55b43e730e10a4aa4e92f16a3930bb2f..5f0db6dde76dc3519d803f7d957073247cc4a126 100644 (file)
@@ -17,8 +17,15 @@ extern "C" {
 
 struct VP9_COMP;
 
+void get_frame_motionfield(struct VP9_COMP *cpi,
+                           YV12_BUFFER_CONFIG *buf,
+                           YV12_BUFFER_CONFIG *ref,
+                           int blocksize,
+                           MV *motionfield,
+                           double *confidence);
+
 void vp9_get_motionfield(struct VP9_COMP *cpi, int ref,
-    int blocksize, MV *motionfield, double *confidence);
+                         int blocksize, MV *motionfield, double *confidence);
 
 #ifdef __cplusplus
 }  // extern "C"