Support trapezoidal models for global motion
Adds functinoality for least-squares, RANSAC as well as encoding and decoding with new constrained homographies that warp blocks to horizontal and/or vertical trapezoids. This is for future experimentation. None of the models are actually enabled in the code. Change-Id: I1936018c6b11587d6fd83c3a2c63548cb641b33f
This commit is contained in:
Родитель
15dbc1a149
Коммит
5dfa930084
|
@ -128,22 +128,33 @@ static const uint8_t log_in_base_2[] = {
|
|||
};
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
#if GLOBAL_TRANS_TYPES == 5
|
||||
#if GLOBAL_TRANS_TYPES == 7 // All models
|
||||
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
|
||||
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4,
|
||||
-ROTZOOM, 6, -AFFINE, -HOMOGRAPHY };
|
||||
-ROTZOOM, 6, -AFFINE, 8,
|
||||
-HOMOGRAPHY, 10, -HORTRAPEZOID, -VERTRAPEZOID };
|
||||
|
||||
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
|
||||
{ 224, 128, 192, 192 };
|
||||
{ 224, 128, 192, 192, 32, 128 };
|
||||
|
||||
#elif GLOBAL_TRANS_TYPES == 4
|
||||
#elif GLOBAL_TRANS_TYPES == 6 // Do not allow full homography
|
||||
const aom_tree_index
|
||||
av1_global_motion_types_tree[TREE_SIZE(GLOBAL_TRANS_TYPES)] = {
|
||||
-IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, 6, -AFFINE, 8, -HORTRAPEZOID,
|
||||
-VERTRAPEZOID
|
||||
};
|
||||
|
||||
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
|
||||
{ 224, 128, 192, 192, 128 };
|
||||
|
||||
#elif GLOBAL_TRANS_TYPES == 4 // Upto Affine
|
||||
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
|
||||
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, -AFFINE };
|
||||
|
||||
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
|
||||
{ 224, 128, 240 };
|
||||
|
||||
#elif GLOBAL_TRANS_TYPES == 3
|
||||
#elif GLOBAL_TRANS_TYPES == 3 // Upto rotation-zoom
|
||||
|
||||
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
|
||||
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, -ROTZOOM };
|
||||
|
|
|
@ -57,21 +57,28 @@ typedef enum {
|
|||
TRANSLATION = 1, // translational motion 2-parameter
|
||||
ROTZOOM = 2, // simplified affine with rotation + zoom only, 4-parameter
|
||||
AFFINE = 3, // affine, 6-parameter
|
||||
HOMOGRAPHY = 4, // homography, 8-parameter
|
||||
TRANS_TYPES = 5,
|
||||
HORTRAPEZOID = 4, // constrained homography, hor trapezoid, 6-parameter
|
||||
VERTRAPEZOID = 5, // constrained homography, ver trapezoid, 6-parameter
|
||||
HOMOGRAPHY = 6, // homography, 8-parameter
|
||||
TRANS_TYPES = 7,
|
||||
} TransformationType;
|
||||
/* clang-format on */
|
||||
|
||||
// Number of types used for global motion (must be >= 3 and <= TRANS_TYPES)
|
||||
// The following can be useful:
|
||||
// GLOBAL_TRANS_TYPES 3 - up to rotation-zoom
|
||||
// GLOBAL_TRANS_TYPES 4 - up to affine
|
||||
// GLOBAL_TRANS_TYPES 6 - up to hor/ver trapezoids
|
||||
// GLOBAL_TRANS_TYPES 7 - up to full homography
|
||||
#define GLOBAL_TRANS_TYPES 3
|
||||
|
||||
// number of parameters used by each transformation in TransformationTypes
|
||||
static const int n_trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6, 8 };
|
||||
static const int trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6, 6, 6, 8 };
|
||||
|
||||
// The order of values in the wmmat matrix below is best described
|
||||
// by the homography:
|
||||
// [x' (m2 m3 m0 [x
|
||||
// y' = m4 m5 m1 * y
|
||||
// z . y' = m4 m5 m1 * y
|
||||
// 1] m6 m7 1) 1]
|
||||
typedef struct {
|
||||
TransformationType wmtype;
|
||||
|
@ -134,6 +141,10 @@ typedef struct {
|
|||
#define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
|
||||
#define GM_AFFINE_BITS (GM_ROTZOOM_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
|
||||
#define GM_HOMOGRAPHY_BITS (GM_AFFINE_BITS + (GM_ABS_ROW3HOMO_BITS + 1) * 2)
|
||||
#define GM_HORTRAPEZOID_BITS \
|
||||
(GM_AFFINE_BITS - GM_ABS_ALPHA_BITS + GM_ABS_ROW3HOMO_BITS)
|
||||
#define GM_VERTRAPEZOID_BITS \
|
||||
(GM_AFFINE_BITS - GM_ABS_ALPHA_BITS + GM_ABS_ROW3HOMO_BITS)
|
||||
|
||||
// Convert a global motion translation vector (which may have more bits than a
|
||||
// regular motion vector) into a motion vector
|
||||
|
@ -154,7 +165,11 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
|
|||
}
|
||||
|
||||
static INLINE TransformationType get_gmtype(const WarpedMotionParams *gm) {
|
||||
// if (gm->wmmat[6] != 0 || gm->wmmat[7] != 0) return HOMOGRAPHY;
|
||||
if (gm->wmmat[6] != 0 || gm->wmmat[7] != 0) {
|
||||
if (!gm->wmmat[6] && !gm->wmmat[4]) return HORTRAPEZOID;
|
||||
if (!gm->wmmat[7] && !gm->wmmat[3]) return VERTRAPEZOID;
|
||||
return HOMOGRAPHY;
|
||||
}
|
||||
if (gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[4] &&
|
||||
gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[3]) {
|
||||
return ((!gm->wmmat[1] && !gm->wmmat[0]) ? IDENTITY : TRANSLATION);
|
||||
|
|
|
@ -178,6 +178,72 @@ void project_points_affine(int32_t *mat, int *points, int *proj, const int n,
|
|||
}
|
||||
}
|
||||
|
||||
void project_points_hortrapezoid(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
const int subsampling_y) {
|
||||
int i;
|
||||
int64_t x, y, Z;
|
||||
int64_t xp, yp;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
x = (subsampling_x ? 4 * x + 1 : 2 * x);
|
||||
y = (subsampling_y ? 4 * y + 1 : 2 * y);
|
||||
|
||||
Z = (mat[7] * y + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1)));
|
||||
xp = (mat[2] * x + mat[3] * y + 2 * mat[0]) *
|
||||
(1 << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
|
||||
WARPEDMODEL_PREC_BITS));
|
||||
yp = (mat[5] * y + 2 * mat[1]) *
|
||||
(1 << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
|
||||
WARPEDMODEL_PREC_BITS));
|
||||
|
||||
xp = xp > 0 ? (xp + Z / 2) / Z : (xp - Z / 2) / Z;
|
||||
yp = yp > 0 ? (yp + Z / 2) / Z : (yp - Z / 2) / Z;
|
||||
|
||||
if (subsampling_x) xp = (xp - (1 << (WARPEDPIXEL_PREC_BITS - 1))) / 2;
|
||||
if (subsampling_y) yp = (yp - (1 << (WARPEDPIXEL_PREC_BITS - 1))) / 2;
|
||||
*(proj++) = xp;
|
||||
*(proj++) = yp;
|
||||
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
void project_points_vertrapezoid(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
const int subsampling_y) {
|
||||
int i;
|
||||
int64_t x, y, Z;
|
||||
int64_t xp, yp;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
x = (subsampling_x ? 4 * x + 1 : 2 * x);
|
||||
y = (subsampling_y ? 4 * y + 1 : 2 * y);
|
||||
|
||||
Z = (mat[6] * x + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1)));
|
||||
xp = (mat[2] * x + 2 * mat[0]) *
|
||||
(1 << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
|
||||
WARPEDMODEL_PREC_BITS));
|
||||
yp = (mat[4] * x + mat[5] * y + 2 * mat[1]) *
|
||||
(1 << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
|
||||
WARPEDMODEL_PREC_BITS));
|
||||
|
||||
xp = xp > 0 ? (xp + Z / 2) / Z : (xp - Z / 2) / Z;
|
||||
yp = yp > 0 ? (yp + Z / 2) / Z : (yp - Z / 2) / Z;
|
||||
|
||||
if (subsampling_x) xp = (xp - (1 << (WARPEDPIXEL_PREC_BITS - 1))) / 2;
|
||||
if (subsampling_y) yp = (yp - (1 << (WARPEDPIXEL_PREC_BITS - 1))) / 2;
|
||||
*(proj++) = xp;
|
||||
*(proj++) = yp;
|
||||
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
void project_points_homography(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
|
@ -1720,6 +1786,144 @@ int find_affine(const int np, double *pts1, double *pts2, double *mat) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int find_vertrapezoid(const int np, double *pts1, double *pts2, double *mat) {
|
||||
const int np3 = np * 3;
|
||||
double *a = (double *)aom_malloc(sizeof(*a) * np3 * 14);
|
||||
double *U = a + np3 * 7;
|
||||
double S[7], V[7 * 7], H[9];
|
||||
int i, mini;
|
||||
double sx, sy, dx, dy;
|
||||
double T1[9], T2[9];
|
||||
|
||||
normalize_homography(pts1, np, T1);
|
||||
normalize_homography(pts2, np, T2);
|
||||
|
||||
for (i = 0; i < np; ++i) {
|
||||
dx = *(pts2++);
|
||||
dy = *(pts2++);
|
||||
sx = *(pts1++);
|
||||
sy = *(pts1++);
|
||||
|
||||
a[i * 3 * 7 + 0] = a[i * 3 * 7 + 1] = 0;
|
||||
a[i * 3 * 7 + 2] = -sx;
|
||||
a[i * 3 * 7 + 3] = -sy;
|
||||
a[i * 3 * 7 + 4] = -1;
|
||||
a[i * 3 * 7 + 5] = dy * sx;
|
||||
a[i * 3 * 7 + 6] = dy;
|
||||
|
||||
a[(i * 3 + 1) * 7 + 0] = sx;
|
||||
a[(i * 3 + 1) * 7 + 1] = 1;
|
||||
a[(i * 3 + 1) * 7 + 2] = a[(i * 3 + 1) * 7 + 3] = a[(i * 3 + 1) * 7 + 4] =
|
||||
0;
|
||||
a[(i * 3 + 1) * 7 + 5] = -dx * sx;
|
||||
a[(i * 3 + 1) * 7 + 6] = -dx;
|
||||
|
||||
a[(i * 3 + 2) * 7 + 0] = -dy * sx;
|
||||
a[(i * 3 + 2) * 7 + 1] = -dy;
|
||||
a[(i * 3 + 2) * 7 + 2] = dx * sx;
|
||||
a[(i * 3 + 2) * 7 + 3] = dx * sy;
|
||||
a[(i * 3 + 2) * 7 + 4] = dx;
|
||||
a[(i * 3 + 2) * 7 + 5] = a[(i * 3 + 2) * 7 + 6] = 0;
|
||||
}
|
||||
if (SVD(U, S, V, a, np3, 7)) {
|
||||
aom_free(a);
|
||||
return 1;
|
||||
} else {
|
||||
double minS = 1e12;
|
||||
mini = -1;
|
||||
for (i = 0; i < 7; ++i) {
|
||||
if (S[i] < minS) {
|
||||
minS = S[i];
|
||||
mini = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
H[1] = H[7] = 0;
|
||||
for (i = 0; i < 1; i++) H[i] = V[i * 7 + mini];
|
||||
for (; i < 6; i++) H[i + 1] = V[i * 7 + mini];
|
||||
for (; i < 7; i++) H[i + 2] = V[i * 7 + mini];
|
||||
|
||||
denormalize_homography_reorder(H, T1, T2);
|
||||
aom_free(a);
|
||||
if (H[8] == 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
// normalize
|
||||
double f = 1.0 / H[8];
|
||||
for (i = 0; i < 8; i++) mat[i] = f * H[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_hortrapezoid(const int np, double *pts1, double *pts2, double *mat) {
|
||||
const int np3 = np * 3;
|
||||
double *a = (double *)aom_malloc(sizeof(*a) * np3 * 14);
|
||||
double *U = a + np3 * 7;
|
||||
double S[7], V[7 * 7], H[9];
|
||||
int i, mini;
|
||||
double sx, sy, dx, dy;
|
||||
double T1[9], T2[9];
|
||||
|
||||
normalize_homography(pts1, np, T1);
|
||||
normalize_homography(pts2, np, T2);
|
||||
|
||||
for (i = 0; i < np; ++i) {
|
||||
dx = *(pts2++);
|
||||
dy = *(pts2++);
|
||||
sx = *(pts1++);
|
||||
sy = *(pts1++);
|
||||
|
||||
a[i * 3 * 7 + 0] = a[i * 3 * 7 + 1] = a[i * 3 * 7 + 2] = 0;
|
||||
a[i * 3 * 7 + 3] = -sy;
|
||||
a[i * 3 * 7 + 4] = -1;
|
||||
a[i * 3 * 7 + 5] = dy * sy;
|
||||
a[i * 3 * 7 + 6] = dy;
|
||||
|
||||
a[(i * 3 + 1) * 7 + 0] = sx;
|
||||
a[(i * 3 + 1) * 7 + 1] = sy;
|
||||
a[(i * 3 + 1) * 7 + 2] = 1;
|
||||
a[(i * 3 + 1) * 7 + 3] = a[(i * 3 + 1) * 7 + 4] = 0;
|
||||
a[(i * 3 + 1) * 7 + 5] = -dx * sy;
|
||||
a[(i * 3 + 1) * 7 + 6] = -dx;
|
||||
|
||||
a[(i * 3 + 2) * 7 + 0] = -dy * sx;
|
||||
a[(i * 3 + 2) * 7 + 1] = -dy * sy;
|
||||
a[(i * 3 + 2) * 7 + 2] = -dy;
|
||||
a[(i * 3 + 2) * 7 + 3] = dx * sy;
|
||||
a[(i * 3 + 2) * 7 + 4] = dx;
|
||||
a[(i * 3 + 2) * 7 + 5] = a[(i * 3 + 2) * 7 + 6] = 0;
|
||||
}
|
||||
|
||||
if (SVD(U, S, V, a, np3, 7)) {
|
||||
aom_free(a);
|
||||
return 1;
|
||||
} else {
|
||||
double minS = 1e12;
|
||||
mini = -1;
|
||||
for (i = 0; i < 7; ++i) {
|
||||
if (S[i] < minS) {
|
||||
minS = S[i];
|
||||
mini = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
H[3] = H[6] = 0;
|
||||
for (i = 0; i < 3; i++) H[i] = V[i * 7 + mini];
|
||||
for (; i < 5; i++) H[i + 1] = V[i * 7 + mini];
|
||||
for (; i < 7; i++) H[i + 2] = V[i * 7 + mini];
|
||||
|
||||
denormalize_homography_reorder(H, T1, T2);
|
||||
aom_free(a);
|
||||
if (H[8] == 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
// normalize
|
||||
double f = 1.0 / H[8];
|
||||
for (i = 0; i < 8; i++) mat[i] = f * H[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_homography(const int np, double *pts1, double *pts2, double *mat) {
|
||||
// Implemented from Peter Kovesi's normalized implementation
|
||||
const int np3 = np * 3;
|
||||
|
|
|
@ -51,6 +51,14 @@ void project_points_affine(int32_t *mat, int *points, int *proj, const int n,
|
|||
const int stride_points, const int stride_proj,
|
||||
const int subsampling_x, const int subsampling_y);
|
||||
|
||||
void project_points_hortrapezoid(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
const int subsampling_y);
|
||||
void project_points_vertrapezoid(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
const int subsampling_y);
|
||||
void project_points_homography(int32_t *mat, int *points, int *proj,
|
||||
const int n, const int stride_points,
|
||||
const int stride_proj, const int subsampling_x,
|
||||
|
@ -85,6 +93,8 @@ void av1_integerize_model(const double *model, TransformationType wmtype,
|
|||
int find_translation(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_rotzoom(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_affine(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_hortrapezoid(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_vertrapezoid(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_homography(const int np, double *pts1, double *pts2, double *mat);
|
||||
int find_projection(const int np, double *pts1, double *pts2,
|
||||
WarpedMotionParams *wm_params);
|
||||
|
|
|
@ -4449,19 +4449,28 @@ static void read_global_motion_params(WarpedMotionParams *params,
|
|||
params->wmtype = type;
|
||||
switch (type) {
|
||||
case HOMOGRAPHY:
|
||||
params->wmmat[6] = aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
|
||||
case HORTRAPEZOID:
|
||||
case VERTRAPEZOID:
|
||||
if (type != HORTRAPEZOID)
|
||||
params->wmmat[6] =
|
||||
aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
|
||||
GM_ROW3HOMO_DECODE_FACTOR;
|
||||
params->wmmat[7] = aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
|
||||
if (type != VERTRAPEZOID)
|
||||
params->wmmat[7] =
|
||||
aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
|
||||
GM_ROW3HOMO_DECODE_FACTOR;
|
||||
case AFFINE:
|
||||
case ROTZOOM:
|
||||
params->wmmat[2] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
||||
GM_ALPHA_DECODE_FACTOR +
|
||||
(1 << WARPEDMODEL_PREC_BITS);
|
||||
if (type != VERTRAPEZOID)
|
||||
params->wmmat[3] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
||||
GM_ALPHA_DECODE_FACTOR;
|
||||
if (type == AFFINE || type == HOMOGRAPHY) {
|
||||
params->wmmat[4] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
||||
if (type >= AFFINE) {
|
||||
if (type != HORTRAPEZOID)
|
||||
params->wmmat[4] =
|
||||
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
||||
GM_ALPHA_DECODE_FACTOR;
|
||||
params->wmmat[5] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
|
||||
GM_ALPHA_DECODE_FACTOR +
|
||||
|
|
|
@ -4495,10 +4495,16 @@ static void write_global_motion_params(WarpedMotionParams *params,
|
|||
&global_motion_types_encodings[type]);
|
||||
switch (type) {
|
||||
case HOMOGRAPHY:
|
||||
case HORTRAPEZOID:
|
||||
case VERTRAPEZOID:
|
||||
if (type != HORTRAPEZOID)
|
||||
aom_write_primitive_symmetric(
|
||||
w, (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF), GM_ABS_ROW3HOMO_BITS);
|
||||
w, (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
|
||||
GM_ABS_ROW3HOMO_BITS);
|
||||
if (type != VERTRAPEZOID)
|
||||
aom_write_primitive_symmetric(
|
||||
w, (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF), GM_ABS_ROW3HOMO_BITS);
|
||||
w, (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
|
||||
GM_ABS_ROW3HOMO_BITS);
|
||||
// fallthrough intended
|
||||
case AFFINE:
|
||||
case ROTZOOM:
|
||||
|
@ -4506,9 +4512,11 @@ static void write_global_motion_params(WarpedMotionParams *params,
|
|||
w,
|
||||
(params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
|
||||
GM_ABS_ALPHA_BITS);
|
||||
aom_write_primitive_symmetric(w, (params->wmmat[3] >> GM_ALPHA_PREC_DIFF),
|
||||
GM_ABS_ALPHA_BITS);
|
||||
if (type == AFFINE || type == HOMOGRAPHY) {
|
||||
if (type != VERTRAPEZOID)
|
||||
aom_write_primitive_symmetric(
|
||||
w, (params->wmmat[3] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
|
||||
if (type >= AFFINE) {
|
||||
if (type != HORTRAPEZOID)
|
||||
aom_write_primitive_symmetric(
|
||||
w, (params->wmmat[4] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
|
||||
aom_write_primitive_symmetric(w,
|
||||
|
|
|
@ -3007,7 +3007,7 @@ static int scale_down(AV1_COMP *cpi, int q) {
|
|||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
static int recode_loop_test_global_motion(AV1_COMP *cpi) {
|
||||
static const int min_blocks[TRANS_TYPES] = { 0, 60, 120, 180, 240 };
|
||||
static const int min_blocks[TRANS_TYPES] = { 0, 60, 120, 180, 180, 180, 240 };
|
||||
int i;
|
||||
int recode = 0;
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
|
|
|
@ -104,7 +104,9 @@ void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
|
|||
wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
|
||||
wm->wmmat[3] = 0;
|
||||
case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
|
||||
case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
|
||||
case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0; break;
|
||||
case HORTRAPEZOID: wm->wmmat[6] = wm->wmmat[4] = 0; break;
|
||||
case VERTRAPEZOID: wm->wmmat[7] = wm->wmmat[3] = 0; break;
|
||||
case HOMOGRAPHY: break;
|
||||
default: assert(0);
|
||||
}
|
||||
|
@ -119,9 +121,12 @@ double refine_integerized_param(WarpedMotionParams *wm,
|
|||
uint8_t *ref, int r_width, int r_height,
|
||||
int r_stride, uint8_t *dst, int d_width,
|
||||
int d_height, int d_stride, int n_refinements) {
|
||||
static const int max_trans_model_params[TRANS_TYPES] = {
|
||||
0, 2, 4, 6, 8, 8, 8
|
||||
};
|
||||
const int border = ERRORADV_BORDER;
|
||||
int i = 0, p;
|
||||
int n_params = n_trans_model_params[wmtype];
|
||||
int n_params = max_trans_model_params[wmtype];
|
||||
int32_t *param_mat = wm->wmmat;
|
||||
double step_error;
|
||||
int32_t step;
|
||||
|
@ -143,6 +148,9 @@ double refine_integerized_param(WarpedMotionParams *wm,
|
|||
for (i = 0; i < n_refinements; i++, step >>= 1) {
|
||||
for (p = 0; p < n_params; ++p) {
|
||||
int step_dir = 0;
|
||||
// Skip searches for parameters that are forced to be 0
|
||||
if (wmtype == HORTRAPEZOID && (p == 4 || p == 6)) continue;
|
||||
if (wmtype == VERTRAPEZOID && (p == 3 || p == 7)) continue;
|
||||
param = param_mat + p;
|
||||
curr_param = *param;
|
||||
best_param = curr_param;
|
||||
|
@ -209,6 +217,8 @@ double refine_integerized_param(WarpedMotionParams *wm,
|
|||
static INLINE RansacFunc get_ransac_type(TransformationType type) {
|
||||
switch (type) {
|
||||
case HOMOGRAPHY: return ransac_homography;
|
||||
case HORTRAPEZOID: return ransac_hortrapezoid;
|
||||
case VERTRAPEZOID: return ransac_vertrapezoid;
|
||||
case AFFINE: return ransac_affine;
|
||||
case ROTZOOM: return ransac_rotzoom;
|
||||
case TRANSLATION: return ransac_translation;
|
||||
|
|
|
@ -23,6 +23,8 @@ const double gm_advantage_thresh[TRANS_TYPES] = {
|
|||
0.85, // Translation
|
||||
0.75, // Rot zoom
|
||||
0.65, // Affine
|
||||
0.65, // Hor Trapezoid
|
||||
0.65, // Ver Trapezoid
|
||||
0.50, // Homography
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#define MAX_DEGENERATE_ITER 10
|
||||
#define MINPTS_MULTIPLIER 5
|
||||
|
||||
#define INLIER_THRESHOLD 1.0
|
||||
#define MIN_TRIALS 20
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ransac
|
||||
typedef int (*IsDegenerateFunc)(double *p);
|
||||
|
@ -76,6 +79,42 @@ static void project_points_double_affine(double *mat, double *points,
|
|||
}
|
||||
}
|
||||
|
||||
static void project_points_double_hortrapezoid(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
const int stride_proj) {
|
||||
int i;
|
||||
double x, y, Z, Z_inv;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
Z_inv = mat[7] * y + 1;
|
||||
assert(fabs(Z_inv) > 0.000001);
|
||||
Z = 1. / Z_inv;
|
||||
*(proj++) = (mat[2] * x + mat[3] * y + mat[0]) * Z;
|
||||
*(proj++) = (mat[5] * y + mat[1]) * Z;
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void project_points_double_vertrapezoid(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
const int stride_proj) {
|
||||
int i;
|
||||
double x, y, Z, Z_inv;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
Z_inv = mat[6] * x + 1;
|
||||
assert(fabs(Z_inv) > 0.000001);
|
||||
Z = 1. / Z_inv;
|
||||
*(proj++) = (mat[2] * x + mat[0]) * Z;
|
||||
*(proj++) = (mat[4] * x + mat[5] * y + mat[1]) * Z;
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void project_points_double_homography(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
|
@ -121,10 +160,8 @@ static int ransac(int *matched_points, int npoints, int *number_of_inliers,
|
|||
IsDegenerateFunc is_degenerate,
|
||||
FindTransformationFunc find_transformation,
|
||||
ProjectPointsDoubleFunc projectpoints) {
|
||||
static const double inlier_threshold = 1.0;
|
||||
static const double PROBABILITY_REQUIRED = 0.9;
|
||||
static const double EPS = 1e-12;
|
||||
static const int MIN_TRIALS = 20;
|
||||
|
||||
int N = 10000, trial_count = 0;
|
||||
int i;
|
||||
|
@ -223,7 +260,7 @@ static int ransac(int *matched_points, int npoints, int *number_of_inliers,
|
|||
double dy = image1_coord[i * 2 + 1] - corners2[i * 2 + 1];
|
||||
double distance = sqrt(dx * dx + dy * dy);
|
||||
|
||||
inlier_mask[i] = distance < inlier_threshold;
|
||||
inlier_mask[i] = distance < INLIER_THRESHOLD;
|
||||
if (inlier_mask[i]) {
|
||||
inlier_set1[num_inliers * 2] = corners1[i * 2];
|
||||
inlier_set1[num_inliers * 2 + 1] = corners1[i * 2 + 1];
|
||||
|
@ -332,3 +369,19 @@ int ransac_homography(int *matched_points, int npoints, int *number_of_inliers,
|
|||
best_params, 4, is_degenerate_homography, find_homography,
|
||||
project_points_double_homography);
|
||||
}
|
||||
|
||||
int ransac_hortrapezoid(int *matched_points, int npoints,
|
||||
int *number_of_inliers, int *best_inlier_mask,
|
||||
double *best_params) {
|
||||
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
|
||||
best_params, 4, is_degenerate_homography, find_hortrapezoid,
|
||||
project_points_double_hortrapezoid);
|
||||
}
|
||||
|
||||
int ransac_vertrapezoid(int *matched_points, int npoints,
|
||||
int *number_of_inliers, int *best_inlier_mask,
|
||||
double *best_params) {
|
||||
return ransac(matched_points, npoints, number_of_inliers, best_inlier_mask,
|
||||
best_params, 4, is_degenerate_homography, find_vertrapezoid,
|
||||
project_points_double_vertrapezoid);
|
||||
}
|
||||
|
|
|
@ -24,11 +24,17 @@ typedef int (*RansacFunc)(int *matched_points, int npoints,
|
|||
double *best_params);
|
||||
|
||||
/* Each of these functions fits a motion model from a set of
|
||||
corresponding points in 2 frames using RANSAC.*/
|
||||
corresponding points in 2 frames using RANSAC. */
|
||||
int ransac_homography(int *matched_points, int npoints, int *number_of_inliers,
|
||||
int *best_inlier_indices, double *best_params);
|
||||
int ransac_affine(int *matched_points, int npoints, int *number_of_inliers,
|
||||
int *best_inlier_indices, double *best_params);
|
||||
int ransac_hortrapezoid(int *matched_points, int npoints,
|
||||
int *number_of_inliers, int *best_inlier_indices,
|
||||
double *best_params);
|
||||
int ransac_vertrapezoid(int *matched_points, int npoints,
|
||||
int *number_of_inliers, int *best_inlier_indices,
|
||||
double *best_params);
|
||||
int ransac_rotzoom(int *matched_points, int npoints, int *number_of_inliers,
|
||||
int *best_inlier_indices, double *best_params);
|
||||
int ransac_translation(int *matched_points, int npoints, int *number_of_inliers,
|
||||
|
|
|
@ -4911,10 +4911,13 @@ static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
|
|||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
|
||||
static const int gm_amortization_blks[TRANS_TYPES] = { 4, 6, 8, 10, 12 };
|
||||
static const int gm_amortization_blks[TRANS_TYPES] = {
|
||||
4, 6, 8, 10, 10, 10, 12
|
||||
};
|
||||
static const int gm_params_cost[TRANS_TYPES] = {
|
||||
GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
|
||||
GM_AFFINE_BITS, GM_HOMOGRAPHY_BITS,
|
||||
GM_AFFINE_BITS, GM_HORTRAPEZOID_BITS, GM_VERTRAPEZOID_BITS,
|
||||
GM_HOMOGRAPHY_BITS,
|
||||
};
|
||||
const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
|
||||
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
|
||||
|
|
Загрузка…
Ссылка в новой задаче