Slight modification of the image_sim_fill_data, that creates the
similarity signature. When the image size is not a multiple of 32, all
cells had size w/32, so the last w%32 pixels were just ignored, and more
importantly it was not symmetric at all when the signature was built
from the other side, which is annoying for my comparison algorithm. So I
changed the cell size (x_inc) from a constant one to
"round(w_left/n_left)", in order to spread the spare pixels (eg to split
42 pixels into 4 cells, it results in 11,10,11,10 instead of
10,10,10,10). With an image of size w with w%32=16, my
rotation-invariant algorithm results in a similarity of
0.951000 with the original version, and 0.999968 with this modification
(apparently lossless jpeg rotation is not perfectly lossless).
Signed-off-by: Klaus Ethgen <Klaus@Ethgen.de>
+gint mround(gdouble x)
+{
+ gint ipart = x;
+ gdouble fpart = x-ipart;
+ return (fpart < 0.5 ? ipart : ipart+1);
+}
+
void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf)
{
gint w, h;
void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf)
{
gint w, h;
gint j;
gint x_inc, y_inc, xy_inc;
gint xs, ys;
gint j;
gint x_inc, y_inc, xy_inc;
gint xs, ys;
gboolean x_small = FALSE; /* if less than 32 w or h, set TRUE */
gboolean y_small = FALSE;
gboolean x_small = FALSE; /* if less than 32 w or h, set TRUE */
gboolean y_small = FALSE;
if (!sd || !pixbuf) return;
w = gdk_pixbuf_get_width(pixbuf);
if (!sd || !pixbuf) return;
w = gdk_pixbuf_get_width(pixbuf);
p_step = has_alpha ? 4 : 3;
x_inc = w / 32;
y_inc = h / 32;
p_step = has_alpha ? 4 : 3;
x_inc = w / 32;
y_inc = h / 32;
+ w_left = w;
+ h_left = h;
- xy_inc = x_inc * y_inc;
-
for (ys = 0; ys < 32; ys++)
{
if (y_small) j = (gdouble)h / 32 * ys;
for (ys = 0; ys < 32; ys++)
{
if (y_small) j = (gdouble)h / 32 * ys;
+ else y_inc = mround((gdouble)h_left/(32-ys));
for (xs = 0; xs < 32; xs++)
{
gint x, y;
for (xs = 0; xs < 32; xs++)
{
gint x, y;
guchar *xpos;
if (x_small) i = (gdouble)w / 32 * xs;
guchar *xpos;
if (x_small) i = (gdouble)w / 32 * xs;
+ else x_inc = mround((gdouble)w_left/(32-xs));
+ xy_inc = x_inc * y_inc;
r = g = b = 0;
xpos = pix + (i * p_step);
r = g = b = 0;
xpos = pix + (i * p_step);
sd->avg_b[t] = b;
i += x_inc;
sd->avg_b[t] = b;
i += x_inc;