]> mj.ucw.cz Git - libucw.git/blob - images/sig-cmp-gen.h
configurable border bonuses for signature computation
[libucw.git] / images / sig-cmp-gen.h
1 #ifndef EXPLAIN
2
3 #define MSG(x...) do{}while(0)
4 #define LINE do{}while(0)
5
6 static uns
7 image_signatures_dist_2(struct image_signature *sig1, struct image_signature *sig2)
8
9 #else
10
11 #define MSG(x...) do{ line += sprintf(line, x); }while(0)
12 #define LINE do{ line = buf; msg(line, param); }while(0)
13
14 static void
15 explain_signature(struct image_signature *sig, void (*msg)(byte *text, void *param), void *param)
16 {
17   byte buf[1024], *line = buf;
18   MSG("signature: flags=0x%x df=%u dh=%u f=(%u", sig->flags, sig->df, sig->dh, sig->vec.f[0]);
19   for (uns i = 1; i < IMAGE_VEC_F; i++)
20     MSG(" %u", sig->vec.f[i]);
21   MSG(")");
22   LINE;
23   for (uns j = 0; j < sig->len; j++)
24     {
25       struct image_region *reg = sig->reg + j;
26       MSG("region %u: wa=%u wb=%u f=(%u", j, reg->wa, reg->wb, reg->f[0]);
27       for (uns i = 1; i < IMAGE_VEC_F; i++)
28         MSG(" %u", reg->f[i]);
29       MSG(") h=(%u", reg->h[0]);
30       for (uns i = 1; i < IMAGE_REG_H; i++)
31         MSG(" %u", reg->h[i]);
32       MSG(")");
33       LINE;
34     }
35 }
36
37 static uns
38 image_signatures_dist_2_explain(struct image_signature *sig1, struct image_signature *sig2, void (*msg)(byte *text, void *param), void *param)
39
40 #endif
41 {
42   DBG("image_signatures_dist_2()");
43
44   uns dist[IMAGE_REG_MAX * IMAGE_REG_MAX], p[IMAGE_REG_MAX], q[IMAGE_REG_MAX];
45   uns n, i, j, k, l, s, d;
46   struct image_region *reg1, *reg2;
47 #ifdef EXPLAIN
48   byte buf[1024], *line = buf;
49   explain_signature(sig1, msg, param);
50   explain_signature(sig2, msg, param);
51 #endif
52
53   /* FIXME: do not mux textured and non-textured images (should be split in clusters tree) */
54   if ((sig1->flags ^ sig2->flags) & IMAGE_SIG_TEXTURED)
55     {
56       MSG("Textured vs non-textured");
57       LINE;
58       return ~0U;
59     }
60   
61   /* Compute distance matrix */
62   n = 0;
63   MSG("Distance matrix:");
64   LINE;
65   /* ... for non-textured images */
66   if (!((sig1->flags | sig2->flags) & IMAGE_SIG_TEXTURED))
67     for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
68       for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
69         {
70           uns ds =
71             image_sig_cmp_features_weights[6] * isqr((int)reg1->h[0] - (int)reg2->h[0]) +
72             image_sig_cmp_features_weights[7] * isqr((int)reg1->h[1] - (int)reg2->h[1]) +
73             image_sig_cmp_features_weights[8] * isqr((int)reg1->h[2] - (int)reg2->h[2]);
74           uns dt =
75             image_sig_cmp_features_weights[0] * isqr((int)reg1->f[0] - (int)reg2->f[0]) +
76             image_sig_cmp_features_weights[1] * isqr((int)reg1->f[1] - (int)reg2->f[1]) +
77             image_sig_cmp_features_weights[2] * isqr((int)reg1->f[2] - (int)reg2->f[2]) +
78             image_sig_cmp_features_weights[3] * isqr((int)reg1->f[3] - (int)reg2->f[3]) +
79             image_sig_cmp_features_weights[4] * isqr((int)reg1->f[4] - (int)reg2->f[4]) +
80             image_sig_cmp_features_weights[5] * isqr((int)reg1->f[5] - (int)reg2->f[5]);
81           if (ds < 1000)
82             dt *= 8;
83           else if (ds < 10000)
84             dt *= 12;
85           else
86             dt *= 16;
87           dist[n++] = (dt << 8) + i + (j << 4);
88           DBG("[%u, %u] dt=%u ds=%u", i, j, dt, ds);
89           MSG("[%u, %u] dt=%u ds=%u", i, j, dt, ds);
90           LINE;
91         }
92   /* ... for textured images (ignore shape properties) */
93   else
94     for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
95       for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
96         {
97           uns dt =
98             image_sig_cmp_features_weights[0] * isqr((int)reg1->f[0] - (int)reg2->f[0]) +
99             image_sig_cmp_features_weights[1] * isqr((int)reg1->f[1] - (int)reg2->f[1]) +
100             image_sig_cmp_features_weights[2] * isqr((int)reg1->f[2] - (int)reg2->f[2]) +
101             image_sig_cmp_features_weights[3] * isqr((int)reg1->f[3] - (int)reg2->f[3]) +
102             image_sig_cmp_features_weights[4] * isqr((int)reg1->f[4] - (int)reg2->f[4]) +
103             image_sig_cmp_features_weights[5] * isqr((int)reg1->f[5] - (int)reg2->f[5]);
104           dist[n++] = (dt << 12) + i + (j << 4);
105           DBG("[%u, %u] dt=%u", i, j, dt);
106           MSG("[%u, %u] dt=%u", i, j, dt);
107           LINE;
108         }
109
110   /* One or both signatures have no regions */
111   if (!n)
112     return 0xffffffff;
113
114   /* Get percentages */
115   for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
116     p[i] = reg1->wb;
117   for (i = 0, reg2 = sig2->reg; i < sig2->len; i++, reg2++)
118     q[i] = reg2->wb;
119
120   /* Sort entries in distance matrix */
121   image_signatures_dist_2_sort(n, dist);
122
123   /* Compute significance matrix and resulting distance */
124   uns sum = 0;
125   MSG("Significance matrix:");
126   LINE;
127   for (k = 0, l = 128; l; k++)
128     {
129       i = dist[k] & 15;
130       j = (dist[k] >> 4) & 15;
131       d = dist[k] >> 8;
132       if (p[i] <= q[j])
133         {
134           s = p[i];
135           q[j] -= p[i];
136           p[i] = 0;
137         }
138       else
139         {
140           s = q[j];
141           p[i] -= q[j];
142           q[j] = 0;
143         }
144       l -= s;
145       sum += s * d;
146       DBG("[%u, %u] s=%u d=%u", i, j, s, d);
147       MSG("[%u, %u] s=%u d=%u", i, j, s, d);
148       LINE;
149     }
150
151   return sum;
152 }
153
154 #undef EXPLAIN
155 #undef MSG
156 #undef LINE