Global Motion block-based

Uses block-based motion fields with ransac to find transformation between
frames.

Change-Id: I6293fbb690cdad854a1140fb6af76b326abfe964
This commit is contained in:
Spencer Egart 2015-02-11 16:00:15 -08:00
parent edffe3f956
commit d8983f0dd7
4 changed files with 150 additions and 12 deletions

View File

@ -14,10 +14,19 @@
#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;
}

View File

@ -25,8 +25,12 @@
#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

View 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;

View 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"