357r4bd / Image-Libpuzzle

Perl 5 XS wrapper around libpuzzle. Friendly user feedback welcomed!
http://search.cpan.org/~estrabd/Image-Libpuzzle
0 stars 1 forks source link

vector_normalized_distance varies depending on size of image #5

Open benkasminbullock opened 8 years ago

357r4bd commented 8 years ago

Thank you, @benkasminbullock.

Can you compare the same images using puzzle-diff? It should have been installed when you installed libpuzzle.

https://download.pureftpd.org/libpuzzle/doc/man8/puzzle-diff.8.html

357r4bd commented 8 years ago

@benkasminbullock, I have not attempted nor am I going to attempt to reproduce the results you got. What I am asking you to do is to use the "puzzle-diff" utility that comes with libpuzzle to see if it gives you the same numbers when comparing two files. You can also attach a tar.gz of the images you're comparing so that when I have some time, I can use puzzle-diff myself to see if it is libpuzzle or my module that is causing the unexpected variances you're seeing. Thank you!

357r4bd commented 8 years ago

I am going to keep this open. Worst case, I can have a test that compares module output with that of puzzle-diff (if installed).

@benkasminbullock will you please attach a tar.gz of the images you tested above, being sure to denote the original image.

Thank you.

benkasminbullock commented 8 years ago

You can get the images I referred to by running these scripts:

https://github.com/benkasminbullock/image-similar/blob/master/t/images/lenagercke/lenagercke.pl

https://github.com/benkasminbullock/image-similar/blob/master/t/images/chess/make-chessboards.pl

benkasminbullock commented 8 years ago

Further to that, the C program I mentioned in the bug report is here:

https://gist.github.com/benkasminbullock/42a6ac50470ed3bf2fe3

Sorry but I didn't carefully track changes to this.

The Makefile for that is as follows:

puzzletest: puzzletest.c
        $(CC) $(CFLAGS) -I /usr/local/include -o $@ puzzletest.c -L /usr/local/lib -lpuzzle -lgd
357r4bd commented 8 years ago

@benkasminbullock you deleted your comments so now I have nothing to go by. Based on reconstructin through email, you first wrote:

Using the following image:

http://xtremewalls.com/supermodels/Lena_Gercke/lena-gercke-001-01.jpg

I made various sized versions using Imager:

!/home/ben/software/install/bin/perl

use warnings; use strict; use utf8; use Imager; my $photo = 'lena-gercke-001-01.jpg'; my $img = Imager->new (); $img->read (file => $photo) or die $img->errstr (); for my $s (1..10) { my $size = 100*$s; my $out = $img->scale (xpixels => $size, ypixels => $size); $out->write (file => "lena-$size.png") or die $out->errstr (); }

Then I tried running Image::Libpuzzle against the original and smaller images:

!/home/ben/software/install/bin/perl

use warnings; use strict; use utf8; use FindBin '$Bin'; use Image::Libpuzzle; my $photo = 'lena-gercke-001-01.jpg'; my $p1 = Image::Libpuzzle->new; my $p2 = Image::Libpuzzle->new; my $sig1 = $p1->fill_cvec_from_file ($photo); my $s1 = $p1->signature_as_hex_string (); for my $s (1..10) { my $size =$s*100; my $photo2 = "$Bin/lena-$size.png"; my $sig2 = $p2->fill_cvec_from_file ($photo2); print "$size: ", $p1->vector_normalized_distance ($p2), "\n"; }

The outputs look like this:

100: 0.631680045723442 200: 0.616250444274758 300: 0.0698092831405639 400: 0.604140770698438 500: 0.623692779736408 600: 0.037084321574116 700: 0.60607610711603 800: 0.622808505614176 900: 0.0419672983694311 1000: 0.606291586628549

It's very striking that the numbers are completely different for numbers which are a factor of three and which are not. Did I make some kind of error here? I was also able to reproduce this using a C program with the original libpuzzle. I did some digging and found that the centres of the pixel squares seem to be wrong, which may be why this happens.

I tried this on a number of different images and was able to reproduce it with most of them. Since they were private photos I couldn't use them, so I tried with a Lenna image. I couldn't reproduce it with a Lenna image but the above I found on a google image search for "lena".

357r4bd commented 8 years ago

Then: Further to this, I tried making some simple graphics to see what would happen.

The following script prints simple chessboard graphics:

!/home/ben/software/install/bin/perl

Make simple images for use in testing libpuzzle

use warnings; use strict; use utf8; use FindBin '$Bin'; use Cairo; my $outdir = "$Bin/simg"; if (! -d $outdir) { die "No $outdir"; }

http://www.lemoda.net/cairo/cairo-tutorial/line.html

for my $s (1..20) { my $size = $s * 100; my $surface = Cairo::ImageSurface->create ('rgb24', $size, $size); my $cr = Cairo::Context->create ($surface); $cr->rectangle (0, 0, $size/2.0, $size); $cr->set_source_rgb (0, 0, 0); $cr->fill (); $cr->rectangle ($size/2.0, 0, $size, $size); $cr->set_source_rgb (1, 1, 1); $cr->fill (); $surface->write_to_png ("$outdir/bw-$size.png"); for my $x (0..7) { for my $y (0..7) { my $bw = $x + $y; if ($bw % 2 == 0) { $cr->set_source_rgb (1, 1, 1); } else { $cr->set_sourcergb (0, 0, 0); } $cr->rectangle ($x/8$size, $y/8$size,($x+1)/8$size, ($y+1)/8_$size,); $cr->fill (); } } $surface->write_to_png ("$outdir/chess-$size.png"); }

The chessboards can be visually inspected.

Using these I adapted the above script to compare the chessboards as follows:

!/home/ben/software/install/bin/perl

Test Libpuzzle on simple images

use warnings; use strict; use utf8; use FindBin '$Bin'; use Image::Libpuzzle;

my $oldsig; my @p; for my $s (1..20) { my $size = $s*100; my $photo2 = "$Bin/simg/chess-$size.png"; $p[$s] = Image::Libpuzzle->new (); $p[$s]->fill_cvec_from_file ($photo2); my $sig = $p[$s]->signature_as_hex_string (); if ($oldsig) { if ($sig ne $oldsig) { print "$size: ", $p[$s]->vector_normalized_distance ($p[$s-1]), "\n"; } } $oldsig = $sig; }

The output I get is as follows:

200: 0.297885626124051 300: 0.167714483784924 400: 0.0377426060986464 500: 0.159963154941154 600: 0.204693546582767 700: 0.141560905901128 800: 0.0436021508164603 900: 0.158667748953097 1000: 0.203797807460921 1100: 0.141560905901128 1200: 0.0436021508164603 1300: 0.158667748953097 1400: 0.197989962089072 1500: 0.138564982488454 1600: 0.0436021508164603 1700: 0.153354519552891 1800: 0.188068537824949 1900: 0.135492550984666 2000: 0.0436021508164603

Since it's comparing identical images each time, the variation indicates something amiss.

357r4bd commented 8 years ago

@benkasminbullock thanks for the C program, but where in the bug report do you mention it? So you compared the output of that program with the output of the Perl script using Image::LibPuzzle?

357r4bd commented 8 years ago

@benkasminbullock - can you read through this and tell me if this might be the cause of your issue?

https://rt.cpan.org/Ticket/Display.html?id=113716&results=610b7d631bbf5ca74ba6c2804c051fdb

Thank you

357r4bd commented 8 years ago

@benkasminbullock can you check this branch to see if it fixes your issue? I believe now the char representation of the signature will be more consistent from image to image.

https://github.com/estrabd/Image-Libpuzzle/tree/RT-113716-signature_as_char_string-possible-not-correct-at-all

357r4bd commented 8 years ago

@benkasminbullock after looking into this more, I have reported this upstream. I have reproduced it with puzzle-diff, so it's not an issue with my module. I would like to get this resolved, though.

https://github.com/jedisct1/libpuzzle/issues/16