From: Cyril Roussillon <> Date: Fri, 13 May 2016 12:43:41 +0000 (+0100) Subject: Slightly better similarity samples X-Git-Tag: v1.3~24^2~1 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=49df4e25014e2ce1792ad0c0fd01f7d781b0e491 Slightly better similarity samples 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 --- diff --git a/src/similar.c b/src/similar.c index 7f51f6cc..316dfa14 100644 --- a/src/similar.c +++ b/src/similar.c @@ -169,6 +169,13 @@ void image_sim_alternate_processing(ImageSimilarityData *sd) #endif } +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; @@ -182,10 +189,10 @@ void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf) gint j; gint x_inc, y_inc, xy_inc; gint xs, ys; + gint w_left, h_left; 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); @@ -197,6 +204,8 @@ void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf) p_step = has_alpha ? 4 : 3; x_inc = w / 32; y_inc = h / 32; + w_left = w; + h_left = h; if (x_inc < 1) { @@ -209,16 +218,16 @@ void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf) y_small = TRUE; } - xy_inc = x_inc * y_inc; - j = 0; + h_left = h; for (ys = 0; ys < 32; ys++) { if (y_small) j = (gdouble)h / 32 * ys; - + else y_inc = mround((gdouble)h_left/(32-ys)); i = 0; + w_left = w; for (xs = 0; xs < 32; xs++) { gint x, y; @@ -227,7 +236,8 @@ void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf) 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); @@ -253,9 +263,11 @@ void image_sim_fill_data(ImageSimilarityData *sd, GdkPixbuf *pixbuf) sd->avg_b[t] = b; i += x_inc; + w_left -= x_inc; } j += y_inc; + h_left -= y_inc; } sd->filled = TRUE;