VPX skin map improvement.
Use multiple clusters instead of one and decrease the distance thresholds. Add a define to switch between models. Default is set to existing (1 cluster) model. Change-Id: I802cd9bb565437ae8983ef39453939f5d5073bb1
This commit is contained in:
parent
aa3fb7e1b5
commit
d1e3d0467c
@ -36,6 +36,8 @@
|
||||
extern unsigned int cnt_pm;
|
||||
#endif
|
||||
|
||||
#define MODEL_MODE 0
|
||||
|
||||
extern const int vp8_ref_frame_order[MAX_MODES];
|
||||
extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
|
||||
|
||||
@ -45,18 +47,21 @@ extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
|
||||
// skin color classifier is defined.
|
||||
|
||||
// Fixed-point skin color model parameters.
|
||||
static const int skin_mean[2] = {7463, 9614}; // q6
|
||||
static const int skin_mean[5][2] =
|
||||
{{7463, 9614}, {6400, 10240}, {7040, 10240}, {8320, 9280}, {6800, 9614}};
|
||||
static const int skin_inv_cov[4] = {4107, 1663, 1663, 2157}; // q16
|
||||
static const int skin_threshold = 1570636; // q18
|
||||
static const int skin_threshold[2] = {1570636, 800000}; // q18
|
||||
|
||||
// Evaluates the Mahalanobis distance measure for the input CbCr values.
|
||||
static int evaluate_skin_color_difference(int cb, int cr)
|
||||
{
|
||||
static int evaluate_skin_color_difference(int cb, int cr, int idx) {
|
||||
const int cb_q6 = cb << 6;
|
||||
const int cr_q6 = cr << 6;
|
||||
const int cb_diff_q12 = (cb_q6 - skin_mean[0]) * (cb_q6 - skin_mean[0]);
|
||||
const int cbcr_diff_q12 = (cb_q6 - skin_mean[0]) * (cr_q6 - skin_mean[1]);
|
||||
const int cr_diff_q12 = (cr_q6 - skin_mean[1]) * (cr_q6 - skin_mean[1]);
|
||||
const int cb_diff_q12 =
|
||||
(cb_q6 - skin_mean[idx][0]) * (cb_q6 - skin_mean[idx][0]);
|
||||
const int cbcr_diff_q12 =
|
||||
(cb_q6 - skin_mean[idx][0]) * (cr_q6 - skin_mean[idx][1]);
|
||||
const int cr_diff_q12 =
|
||||
(cr_q6 - skin_mean[idx][1]) * (cr_q6 - skin_mean[idx][1]);
|
||||
const int cb_diff_q2 = (cb_diff_q12 + (1 << 9)) >> 10;
|
||||
const int cbcr_diff_q2 = (cbcr_diff_q12 + (1 << 9)) >> 10;
|
||||
const int cr_diff_q2 = (cr_diff_q12 + (1 << 9)) >> 10;
|
||||
@ -67,6 +72,34 @@ static int evaluate_skin_color_difference(int cb, int cr)
|
||||
return skin_diff;
|
||||
}
|
||||
|
||||
// Checks if the input yCbCr values corresponds to skin color.
|
||||
static int is_skin_color(int y, int cb, int cr)
|
||||
{
|
||||
if (y < 40 || y > 220)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MODEL_MODE == 0)
|
||||
{
|
||||
return (evaluate_skin_color_difference(cb, cr, 0) < skin_threshold[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < 5; i++)
|
||||
{
|
||||
if (evaluate_skin_color_difference(cb, cr, i) < skin_threshold[1])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int macroblock_corner_grad(unsigned char* signal, int stride,
|
||||
int offsetx, int offsety, int sgnx, int sgny)
|
||||
{
|
||||
@ -157,16 +190,6 @@ static int check_dot_artifact_candidate(VP8_COMP *cpi,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Checks if the input yCbCr values corresponds to skin color.
|
||||
static int is_skin_color(int y, int cb, int cr)
|
||||
{
|
||||
if (y < 40 || y > 220)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (evaluate_skin_color_difference(cb, cr) < skin_threshold);
|
||||
}
|
||||
|
||||
int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
|
||||
int_mv *bestmv, int_mv *ref_mv,
|
||||
int error_per_bit,
|
||||
|
@ -15,22 +15,28 @@
|
||||
#include "vp9/encoder/vp9_encoder.h"
|
||||
#include "vp9/encoder/vp9_skin_detection.h"
|
||||
|
||||
#define MODEL_MODE 0
|
||||
|
||||
// Fixed-point skin color model parameters.
|
||||
static const int skin_mean[2] = {7463, 9614}; // q6
|
||||
static const int skin_mean[5][2] = {
|
||||
{7463, 9614}, {6400, 10240}, {7040, 10240}, {8320, 9280}, {6800, 9614}};
|
||||
static const int skin_inv_cov[4] = {4107, 1663, 1663, 2157}; // q16
|
||||
static const int skin_threshold = 1570636; // q18
|
||||
static const int skin_threshold[2] = {1570636, 800000}; // q18
|
||||
|
||||
// Thresholds on luminance.
|
||||
static const int y_low = 20;
|
||||
static const int y_high = 220;
|
||||
|
||||
// Evaluates the Mahalanobis distance measure for the input CbCr values.
|
||||
static int evaluate_skin_color_difference(int cb, int cr) {
|
||||
static int evaluate_skin_color_difference(int cb, int cr, int idx) {
|
||||
const int cb_q6 = cb << 6;
|
||||
const int cr_q6 = cr << 6;
|
||||
const int cb_diff_q12 = (cb_q6 - skin_mean[0]) * (cb_q6 - skin_mean[0]);
|
||||
const int cbcr_diff_q12 = (cb_q6 - skin_mean[0]) * (cr_q6 - skin_mean[1]);
|
||||
const int cr_diff_q12 = (cr_q6 - skin_mean[1]) * (cr_q6 - skin_mean[1]);
|
||||
const int cb_diff_q12 =
|
||||
(cb_q6 - skin_mean[idx][0]) * (cb_q6 - skin_mean[idx][0]);
|
||||
const int cbcr_diff_q12 =
|
||||
(cb_q6 - skin_mean[idx][0]) * (cr_q6 - skin_mean[idx][1]);
|
||||
const int cr_diff_q12 =
|
||||
(cr_q6 - skin_mean[idx][1]) * (cr_q6 - skin_mean[idx][1]);
|
||||
const int cb_diff_q2 = (cb_diff_q12 + (1 << 9)) >> 10;
|
||||
const int cbcr_diff_q2 = (cbcr_diff_q12 + (1 << 9)) >> 10;
|
||||
const int cr_diff_q2 = (cr_diff_q12 + (1 << 9)) >> 10;
|
||||
@ -42,10 +48,21 @@ static int evaluate_skin_color_difference(int cb, int cr) {
|
||||
}
|
||||
|
||||
int vp9_skin_pixel(const uint8_t y, const uint8_t cb, const uint8_t cr) {
|
||||
if (y < y_low || y > y_high)
|
||||
if (y < y_low || y > y_high) {
|
||||
return 0;
|
||||
else
|
||||
return (evaluate_skin_color_difference(cb, cr) < skin_threshold);
|
||||
} else {
|
||||
if (MODEL_MODE == 0) {
|
||||
return (evaluate_skin_color_difference(cb, cr, 0) < skin_threshold[0]);
|
||||
} else {
|
||||
int i = 0;
|
||||
for (; i < 5; i++) {
|
||||
if (evaluate_skin_color_difference(cb, cr, i) < skin_threshold[1]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int vp9_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v,
|
||||
|
Loading…
x
Reference in New Issue
Block a user