2 * Image Library -- Comparitions of image signatures
4 * (c) 2006 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
14 #include "images/math.h"
15 #include "images/images.h"
16 #include "images/signature.h"
21 image_signatures_dist_1(struct image_signature *sig1, struct image_signature *sig2)
23 DBG("image_signatures_dist_1()");
27 struct image_region *reg1 = sig1->reg;
28 struct image_region *reg2 = sig2->reg;
29 uns mf[IMAGE_REG_MAX][IMAGE_REG_MAX], mh[IMAGE_REG_MAX][IMAGE_REG_MAX];
30 uns lf[IMAGE_REG_MAX * 2], lh[IMAGE_REG_MAX * 2];
31 uns df = sig1->df + sig2->df, dh = sig1->dh + sig2->dh;
33 /* Compute distance matrix */
34 for (uns i = 0; i < cnt1; i++)
35 for (uns j = 0; j < cnt2; j++)
38 for (uns k = 0; k < IMAGE_REG_F; k++)
40 int dif = reg1[i].f[k] - reg2[j].f[k];
45 for (uns k = 0; k < IMAGE_REG_H; k++)
47 int dif = reg1[i].h[k] - reg2[j].h[k];
54 for (uns i = 0; i < cnt1; i++)
56 uns f = mf[i][0], h = mh[i][0];
57 for (uns j = 1; j < cnt2; j++)
62 lf[i] = (df * 0x10000) / (df + fast_sqrt_u32(f));
63 lh[i] = (dh * 0x10000) / (dh + fast_sqrt_u32(h));
64 lfs += lf[i] * (6 * reg1[i].wa + 2 * reg1[i].wb);
65 lhs += lh[i] * reg1[i].wa;
67 for (uns i = 0; i < cnt2; i++)
69 uns f = mf[0][i], h = mh[0][i];
70 for (uns j = 1; j < cnt1; j++)
75 lf[i + cnt1] = (df * 0x10000) / (df + fast_sqrt_u32(f));
76 lh[i + cnt1] = (dh * 0x10000) / (dh + fast_sqrt_u32(h));
77 lfs += lf[i] * (6 * reg2[i].wa + 2 * reg2[i].wb);
78 lhs += lh[i] * reg2[i].wa;
81 uns measure = lfs * 6 + lhs * 2 * 8;
84 /* Display similarity vectors */
85 byte buf[2 * IMAGE_REG_MAX * 16 + 3], *b = buf;
86 for (uns i = 0; i < cnt1 + cnt2; i++)
91 *b++ = '~', *b++ = ' ';
92 b += sprintf(b, "%.4f", (double)lf[i] / 0x10000);
97 for (uns i = 0; i < cnt1 + cnt2; i++)
102 *b++ = '~', *b++ = ' ';
103 b += sprintf(b, "%.4f", (double)lh[i] / 0x10000);
107 DBG("Lfm=%.4f", lfs / (double)(1 << (3 + 8 + 16)));
108 DBG("Lhm=%.4f", lhs / (double)(1 << (8 + 16)));
109 DBG("measure=%.4f", measure / (double)(1 << (3 + 3 + 8 + 16)));
112 return (1 << (3 + 3 + 8 + 16)) - measure;
115 #define ASORT_PREFIX(x) image_signatures_dist_2_##x
116 #define ASORT_KEY_TYPE uns
117 #define ASORT_ELT(i) items[i]
118 #define ASORT_EXTRA_ARGS , uns *items
119 #include "lib/arraysort.h"
122 image_signatures_dist_2(struct image_signature *sig1, struct image_signature *sig2)
124 DBG("image_signatures_dist_2()");
126 uns dist[IMAGE_REG_MAX * IMAGE_REG_MAX], p[IMAGE_REG_MAX], q[IMAGE_REG_MAX];
127 uns n, i, j, k, l, s, d;
128 struct image_region *reg1, *reg2;
130 /* Compute distance matrix */
132 /* ... for non-textured images */
133 if (!((sig1->flags | sig2->flags) & IMAGE_SIG_TEXTURED))
134 for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
135 for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
138 isqr((int)reg1->h[0] - (int)reg2->h[0]) +
139 isqr((int)reg1->h[1] - (int)reg2->h[1]) +
140 isqr((int)reg1->h[2] - (int)reg2->h[2]);
142 isqr((int)reg1->f[0] - (int)reg2->f[0]) +
143 isqr((int)reg1->f[1] - (int)reg2->f[1]) +
144 isqr((int)reg1->f[2] - (int)reg2->f[2]) +
145 isqr((int)reg1->f[3] - (int)reg2->f[3]) +
146 isqr((int)reg1->f[4] - (int)reg2->f[4]) +
147 isqr((int)reg1->f[5] - (int)reg2->f[5]);
154 DBG("[%u][%u] ... ds=%u dt=%u", i, j, ds, dt);
155 dist[n++] = (dt << 8) + i + (j << 4) ;
157 /* ... for textured images (ignore shape properties) */
159 for (j = 0, reg2 = sig2->reg; j < sig2->len; j++, reg2++)
160 for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
163 isqr((int)reg1->f[0] - (int)reg2->f[0]) +
164 isqr((int)reg1->f[1] - (int)reg2->f[1]) +
165 isqr((int)reg1->f[2] - (int)reg2->f[2]) +
166 isqr((int)reg1->f[3] - (int)reg2->f[3]) +
167 isqr((int)reg1->f[4] - (int)reg2->f[4]) +
168 isqr((int)reg1->f[5] - (int)reg2->f[5]);
169 dist[n++] = (dt << 12) + i + (j << 4) ;
172 /* One or both signatures have no regions */
174 return 1 << IMAGE_SIG_DIST_SCALE;
176 /* Get percentages */
177 for (i = 0, reg1 = sig1->reg; i < sig1->len; i++, reg1++)
179 for (i = 0, reg2 = sig2->reg; i < sig2->len; i++, reg2++)
182 /* Sort entries in distance matrix */
183 image_signatures_dist_2_sort(n, dist);
185 /* Compute significance matrix and resulting distance */
187 for (k = 0, l = 128; l; k++)
190 j = (dist[k] >> 4) & 15;
206 DBG("s[%u][%u]=%u d=%u", i, j, s, d);
213 image_signatures_dist(struct image_signature *sig1, struct image_signature *sig2)
215 switch (image_sig_compare_method)
218 return image_signatures_dist_1(sig1, sig2);
220 return image_signatures_dist_2(sig1, sig2);
222 die("Invalid image signatures compare method.");