Compute multiple global motions and pick best by error adv.
Modify ransac to keep the N best global motions by num_inliers and
variance rather than a single one. Compute the error advantage for
each in encode_frame_internal(), and use the best as the global motion
for that pair of <target, reference> frames.
Improvements for different values of N:
N %PSNR gain on lowres
1 (current impl) 1.287
2 1.328
4 1.370
8 1.419
16 1.427
32 1.439
Change-Id: Ic0c9066a3f175a5ea0a78828cd244104e70144ba
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 6ab7c02..55a0a91 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -26,6 +26,7 @@
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/idct.h"
+#include "av1/common/mv.h"
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
@@ -5041,23 +5042,45 @@
!cpi->global_motion_search_done) {
YV12_BUFFER_CONFIG *ref_buf;
int frame;
- double erroradvantage = 0;
- double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
+ double params_by_motion[RANSAC_NUM_MOTIONS * (MAX_PARAMDIM - 1)];
+ const double *params_this_motion;
+ int inliers_by_motion[RANSAC_NUM_MOTIONS];
+ WarpedMotionParams tmp_wm_params;
+ static const double kInfiniteErrAdv = 1e12;
+ static const double kIdentityParams[MAX_PARAMDIM - 1] = {
+ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
+ };
+
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
ref_buf = get_ref_frame_buffer(cpi, frame);
if (ref_buf) {
TransformationType model;
aom_clear_system_state();
for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
- if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
+ double best_erroradvantage = kInfiniteErrAdv;
+
+ // Initially set all params to identity.
+ for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
+ memcpy(params_by_motion + (MAX_PARAMDIM - 1) * i, kIdentityParams,
+ (MAX_PARAMDIM - 1) * sizeof(*params_by_motion));
+ }
+
+ compute_global_motion_feature_based(
+ model, cpi->Source, ref_buf,
#if CONFIG_AOM_HIGHBITDEPTH
- cpi->common.bit_depth,
+ cpi->common.bit_depth,
#endif // CONFIG_AOM_HIGHBITDEPTH
- params)) {
- convert_model_to_params(params, &cm->global_motion[frame]);
- if (cm->global_motion[frame].wmtype != IDENTITY) {
- erroradvantage = refine_integerized_param(
- &cm->global_motion[frame], cm->global_motion[frame].wmtype,
+ inliers_by_motion, params_by_motion, RANSAC_NUM_MOTIONS);
+
+ for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
+ if (inliers_by_motion[i] == 0) continue;
+
+ params_this_motion = params_by_motion + (MAX_PARAMDIM - 1) * i;
+ convert_model_to_params(params_this_motion, &tmp_wm_params);
+
+ if (tmp_wm_params.wmtype != IDENTITY) {
+ const double erroradv_this_motion = refine_integerized_param(
+ &tmp_wm_params, tmp_wm_params.wmtype,
#if CONFIG_AOM_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
@@ -5065,12 +5088,23 @@
ref_buf->y_stride, cpi->Source->y_buffer,
cpi->Source->y_width, cpi->Source->y_height,
cpi->Source->y_stride, 3);
- if (erroradvantage >
- gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
- set_default_gmparams(&cm->global_motion[frame]);
+ if (erroradv_this_motion < best_erroradvantage) {
+ best_erroradvantage = erroradv_this_motion;
+ // Save the wm_params modified by refine_integerized_param()
+ // rather than motion index to avoid rerunning refine() below.
+ memcpy(&(cm->global_motion[frame]), &tmp_wm_params,
+ sizeof(WarpedMotionParams));
}
}
}
+
+ // If the best error advantage found doesn't meet the threshold for
+ // this motion type, revert to IDENTITY.
+ if (best_erroradvantage >
+ gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
+ set_default_gmparams(&cm->global_motion[frame]);
+ }
+
if (cm->global_motion[frame].wmtype != IDENTITY) break;
}
aom_clear_system_state();
diff --git a/av1/encoder/global_motion.c b/av1/encoder/global_motion.c
index 5a5e352..7471bfc 100644
--- a/av1/encoder/global_motion.c
+++ b/av1/encoder/global_motion.c
@@ -238,24 +238,6 @@
}
}
-// computes global motion parameters by fitting a model using RANSAC
-static int compute_global_motion_params(TransformationType type,
- int *correspondences,
- int num_correspondences,
- double *params) {
- int result;
- int num_inliers = 0;
- RansacFunc ransac = get_ransac_type(type);
- if (ransac == NULL) return 0;
-
- result = ransac(correspondences, num_correspondences, &num_inliers, params);
- if (!result && num_inliers < MIN_INLIER_PROB * num_correspondences) {
- result = 1;
- num_inliers = 0;
- }
- return num_inliers;
-}
-
#if CONFIG_AOM_HIGHBITDEPTH
unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm, int bit_depth) {
int i, j;
@@ -271,20 +253,20 @@
}
#endif
-int compute_global_motion_feature_based(TransformationType type,
- YV12_BUFFER_CONFIG *frm,
- YV12_BUFFER_CONFIG *ref,
+int compute_global_motion_feature_based(
+ TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
#if CONFIG_AOM_HIGHBITDEPTH
- int bit_depth,
+ int bit_depth,
#endif
- double *params) {
+ int *num_inliers_by_motion, double *params_by_motion, int num_motions) {
+ int i;
int num_frm_corners, num_ref_corners;
int num_correspondences;
int *correspondences;
- int num_inliers;
int frm_corners[2 * MAX_CORNERS], ref_corners[2 * MAX_CORNERS];
unsigned char *frm_buffer = frm->y_buffer;
unsigned char *ref_buffer = ref->y_buffer;
+ RansacFunc ransac = get_ransac_type(type);
#if CONFIG_AOM_HIGHBITDEPTH
if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
@@ -317,8 +299,21 @@
(int *)ref_corners, num_ref_corners, frm->y_width, frm->y_height,
frm->y_stride, ref->y_stride, correspondences);
- num_inliers = compute_global_motion_params(type, correspondences,
- num_correspondences, params);
+ ransac(correspondences, num_correspondences, num_inliers_by_motion,
+ params_by_motion, num_motions);
+
free(correspondences);
- return (num_inliers > 0);
+
+ // Set num_inliers = 0 for motions with too few inliers so they are ignored.
+ for (i = 0; i < num_motions; ++i) {
+ if (num_inliers_by_motion[i] < MIN_INLIER_PROB * num_correspondences) {
+ num_inliers_by_motion[i] = 0;
+ }
+ }
+
+ // Return true if any one of the motions has inliers.
+ for (i = 0; i < num_motions; ++i) {
+ if (num_inliers_by_motion[i] > 0) return 1;
+ }
+ return 0;
}
diff --git a/av1/encoder/global_motion.h b/av1/encoder/global_motion.h
index 141a16e..232489f 100644
--- a/av1/encoder/global_motion.h
+++ b/av1/encoder/global_motion.h
@@ -20,6 +20,8 @@
extern "C" {
#endif
+#define RANSAC_NUM_MOTIONS 1
+
extern const double gm_advantage_thresh[TRANS_TYPES];
void convert_to_params(const double *params, int32_t *model);
@@ -43,23 +45,24 @@
int d_height, int d_stride, int n_refinements);
/*
- Computes global motion parameters between two frames. The array
- "params" should be length 9, where the first 2 slots are translation
- parameters in (row, col) order, and the remaining slots correspond
- to values in the transformation matrix of the corresponding motion
- model. They are arranged in "params" such that values on the tx-matrix
- diagonal have odd numbered indices so the folowing matrix:
- A | B
- C | D
- would produce params = [trans row, trans col, B, A, C, D]
+ Computes "num_motions" candidate global motion parameters between two frames.
+ The array "params_by_motion" should be length 8 * "num_motions", where the
+ first 2 slots in each group of 8 parameters are the translation parameters in
+ (row, col) order, and the remaining slots correspond to values in the
+ transformation matrix of the corresponding motion model. They are arranged in
+ "params" such that values on the tx-matrix diagonal have odd numbered indices
+ so the folowing matrix: A | B C | D would produce params = [trans row, trans
+ col, B, A, C, D].
+ "num_inliers" should be length "num_motions", and will be populated with the
+ number of inlier feature points for each motion. Params for which the
+ num_inliers entry is 0 should be ignored by the caller.
*/
-int compute_global_motion_feature_based(TransformationType type,
- YV12_BUFFER_CONFIG *frm,
- YV12_BUFFER_CONFIG *ref,
+int compute_global_motion_feature_based(
+ TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
#if CONFIG_AOM_HIGHBITDEPTH
- int bit_depth,
+ int bit_depth,
#endif
- double *params);
+ int *num_inliers_by_motion, double *params_by_motion, int num_motions);
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/encoder/ransac.c b/av1/encoder/ransac.c
index ab0d530..44dc7f5 100644
--- a/av1/encoder/ransac.c
+++ b/av1/encoder/ransac.c
@@ -916,8 +916,50 @@
return 1;
}
-static int ransac(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params, const int minpts,
+typedef struct {
+ int num_inliers;
+ double variance;
+ int *inlier_indices;
+} RANSAC_MOTION;
+
+// Return -1 if 'a' is a better motion, 1 if 'b' is better, 0 otherwise.
+static int compare_motions(const void *arg_a, const void *arg_b) {
+ const RANSAC_MOTION *motion_a = (RANSAC_MOTION *)arg_a;
+ const RANSAC_MOTION *motion_b = (RANSAC_MOTION *)arg_b;
+
+ if (motion_a->num_inliers > motion_b->num_inliers) return -1;
+ if (motion_a->num_inliers < motion_b->num_inliers) return 1;
+ if (motion_a->variance < motion_b->variance) return -1;
+ if (motion_a->variance > motion_b->variance) return 1;
+ return 0;
+}
+
+static int is_better_motion(const RANSAC_MOTION *motion_a,
+ const RANSAC_MOTION *motion_b) {
+ return compare_motions(motion_a, motion_b) < 0;
+}
+
+static void copy_points_at_indices(double *dest, const double *src,
+ const int *indices, int num_points) {
+ for (int i = 0; i < num_points; ++i) {
+ const int index = indices[i];
+ dest[i * 2] = src[index * 2];
+ dest[i * 2 + 1] = src[index * 2 + 1];
+ }
+}
+
+static const double kInfiniteVariance = 1e12;
+
+static void clear_motion(RANSAC_MOTION *motion, int num_points) {
+ motion->num_inliers = 0;
+ motion->variance = kInfiniteVariance;
+ memset(motion->inlier_indices, 0,
+ sizeof(*motion->inlier_indices * num_points));
+}
+
+static int ransac(const int *matched_points, int npoints,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_desired_motions, const int minpts,
IsDegenerateFunc is_degenerate,
FindTransformationFunc find_transformation,
ProjectPointsDoubleFunc projectpoints) {
@@ -925,51 +967,61 @@
static const double EPS = 1e-12;
int N = 10000, trial_count = 0;
- int i;
+ int i = 0;
int ret_val = 0;
+
unsigned int seed = (unsigned int)npoints;
- int max_inliers = 0;
- double best_variance = 0.0;
- double params[MAX_PARAMDIM];
- WarpedMotionParams wm;
- double points1[2 * MAX_MINPTS];
- double points2[2 * MAX_MINPTS];
int indices[MAX_MINPTS] = { 0 };
- double *best_inlier_set1;
- double *best_inlier_set2;
- double *inlier_set1;
- double *inlier_set2;
- double *corners1;
- double *corners2;
+ double *points1, *points2;
+ double *corners1, *corners2;
double *image1_coord;
+ // Store information for the num_desired_motions best transformations found
+ // and the worst motion among them, as well as the motion currently under
+ // consideration.
+ RANSAC_MOTION *motions, *worst_kept_motion = NULL;
+ RANSAC_MOTION current_motion;
+
+ // Store the parameters and the indices of the inlier points for the motion
+ // currently under consideration.
+ double params_this_motion[MAX_PARAMDIM];
+
double *cnp1, *cnp2;
- *number_of_inliers = 0;
if (npoints < minpts * MINPTS_MULTIPLIER || npoints == 0) {
return 1;
}
- memset(&wm, 0, sizeof(wm));
- best_inlier_set1 =
- (double *)aom_malloc(sizeof(*best_inlier_set1) * npoints * 2);
- best_inlier_set2 =
- (double *)aom_malloc(sizeof(*best_inlier_set2) * npoints * 2);
- inlier_set1 = (double *)aom_malloc(sizeof(*inlier_set1) * npoints * 2);
- inlier_set2 = (double *)aom_malloc(sizeof(*inlier_set2) * npoints * 2);
+ points1 = (double *)aom_malloc(sizeof(*points1) * npoints * 2);
+ points2 = (double *)aom_malloc(sizeof(*points2) * npoints * 2);
corners1 = (double *)aom_malloc(sizeof(*corners1) * npoints * 2);
corners2 = (double *)aom_malloc(sizeof(*corners2) * npoints * 2);
image1_coord = (double *)aom_malloc(sizeof(*image1_coord) * npoints * 2);
- if (!(best_inlier_set1 && best_inlier_set2 && inlier_set1 && inlier_set2 &&
- corners1 && corners2 && image1_coord)) {
+ motions =
+ (RANSAC_MOTION *)aom_malloc(sizeof(RANSAC_MOTION) * num_desired_motions);
+ for (i = 0; i < num_desired_motions; ++i) {
+ motions[i].inlier_indices =
+ (int *)aom_malloc(sizeof(*motions->inlier_indices) * npoints);
+ clear_motion(motions + i, npoints);
+ }
+ current_motion.inlier_indices =
+ (int *)aom_malloc(sizeof(*current_motion.inlier_indices) * npoints);
+ clear_motion(¤t_motion, npoints);
+
+ worst_kept_motion = motions;
+
+ if (!(points1 && points2 && corners1 && corners2 && image1_coord && motions &&
+ current_motion.inlier_indices)) {
ret_val = 1;
goto finish_ransac;
}
- for (cnp1 = corners1, cnp2 = corners2, i = 0; i < npoints; ++i) {
+ cnp1 = corners1;
+ cnp2 = corners2;
+ for (i = 0; i < npoints; ++i) {
*(cnp1++) = *(matched_points++);
*(cnp1++) = *(matched_points++);
*(cnp2++) = *(matched_points++);
@@ -978,28 +1030,24 @@
matched_points -= 4 * npoints;
while (N > trial_count) {
- int num_inliers = 0;
double sum_distance = 0.0;
double sum_distance_squared = 0.0;
+ clear_motion(¤t_motion, npoints);
+
int degenerate = 1;
int num_degenerate_iter = 0;
+
while (degenerate) {
num_degenerate_iter++;
if (!get_rand_indices(npoints, minpts, indices, &seed)) {
ret_val = 1;
goto finish_ransac;
}
- i = 0;
- while (i < minpts) {
- int index = indices[i];
- // add to list
- points1[i * 2] = corners1[index * 2];
- points1[i * 2 + 1] = corners1[index * 2 + 1];
- points2[i * 2] = corners2[index * 2];
- points2[i * 2 + 1] = corners2[index * 2 + 1];
- i++;
- }
+
+ copy_points_at_indices(points1, corners1, indices, minpts);
+ copy_points_at_indices(points2, corners2, indices, minpts);
+
degenerate = is_degenerate(points1);
if (num_degenerate_iter > MAX_DEGENERATE_ITER) {
ret_val = 1;
@@ -1007,12 +1055,12 @@
}
}
- if (find_transformation(minpts, points1, points2, params)) {
+ if (find_transformation(minpts, points1, points2, params_this_motion)) {
trial_count++;
continue;
}
- projectpoints(params, corners1, image1_coord, npoints, 2, 2);
+ projectpoints(params_this_motion, corners1, image1_coord, npoints, 2, 2);
for (i = 0; i < npoints; ++i) {
double dx = image1_coord[i * 2] - corners2[i * 2];
@@ -1020,60 +1068,79 @@
double distance = sqrt(dx * dx + dy * dy);
if (distance < INLIER_THRESHOLD) {
- inlier_set1[num_inliers * 2] = corners1[i * 2];
- inlier_set1[num_inliers * 2 + 1] = corners1[i * 2 + 1];
- inlier_set2[num_inliers * 2] = corners2[i * 2];
- inlier_set2[num_inliers * 2 + 1] = corners2[i * 2 + 1];
- num_inliers++;
+ current_motion.inlier_indices[current_motion.num_inliers++] = i;
sum_distance += distance;
sum_distance_squared += distance * distance;
}
}
- if (num_inliers >= max_inliers && num_inliers > 1) {
+ if (current_motion.num_inliers >= worst_kept_motion->num_inliers &&
+ current_motion.num_inliers > 1) {
int temp;
- double fracinliers, pNoOutliers, mean_distance, variance;
-
- mean_distance = sum_distance / ((double)num_inliers);
- variance = sum_distance_squared / ((double)num_inliers - 1.0) -
- mean_distance * mean_distance * ((double)num_inliers) /
- ((double)num_inliers - 1.0);
- if ((num_inliers > max_inliers) ||
- (num_inliers == max_inliers && variance < best_variance)) {
- best_variance = variance;
- max_inliers = num_inliers;
- // Save parameters, excluding the implicit '1' in the bottom-right
- // entry of the parameter matrix
- memcpy(best_params, params, (MAX_PARAMDIM - 1) * sizeof(*best_params));
- memcpy(best_inlier_set1, inlier_set1,
- num_inliers * 2 * sizeof(*best_inlier_set1));
- memcpy(best_inlier_set2, inlier_set2,
- num_inliers * 2 * sizeof(*best_inlier_set2));
+ double fracinliers, pNoOutliers, mean_distance;
+ mean_distance = sum_distance / ((double)current_motion.num_inliers);
+ current_motion.variance =
+ sum_distance_squared / ((double)current_motion.num_inliers - 1.0) -
+ mean_distance * mean_distance * ((double)current_motion.num_inliers) /
+ ((double)current_motion.num_inliers - 1.0);
+ if (is_better_motion(¤t_motion, worst_kept_motion)) {
+ // This motion is better than the worst currently kept motion. Remember
+ // the inlier points and variance. The parameters for each kept motion
+ // will be recomputed later using only the inliers.
+ worst_kept_motion->num_inliers = current_motion.num_inliers;
+ worst_kept_motion->variance = current_motion.variance;
+ memcpy(worst_kept_motion->inlier_indices, current_motion.inlier_indices,
+ sizeof(*current_motion.inlier_indices) * npoints);
assert(npoints > 0);
- fracinliers = (double)num_inliers / (double)npoints;
+ fracinliers = (double)current_motion.num_inliers / (double)npoints;
pNoOutliers = 1 - pow(fracinliers, minpts);
pNoOutliers = fmax(EPS, pNoOutliers);
pNoOutliers = fmin(1 - EPS, pNoOutliers);
temp = (int)(log(1.0 - PROBABILITY_REQUIRED) / log(pNoOutliers));
+
if (temp > 0 && temp < N) {
N = AOMMAX(temp, MIN_TRIALS);
}
+
+ // Determine the new worst kept motion and its num_inliers and variance.
+ for (i = 0; i < num_desired_motions; ++i) {
+ if (is_better_motion(worst_kept_motion, &motions[i])) {
+ worst_kept_motion = &motions[i];
+ }
+ }
}
}
trial_count++;
}
- find_transformation(max_inliers, best_inlier_set1, best_inlier_set2,
- best_params);
- *number_of_inliers = max_inliers;
+
+ // Sort the motions, best first.
+ qsort(motions, num_desired_motions, sizeof(RANSAC_MOTION), compare_motions);
+
+ // Recompute the motions using only the inliers.
+ for (i = 0; i < num_desired_motions; ++i) {
+ copy_points_at_indices(points1, corners1, motions[i].inlier_indices,
+ motions[i].num_inliers);
+ copy_points_at_indices(points2, corners2, motions[i].inlier_indices,
+ motions[i].num_inliers);
+
+ find_transformation(motions[i].num_inliers, points1, points2,
+ params_by_motion + (MAX_PARAMDIM - 1) * i);
+ num_inliers_by_motion[i] = motions[i].num_inliers;
+ }
+
finish_ransac:
- aom_free(best_inlier_set1);
- aom_free(best_inlier_set2);
- aom_free(inlier_set1);
- aom_free(inlier_set2);
+ aom_free(points1);
+ aom_free(points2);
aom_free(corners1);
aom_free(corners2);
aom_free(image1_coord);
+ aom_free(current_motion.inlier_indices);
+ for (i = 0; i < num_desired_motions; ++i) {
+ aom_free(motions[i].inlier_indices);
+ }
+ aom_free(motions);
+
return ret_val;
}
@@ -1097,44 +1164,52 @@
is_collinear3(p, p + 4, p + 6) || is_collinear3(p + 2, p + 4, p + 6);
}
-int ransac_translation(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 3,
+int ransac_translation(int *matched_points, int npoints,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 3,
is_degenerate_translation, find_translation,
project_points_double_translation);
}
-int ransac_rotzoom(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 3,
- is_degenerate_affine, find_rotzoom,
- project_points_double_rotzoom);
+int ransac_rotzoom(int *matched_points, int npoints, int *num_inliers_by_motion,
+ double *params_by_motion, int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 3, is_degenerate_affine,
+ find_rotzoom, project_points_double_rotzoom);
}
-int ransac_affine(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 3,
- is_degenerate_affine, find_affine,
- project_points_double_affine);
+int ransac_affine(int *matched_points, int npoints, int *num_inliers_by_motion,
+ double *params_by_motion, int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 3, is_degenerate_affine,
+ find_affine, project_points_double_affine);
}
-int ransac_homography(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 4,
+int ransac_homography(int *matched_points, int npoints,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 4,
is_degenerate_homography, find_homography,
project_points_double_homography);
}
int ransac_hortrapezoid(int *matched_points, int npoints,
- int *number_of_inliers, double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 4,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 4,
is_degenerate_homography, find_hortrapezoid,
project_points_double_hortrapezoid);
}
int ransac_vertrapezoid(int *matched_points, int npoints,
- int *number_of_inliers, double *best_params) {
- return ransac(matched_points, npoints, number_of_inliers, best_params, 4,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_desired_motions) {
+ return ransac(matched_points, npoints, num_inliers_by_motion,
+ params_by_motion, num_desired_motions, 4,
is_degenerate_homography, find_vertrapezoid,
project_points_double_vertrapezoid);
}
diff --git a/av1/encoder/ransac.h b/av1/encoder/ransac.h
index 1eeb105..f611add 100644
--- a/av1/encoder/ransac.h
+++ b/av1/encoder/ransac.h
@@ -20,20 +20,25 @@
#include "av1/common/warped_motion.h"
typedef int (*RansacFunc)(int *matched_points, int npoints,
- int *number_of_inliers, double *best_params);
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_motions);
/* Each of these functions fits a motion model from a set of
corresponding points in 2 frames using RANSAC. */
-int ransac_homography(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params);
-int ransac_affine(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params);
+int ransac_homography(int *matched_points, int npoints,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_motions);
+int ransac_affine(int *matched_points, int npoints, int *num_inliers_by_motion,
+ double *params_by_motion, int num_motions);
int ransac_hortrapezoid(int *matched_points, int npoints,
- int *number_of_inliers, double *best_params);
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_motions);
int ransac_vertrapezoid(int *matched_points, int npoints,
- int *number_of_inliers, double *best_params);
-int ransac_rotzoom(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params);
-int ransac_translation(int *matched_points, int npoints, int *number_of_inliers,
- double *best_params);
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_motions);
+int ransac_rotzoom(int *matched_points, int npoints, int *num_inliers_by_motion,
+ double *params_by_motion, int num_motions);
+int ransac_translation(int *matched_points, int npoints,
+ int *num_inliers_by_motion, double *params_by_motion,
+ int num_motions);
#endif // AV1_ENCODER_RANSAC_H_