Over Macho Grande

Friday, October 14, 2011

Python and libpuzzle

As much as I've dogged on Python in the past (significant whitespace, really?), I've got to admit that it's
got some cool features too.

For example, I'm playing with libpuzzle (a library for visually comparing images).  It has a command line utility and a C and PHP API.  Unfortunately, the CLI utility doesn't allow one to dump the raw comparison vector, and it's a PITA to write C just to play with a library.

Python's native "ctypes" to the rescue!

from ctypes import *

class PuzzleCvec(Structure):
 _fields_ = [("sizeof_vec", c_size_t),
             ("vec", c_char_p)]
class PuzzleCompressedCvec(Structure):     
    _fields_ = [("sizeof_compressed_vec", c_size_t),
       ("vec", c_char_p)]
class PuzzleContext(Structure):
 _fields_ = [("puzzle_max_width", c_uint),
             ("puzzle_max_height", c_uint),
             ("puzzle_lambdas", c_uint),
             ("puzzle_p_ratio", c_double),
             ("puzzle_noise_cutoff", c_double),
             ("puzzle_contrast_barrier_for_cropping", c_double),
             ("puzzle_max_cropping_ratio", c_double),
             ("puzzle_enable_autocrop", c_int),
             ("magic", c_ulong)]
libpuzzle = CDLL('libpuzzle.so')
context = PuzzleContext()
cvec = PuzzleCvec()
ccvec = PuzzleCompressedCvec()

libpuzzle.puzzle_init_cvec(byref(context), byref(cvec))
libpuzzle.puzzle_init_compressed_cvec(byref(context), byref(ccvec))

fileName = '/home/corey/page1.png'
retval = libpuzzle.puzzle_fill_cvec_from_file(byref(context), byref(cvec), fileName)
print "fill_cvec returned %d" % (retval)
print "Vector length: %d" % (cvec.sizeof_vec)

retval = libpuzzle.puzzle_compress_cvec(byref(context), byref(ccvec), byref(cvec))
print "compress_cvec returned %d" % (retval)
print "Compressed vector length: %d" % (ccvec.sizeof_compressed_vec)

print "Vector: %s" % (ccvec.vec)

# Clean up
libpuzzle.puzzle_free_cvec(byref(context), byref(cvec))

Now I can play around with the library from Python, for example dumping the vector for each image into SQLite.