PostQuantMaxSteps 10
PostQuantThreshold 1
-BorderSize 0.2
-BorderBonus 50
+BorderSize 0.4
+BorderBonus -50
+
+InertiaScale 2 0.5 0.05
TexturedThreshold 0.32
CompareMethod integrated
# Array of multiplicative constants in feature vectors distance computation
-# (L, u, v, LH, HL, HH, H0, H1, H2). Each one must be in range 0..15.
-CompareFeaturesWeights 1 2 2 1 1 1 1 1 1
+# (L, u, v, LH, HL, HH, I1, I2, I3, X, Y). Each one must be in range 0..15, default is 4.
+CompareFeaturesWeights 4 8 8 4 4 4 4 4 4 4 4
}
uns image_sig_postquant_threshold;
double image_sig_border_size;
int image_sig_border_bonus;
+double image_sig_inertia_scale[3];
double image_sig_textured_threshold;
int image_sig_compare_method;
-uns image_sig_cmp_features_weights[IMAGE_VEC_F + IMAGE_REG_H];
+uns image_sig_cmp_features_weights[IMAGE_REG_F + IMAGE_REG_H];
static struct cf_section sig_config = {
CF_ITEMS{
CF_UNS("PostQuantThreshold", &image_sig_postquant_threshold),
CF_DOUBLE("BorderSize", &image_sig_border_size),
CF_INT("BorderBonus", &image_sig_border_bonus),
+ CF_DOUBLE_ARY("InertiaScale", image_sig_inertia_scale, 3),
CF_DOUBLE("TexturedThreshold", &image_sig_textured_threshold),
CF_LOOKUP("CompareMethod", &image_sig_compare_method, ((byte *[]){"integrated", "fuzzy", "average", NULL})),
- CF_UNS_ARY("CompareFeaturesWeights", image_sig_cmp_features_weights, IMAGE_VEC_F + IMAGE_REG_H),
+ CF_UNS_ARY("CompareFeaturesWeights", image_sig_cmp_features_weights, IMAGE_REG_F + IMAGE_REG_H),
CF_END
}
};
for (uns j = 0; j < cnt2; j++)
{
uns d = 0;
- for (uns k = 0; k < IMAGE_REG_F; k++)
+ for (uns k = 0; k < IMAGE_VEC_F; k++)
{
int dif = reg1[i].f[k] - reg2[j].f[k];
- d += dif * dif;
+ d += image_sig_cmp_features_weights[k] * dif * dif;
}
mf[i][j] = d;
d = 0;
for (uns k = 0; k < IMAGE_REG_H; k++)
{
int dif = reg1[i].h[k] - reg2[j].h[k];
- d += dif * dif;
+ d += image_sig_cmp_features_weights[k + IMAGE_VEC_F] * dif * dif;
}
mh[i][j] = d;
}
#undef LOCAL_DEBUG
#include "sherlock/sherlock.h"
-#include "lib/math.h"
#include "lib/fastbuf.h"
#include "lib/conf.h"
+#include "lib/math.h"
#include "images/math.h"
#include "images/images.h"
#include "images/color.h"
data->valid = 1;
}
-static double image_sig_inertia_scale[3] = { 3, 1, 0.3 };
-
void
image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
{
sig->reg[i].f[5] = r->a[5];
/* Compute coordinates centroid and region weight */
- u64 x_avg = 0, y_avg = 0, w_sum = 0;
+ u64 x_sum = 0, y_sum = 0, w_sum = 0;
for (struct image_sig_block *b = r->blocks; b; b = b->next)
{
- x_avg += b->x;
- y_avg += b->y;
+ x_sum += b->x;
+ y_sum += b->y;
uns d = b->x;
d = MIN(d, b->y);
d = MIN(d, data->cols - b->x - 1);
}
w_total += w_sum;
r->w_sum = w_sum;
- x_avg /= r->count;
- y_avg /= r->count;
- DBG(" centroid=(%u %u)", (uns)x_avg, (uns)y_avg);
+ uns x_avg = x_sum / r->count;
+ uns y_avg = y_sum / r->count;
+ DBG(" centroid=(%u %u)", x_avg, y_avg);
/* Compute normalized inertia */
u64 sum1 = 0, sum2 = 0, sum3 = 0;
for (struct image_sig_block *b = r->blocks; b; b = b->next)
{
uns inc2 = isqr(x_avg - b->x) + isqr(y_avg - b->y);
- uns inc1 = sqrt(inc2);
+ uns inc1 = fast_sqrt_u32(inc2);
sum1 += inc1;
sum2 += inc2;
sum3 += inc1 * inc2;
}
- sig->reg[i].h[0] = CLAMP(image_sig_inertia_scale[0] * sum1 * ((3 * M_PI * M_PI) / 2) * pow(r->count, -1.5), 0, 65535);
- sig->reg[i].h[1] = CLAMP(image_sig_inertia_scale[1] * sum2 * ((4 * M_PI * M_PI * M_PI) / 2) / ((u64)r->count * r->count), 0, 65535);
- sig->reg[i].h[2] = CLAMP(image_sig_inertia_scale[2] * sum3 * ((5 * M_PI * M_PI * M_PI * M_PI) / 2) * pow(r->count, -2.5), 0, 65535);
-
+ sig->reg[i].h[0] = CLAMP(image_sig_inertia_scale[0] * sum1 * ((3 * M_PI * M_PI) / 2) * pow(r->count, -1.5), 0, 255);
+ sig->reg[i].h[1] = CLAMP(image_sig_inertia_scale[1] * sum2 * ((4 * M_PI * M_PI * M_PI) / 2) / ((u64)r->count * r->count), 0, 255);
+ sig->reg[i].h[2] = CLAMP(image_sig_inertia_scale[2] * sum3 * ((5 * M_PI * M_PI * M_PI * M_PI) / 2) * pow(r->count, -2.5), 0, 255);
+ sig->reg[i].h[3] = (uns)x_avg * 127 / data->cols;
+ sig->reg[i].h[4] = (uns)y_avg * 127 / data->rows;
}
/* Compute average differences */
{
uns d = 0;
for (uns k = 0; k < IMAGE_REG_F; k++)
- d += isqr(sig->reg[i].f[k] - sig->reg[j].f[k]);
- df += sqrt(d);
+ d += image_sig_cmp_features_weights[k] * isqr(sig->reg[i].f[k] - sig->reg[j].f[k]);
+ df += fast_sqrt_u32(d);
d = 0;
for (uns k = 0; k < IMAGE_REG_H; k++)
- d += isqr(sig->reg[i].h[k] - sig->reg[j].h[k]);
- dh += sqrt(d);
+ d += image_sig_cmp_features_weights[k + IMAGE_REG_F] * isqr(sig->reg[i].h[k] - sig->reg[j].h[k]);
+ dh += fast_sqrt_u32(d);
cnt++;
}
- sig->df = CLAMP(df / cnt, 1, 255);
- sig->dh = CLAMP(dh / cnt, 1, 65535);
+ sig->df = CLAMP(df / cnt, 1, 0xffff);
+ sig->dh = CLAMP(dh / cnt, 1, 0xffff);
}
DBG("Average regions difs: df=%u dh=%u", sig->df, sig->dh);
extern uns image_sig_postquant_min_steps, image_sig_postquant_max_steps, image_sig_postquant_threshold;
extern double image_sig_border_size;
extern int image_sig_border_bonus;
+extern double image_sig_inertia_scale[];
extern double image_sig_textured_threshold;
extern int image_sig_compare_method;
extern uns image_sig_cmp_features_weights[];
#define IMAGE_VEC_F 6
#define IMAGE_REG_F IMAGE_VEC_F
-#define IMAGE_REG_H 3
+#define IMAGE_REG_H 5
#define IMAGE_REG_MAX 16
/* K-dimensional feature vector (6 bytes) */
/* Fetures for image regions (16 bytes) */
struct image_region {
- byte f[IMAGE_VEC_F]; /* texture features */
- u16 h[IMAGE_REG_H]; /* shape features */
- u16 wa; /* normalized area percentage */
- u16 wb; /* normalized weight */
+ byte f[IMAGE_VEC_F]; /* texture features - L, u, v, LH, HL, HH */
+ byte h[IMAGE_REG_H]; /* shape/pos features - I1, I2, I3, X, Y */
+ byte wa; /* normalized area percentage */
+ byte wb; /* normalized weight */
+ u16 reserved;
} PACKED;
#define IMAGE_SIG_TEXTURED 0x1
struct image_signature {
byte len; /* Number of regions */
byte flags; /* IMAGE_SIG_xxx */
- byte df; /* Average f dist */
- u16 dh; /* Average h dist */
- struct image_vector vec; /* Combination of all regions... simple signature */
+ u16 df; /* Average weighted f dist */
+ u16 dh; /* Average weighted h dist */
+ struct image_vector vec; /* Average features of all regions... simple signature */
struct image_region reg[IMAGE_REG_MAX];/* Feature vector for every region */
} PACKED;
static inline uns
image_signature_size(uns len)
{
- return 5 + sizeof(struct image_vector) + len * sizeof(struct image_region);
+ return OFFSETOF(struct image_signature, reg) + len * sizeof(struct image_region);
}
/* sig-dump.c */