Search parameter space around gm parameters
For each global motion parameter, search some step size to the left and right to try and minimize warp mse and correct for error. Change-Id: I1f0b464b0924d56b15460e509f89736af9b7e78f
This commit is contained in:
parent
50619bacfd
commit
de085787ec
@ -216,31 +216,39 @@ static void WarpImage(TransformationType type, double *H,
|
||||
}
|
||||
}
|
||||
|
||||
// computes warp error
|
||||
double compute_warp_and_error(TransformationType type,
|
||||
unsigned char *ref,
|
||||
unsigned char *frm,
|
||||
int width, int height, int stride,
|
||||
double *H) {
|
||||
double compute_warp_and_error(Global_Motion_Params *gm,
|
||||
projectPointsType projectPoints,
|
||||
unsigned char *ref,
|
||||
int width, int height, int stride,
|
||||
unsigned char *src,
|
||||
int p_col, int p_row,
|
||||
int p_width, int p_height, int p_stride,
|
||||
int subsampling_col, int subsampling_row,
|
||||
int x_scale, int y_scale) {
|
||||
double H[9];
|
||||
vp9_convert_params_to_rotzoom(gm, H);
|
||||
int i, j;
|
||||
double warped;
|
||||
double mse = 0;
|
||||
double err = 0;
|
||||
projectPointsType projectPoints = get_projectPointsType(type);
|
||||
if (projectPoints == NULL) return -1.0;
|
||||
for (i = 0; i < height; ++i)
|
||||
for (j = 0; j < width; ++j) {
|
||||
int64_t sumerr = 0;
|
||||
if (projectPoints == NULL)
|
||||
return -1;
|
||||
for (i = p_row; i < p_row + p_height; ++i) {
|
||||
for (j = p_col; j < p_col + p_width; ++j) {
|
||||
double in[2], out[2];
|
||||
in[0] = j;
|
||||
in[1] = i;
|
||||
uint8_t pred;
|
||||
int err;
|
||||
in[0] = subsampling_col ? 2 * j + 0.5 : j;
|
||||
in[1] = subsampling_row ? 2 * i + 0.5 : i;
|
||||
projectPoints(H, in, out, 1, 2, 2);
|
||||
warped = interpolate(ref, out[0], out[1], width, height, stride);
|
||||
err = warped - frm[j + i * stride];
|
||||
mse += err * err;
|
||||
out[0] = subsampling_col ? (out[0] - 0.5) / 2.0 : out[0];
|
||||
out[1] = subsampling_row ? (out[1] - 0.5) / 2.0 : out[1];
|
||||
out[0] *= x_scale / 16.0;
|
||||
out[1] *= y_scale / 16.0;
|
||||
pred = interpolate(ref, out[0], out[1], width, height, stride);
|
||||
err = pred - src[(j - p_col) + (i - p_row) * p_stride];
|
||||
sumerr += err * err;
|
||||
}
|
||||
|
||||
mse /= (width * height);
|
||||
return mse;
|
||||
}
|
||||
return sumerr/(width * height);
|
||||
}
|
||||
|
||||
// Computes the ratio of the warp error to the zero motion error
|
||||
|
@ -92,13 +92,15 @@ double vp9_warp_erroradv_unq(TransformationType type, double *H,
|
||||
int subsampling_col, int subsampling_row,
|
||||
int x_scale, int y_scale);
|
||||
|
||||
double compute_warp_and_error(TransformationType type,
|
||||
double compute_warp_and_error(Global_Motion_Params *gm,
|
||||
projectPointsType projectPoints,
|
||||
unsigned char *ref,
|
||||
unsigned char *frm,
|
||||
int width, int height, int stride,
|
||||
double *H);
|
||||
|
||||
|
||||
unsigned char *src,
|
||||
int p_col, int p_row,
|
||||
int p_width, int p_height, int p_stride,
|
||||
int subsampling_col, int subsampling_row,
|
||||
int x_scale, int y_scale);
|
||||
|
||||
unsigned char interpolate(unsigned char *ref, double x, double y,
|
||||
int width, int height, int stride);
|
||||
|
@ -4228,7 +4228,7 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
|
||||
#define GLOBAL_MOTION_ADVANTAGE_THRESH_RZ 0.60
|
||||
#define GLOBAL_MOTION_ADVANTAGE_THRESH_TR 0.75
|
||||
// #define USE_BLOCK_BASED_GLOBAL_MOTION_COMPUTATION
|
||||
// #define USE_FEATURE_BASED_GLOBAL_MOTION_COMPUTATION
|
||||
#define USE_FEATURE_BASED_GLOBAL_MOTION_COMPUTATION
|
||||
|
||||
static void convert_translation_to_params(
|
||||
double *H, Global_Motion_Params *model) {
|
||||
@ -4350,6 +4350,16 @@ static void encode_frame_internal(VP9_COMP *cpi) {
|
||||
global_motion + i * get_numparams(GLOBAL_MOTION_MODEL),
|
||||
GLOBAL_MOTION_MODEL,
|
||||
&cm->global_motion[frame][i]);
|
||||
refine_quant_param(&cm->global_motion[frame][i],
|
||||
GLOBAL_MOTION_MODEL, ref_buf->y_buffer,
|
||||
ref_buf->y_crop_width,
|
||||
ref_buf->y_crop_height,
|
||||
ref_buf->y_stride,
|
||||
cpi->Source->y_buffer,
|
||||
cpi->Source->y_crop_width,
|
||||
cpi->Source->y_crop_height,
|
||||
cpi->Source->y_stride, 3);
|
||||
|
||||
if (get_gmtype(&cm->global_motion[frame][i]) != GLOBAL_ZERO) {
|
||||
double erroradvantage_trans;
|
||||
double erroradvantage =
|
||||
|
@ -95,51 +95,177 @@ static double compute_error_score(TransformationType type,
|
||||
return sqrt(sqerr / n);
|
||||
}
|
||||
|
||||
void refine_param(TransformationType type, unsigned char *frm,
|
||||
unsigned char *ref, double *H,
|
||||
int param_index, int width, int height,
|
||||
int stride, int n_refinements) {
|
||||
int i;
|
||||
double step_mse;
|
||||
double best_mse;
|
||||
double curr_mse;
|
||||
double curr_param = H[param_index];
|
||||
double step = 0.5;
|
||||
double best_param = curr_param;
|
||||
|
||||
curr_mse = compute_warp_and_error(type, ref, frm, width, height, stride, H);
|
||||
best_mse = curr_mse;
|
||||
for (i = 0; i < n_refinements; i++) {
|
||||
// look to the left
|
||||
H[param_index] = curr_param - step;
|
||||
step_mse = compute_warp_and_error(type, ref, frm, width, height, stride, H);
|
||||
if (step_mse < best_mse) {
|
||||
step /= 2;
|
||||
best_mse = step_mse;
|
||||
best_param = H[param_index];
|
||||
curr_param = best_param;
|
||||
curr_mse = step_mse;
|
||||
continue;
|
||||
}
|
||||
|
||||
// look to the right
|
||||
H[param_index] = curr_param + step;
|
||||
step_mse = compute_warp_and_error(type, ref, frm, width, height, stride, H);
|
||||
if (step_mse < best_mse) {
|
||||
step /= 2;
|
||||
best_mse = step_mse;
|
||||
best_param = H[param_index];
|
||||
curr_param = best_param;
|
||||
curr_mse = step_mse;
|
||||
continue;
|
||||
}
|
||||
|
||||
// no improvement found-> means we're either already at a minimum or
|
||||
// step is too wide
|
||||
step /= 4;
|
||||
static int16_t* get_gm_param_trans(Global_Motion_Params *gm, int index) {
|
||||
switch (index) {
|
||||
case 0 :
|
||||
return &gm->mv.as_mv.row;
|
||||
break;
|
||||
case 1 :
|
||||
return &gm->mv.as_mv.col;
|
||||
break;
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
H[param_index] = best_param;
|
||||
static int* get_gm_param_rotzoom(Global_Motion_Params *gm, int index) {
|
||||
switch (index) {
|
||||
case 0 :
|
||||
return &gm->rotation;
|
||||
break;
|
||||
case 1 :
|
||||
return &gm->zoom;
|
||||
break;
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void refine_quant_param_trans(Global_Motion_Params *gm,
|
||||
TransformationType type,
|
||||
unsigned char *ref, int ref_width,
|
||||
int ref_height, int ref_stride,
|
||||
unsigned char *frm, int frm_width,
|
||||
int frm_height, int frm_stride,
|
||||
int n_refinements) {
|
||||
int i = 0, p;
|
||||
double step_mse;
|
||||
int step;
|
||||
int16_t *param;
|
||||
int16_t curr_param;
|
||||
int16_t best_param;
|
||||
projectPointsType projectPoints = get_projectPointsType(type);
|
||||
double best_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
for (p = 0; p < 2; ++p) {
|
||||
param = get_gm_param_trans(gm, p);
|
||||
step = 1 << (n_refinements + 1);
|
||||
curr_param = *param;
|
||||
best_param = curr_param;
|
||||
for (i = 0; i < n_refinements; i++) {
|
||||
// look to the left
|
||||
*param = curr_param - step;
|
||||
step_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
if (step_mse < best_mse) {
|
||||
step >>= 1;
|
||||
best_mse = step_mse;
|
||||
best_param = *param;
|
||||
curr_param = best_param;
|
||||
continue;
|
||||
}
|
||||
|
||||
// look to the right
|
||||
*param = curr_param + step;
|
||||
step_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
if (step_mse < best_mse) {
|
||||
step >>= 1;
|
||||
best_mse = step_mse;
|
||||
best_param = *param;
|
||||
curr_param = best_param;
|
||||
continue;
|
||||
}
|
||||
|
||||
// no improvement found-> means we're either already at a minimum or
|
||||
// step is too wide
|
||||
step >>= 1;
|
||||
}
|
||||
|
||||
*param = best_param;
|
||||
}
|
||||
}
|
||||
|
||||
static void refine_quant_param_rotzoom(Global_Motion_Params *gm,
|
||||
TransformationType type,
|
||||
unsigned char *ref, int ref_width,
|
||||
int ref_height, int ref_stride,
|
||||
unsigned char *frm, int frm_width,
|
||||
int frm_height, int frm_stride,
|
||||
int n_refinements) {
|
||||
int i = 0, p;
|
||||
double step_mse;
|
||||
int step;
|
||||
int *param;
|
||||
int curr_param;
|
||||
int best_param;
|
||||
projectPointsType projectPoints = get_projectPointsType(type);
|
||||
double best_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
for (p = 0; p < 2; ++p) {
|
||||
param = get_gm_param_rotzoom(gm, p);
|
||||
step = 1 << (n_refinements + 1);
|
||||
curr_param = *param;
|
||||
best_param = curr_param;
|
||||
for (i = 0; i < n_refinements; i++) {
|
||||
// look to the left
|
||||
*param = curr_param - step;
|
||||
step_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
if (step_mse < best_mse) {
|
||||
step >>= 1;
|
||||
best_mse = step_mse;
|
||||
best_param = *param;
|
||||
curr_param = best_param;
|
||||
continue;
|
||||
}
|
||||
|
||||
// look to the right
|
||||
*param = curr_param + step;
|
||||
step_mse = compute_warp_and_error(gm, projectPoints, ref, ref_width,
|
||||
ref_height, ref_stride, frm, 0, 0,
|
||||
frm_width, frm_height, frm_stride,
|
||||
0, 0, 16, 16);
|
||||
if (step_mse < best_mse) {
|
||||
step >>= 1;
|
||||
best_mse = step_mse;
|
||||
best_param = *param;
|
||||
curr_param = best_param;
|
||||
continue;
|
||||
}
|
||||
|
||||
// no improvement found-> means we're either already at a minimum or
|
||||
// step is too wide
|
||||
step >>= 1;
|
||||
}
|
||||
|
||||
*param = best_param;
|
||||
}
|
||||
}
|
||||
|
||||
void refine_quant_param(Global_Motion_Params *gm,
|
||||
TransformationType type,
|
||||
unsigned char *ref, int ref_width,
|
||||
int ref_height, int ref_stride,
|
||||
unsigned char *frm, int frm_width, int frm_height,
|
||||
int frm_stride, int n_refinements) {
|
||||
switch (gm->gmtype) {
|
||||
case GLOBAL_TRANSLATION :
|
||||
refine_quant_param_trans(gm, type, ref, ref_width, ref_height,
|
||||
ref_stride, frm, frm_width, frm_height,
|
||||
frm_stride, n_refinements);
|
||||
break;
|
||||
case GLOBAL_ROTZOOM :
|
||||
refine_quant_param_rotzoom(gm, type, ref, ref_width, ref_height,
|
||||
ref_stride, frm, frm_width, frm_height,
|
||||
frm_stride, n_refinements);
|
||||
refine_quant_param_trans(gm, type, ref, ref_width, ref_height,
|
||||
ref_stride, frm, frm_width, frm_height,
|
||||
frm_stride, n_refinements);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int compute_global_motion_single(TransformationType type,
|
||||
@ -366,16 +492,6 @@ int vp9_compute_global_motion_multiple_optical_flow(struct VP9_COMP *cpi,
|
||||
num_correspondences, H,
|
||||
max_models, inlier_prob,
|
||||
&num_models, inlier_map);
|
||||
#ifdef PARAM_SEARCH
|
||||
for (j = 0; j < num_models; ++j) {
|
||||
for (i = 0; i < get_numparams(type); ++i)
|
||||
|
||||
refine_param(type, frm->y_buffer, ref->y_buffer, H,
|
||||
i + j * get_numparams(type), frm->y_width, frm->y_height,
|
||||
frm->y_stride, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("Models = %d, Inliers = %d\n", num_models, num_inliers);
|
||||
if (num_models)
|
||||
@ -458,16 +574,6 @@ int vp9_compute_global_motion_multiple_feature_based(
|
||||
num_correspondences, H,
|
||||
max_models, inlier_prob,
|
||||
&num_models, inlier_map);
|
||||
#ifdef PARAM_SEARCH
|
||||
for (j = 0; j < num_models; ++j) {
|
||||
for (i = 0; i < get_numparams(type); ++i)
|
||||
|
||||
refine_param(type, frm->y_buffer, ref->y_buffer, H,
|
||||
i + j * get_numparams(type), frm->y_width, frm->y_height,
|
||||
frm->y_stride, 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("Models = %d, Inliers = %d\n", num_models, num_inliers);
|
||||
if (num_models)
|
||||
|
@ -31,10 +31,11 @@ INLINE ransacType get_ransacType(TransformationType type);
|
||||
// Searches around each parameter and seeks to minimize MSE between
|
||||
// the warped frame produced from the set of parameters and the frame being
|
||||
// approximated.
|
||||
void refine_param(TransformationType type, unsigned char *frm,
|
||||
unsigned char *ref, double *H,
|
||||
int param_index, int width, int height,
|
||||
int stride, int n_refinements);
|
||||
void refine_quant_param(Global_Motion_Params *gm, TransformationType type,
|
||||
unsigned char *ref, int ref_width,
|
||||
int ref_height, int ref_stride,
|
||||
unsigned char *frm, int frm_width, int frm_height,
|
||||
int frm_stride, int n_refinements);
|
||||
|
||||
// Returns number of models actually returned: 1 - if success, 0 - if failure
|
||||
int vp9_compute_global_motion_single_feature_based(struct VP9_COMP *cpi,
|
||||
|
Loading…
x
Reference in New Issue
Block a user