]> mj.ucw.cz Git - libucw.git/blob - images/sig-cmp-gen.h
imagesim explain: fastbuf replaced with callback
[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   /* Compute distance matrix */
54   n = 0;
55   MSG("Distance matrix:");
56   LINE;
57   /* ... for non-textured images */
58   if (!((sig1->flags | sig2->flags) & IMAGE_SIG_TEXTURED))
59     for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
60       for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
61         {
62           uns ds =
63             isqr((int)reg1->h[0] - (int)reg2->h[0]) +
64             isqr((int)reg1->h[1] - (int)reg2->h[1]) +
65             isqr((int)reg1->h[2] - (int)reg2->h[2]);
66           uns dt =
67             isqr((int)reg1->f[0] - (int)reg2->f[0]) +
68             isqr((int)reg1->f[1] - (int)reg2->f[1]) +
69             isqr((int)reg1->f[2] - (int)reg2->f[2]) +
70             isqr((int)reg1->f[3] - (int)reg2->f[3]) +
71             isqr((int)reg1->f[4] - (int)reg2->f[4]) +
72             isqr((int)reg1->f[5] - (int)reg2->f[5]);
73           if (ds < 1000)
74             dt *= 8;
75           else if (ds < 10000)
76             dt *= 12;
77           else
78             dt *= 16;
79           dist[n++] = (dt << 8) + i + (j << 4);
80           DBG("[%u, %u] dt=%u ds=%u", i, j, dt, ds);
81           MSG("[%u, %u] dt=%u ds=%u", i, j, dt, ds);
82           LINE;
83         }
84   /* ... for textured images (ignore shape properties) */
85   else
86     for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
87       for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
88         {
89           uns dt =
90             isqr((int)reg1->f[0] - (int)reg2->f[0]) +
91             isqr((int)reg1->f[1] - (int)reg2->f[1]) +
92             isqr((int)reg1->f[2] - (int)reg2->f[2]) +
93             isqr((int)reg1->f[3] - (int)reg2->f[3]) +
94             isqr((int)reg1->f[4] - (int)reg2->f[4]) +
95             isqr((int)reg1->f[5] - (int)reg2->f[5]);
96           dist[n++] = (dt << 12) + i + (j << 4);
97           DBG("[%u, %u] dt=%u", i, j, dt);
98           MSG("[%u, %u] dt=%u", i, j, dt);
99           LINE;
100         }
101
102   /* One or both signatures have no regions */
103   if (!n)
104     return 0xffffffff;
105
106   /* Get percentages */
107   for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
108     p[i] = reg1->wb;
109   for (i = 0, reg2 = sig2->reg; i < sig2->len; i++, reg2++)
110     q[i] = reg2->wb;
111
112   /* Sort entries in distance matrix */
113   image_signatures_dist_2_sort(n, dist);
114
115   /* Compute significance matrix and resulting distance */
116   uns sum = 0;
117   MSG("Significance matrix:");
118   LINE;
119   for (k = 0, l = 128; l; k++)
120     {
121       i = dist[k] & 15;
122       j = (dist[k] >> 4) & 15;
123       d = dist[k] >> 8;
124       if (p[i] <= q[j])
125         {
126           s = p[i];
127           q[j] -= p[i];
128           p[i] = 0;
129         }
130       else
131         {
132           s = q[j];
133           p[i] -= q[j];
134           q[j] = 0;
135         }
136       l -= s;
137       sum += s * d;
138       DBG("[%u, %u] s=%u d=%u", i, j, s, d);
139       MSG("[%u, %u] s=%u d=%u", i, j, s, d);
140       LINE;
141     }
142
143   return sum;
144 }
145
146 #undef EXPLAIN
147 #undef MSG
148 #undef LINE