debian::manpages::libpuzzle(3)
NAME
puzzle_init_cvec, puzzle_init_dvec, puzzle_fill_dvec_from_file,
puzzle_fill_cvec_from_file, puzzle_fill_cvec_from_dvec,
puzzle_free_cvec, puzzle_free_dvec, puzzle_init_compressed_cvec,
puzzle_free_compressed_cvec, puzzle_compress_cvec,
puzzle_uncompress_cvec, puzzle_vector_normalized_distance - compute
comparable signatures of bitmap images
SYNOPSIS
#include <puzzle.h> int puzzle_init_context(PuzzleContext *context); int puzzle_free_context(PuzzleContext *context); int puzzle_init_cvec(PuzzleContext *context, PuzzleCvec *cvec); int puzzle_init_dvec(PuzzleContext *context, PuzzleDvec *cvec); void puzzle_fill_dvec_from_file(PuzzleContext *context, PuzzleDvec *dvec, const char *file); void puzzle_fill_cvec_from_file(PuzzleContext *context, PuzzleCvec *cvec, const char *file); void puzzle_fill_cvec_from_dvec(PuzzleContext *context, PuzzleCvec *cvec, const PuzzleDvec *dvec); void puzzle_free_cvec(PuzzleContext *context, PuzzleCvec *cvec); void puzzle_free_dvec(PuzzleContext *context, PuzzleDvec *cvec); void puzzle_init_compressed_cvec(PuzzleContext *context, PuzzleCompressedCvec *compressed_cvec); void puzzle_free_compressed_cvec(PuzzleContext *context, PuzzleCompressedCvec *compressed_cvec); int puzzle_compress_cvec(PuzzleContext *context, PuzzleCompressedCvec *compressed_cvec, const PuzzleCvec *cvec); int puzzle_uncompress_cvec(PuzzleContext *context, PuzzleCompressedCvec *compressed_cvec, PuzzleCvec *const cvec); double puzzle_vector_normalized_distance(PuzzleContext *context, const PuzzleCvec *cvec1, const PuzzleCvec *cvec2, const int fix_for_texts);
DESCRIPTION
The Puzzle library computes a signature out of a bitmap picture.
Signatures are comparable and similar pictures have similar signatures.
After a picture has been loaded and uncompressed, featureless parts of
the image are skipped (autocrop), unless that step has been explicitely
disabled, see puzzle_set(3)
LIBPUZZLE CONTEXT
Every public function requires a PuzzleContext object, that stores
every required tunables.
- Any application using libpuzzle should initialize a PuzzleContext object with ppuuzzzzllee__iinniitt__ccoonntteexxtt(()) and free it after use with ppuuzzzzllee__ffrreeee__ccoonntteexxtt(())
- PuzzleContext context;
- puzzle_init_context(&context);
[...]
puzzle_free_context(&context);
DVEC AND CVEC VECTORS
The next step is to divide the cropped image into a grid and to compute
the average intensity of soft-edged pixels in every block. The result
is a PuzzleDvec object.
PuzzleDvec objects should be initialized before use, with ppuuzzzzllee__iinniitt__ddvveecc(()) and freed after use with ppuuzzzzllee__ffrreeee__ddvveecc(()).
The PuzzleDvec structure has two important fields: vec is the pointer
to the first element of the array containing the average intensities,
and sizeof_compressed_vec is the number of elements.
PuzzleDvec objects are not comparable, so what you usually want is to
transform these objects into PuzzleCvec objects.
A PuzzleCvec object is a vector with relationships between adjacent
blocks from a PuzzleDvec object.
The ppuuzzzzllee__ffiillll__ccvveecc__ffrroomm__ddvveecc(()) fills a PuzzleCvec object from a
PuzzleDvec object.
But just like the other structure, PuzzleCvec objects must be initialized and freed with ppuuzzzzllee__iinniitt__ccvveecc(()) and ppuuzzzzllee__ffrreeee__ccvveecc(()).
PuzzleCvec objects have a vector whoose first element is in the vec field, and the number of elements is in the sizeof_vec field.
LOADING PICTURES
PuzzleDvec and PuzzleCvec objects can be computed from a bitmap picture file, with ppuuzzzzllee__ffiillll__ddvveecc__ffrroomm__ffiillee(()) and ppuuzzzzllee__ffiillll__ccvveecc__ffrroomm__ffiillee(()).
GIF, PNG and JPEG files formats are currently supported and
automatically recognized.
- Here's a simple example that creates a PuzzleCvec objects out of a
file.
- PuzzleContext context;
PuzzleCvec cvec; - puzzle_init_context(&context);
puzzle_init_cvec(&context, &cvec);
puzzle_fill_cvec_from_file(&context, &cvec, "test-picture.jpg");
[...]
puzzle_free_cvec(&context, &cvec);
puzzle_free_context(&context);
COMPARING VECTORS
In order to check whether two pictures are similar, you need to compare their PuzzleCvec signatures, using ppuuzzzzllee__vveeccttoorr__nnoorrmmaalliizzeedd__ddiissttaannccee(()).
That function returns a distance, between 0.0 and 1.0. The lesser, the
nearer.
Tests on common pictures show that a normalized distance of 0.6 (also
defined as PUZZLE_CVEC_SIMILARITY_THRESHOLD) means that both pictures
are visually similar.
If that threshold is not right for your set of pictures, you can
experiment with PUZZLE_CVEC_SIMILARITY_HIGH_THRESHOLD,
PUZZLE_CVEC_SIMILARITY_LOW_THRESHOLD and
PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD or with your own value.
If the fix_for_texts of ppuuzzzzllee__vveeccttoorr__nnoorrmmaalliizzeedd__ddiissttaannccee(()) is 1, a fix
is applied to the computation in order to deal with bitmap pictures
that contain text. That fix is recommended, as it allows using the same
threshold for that kind of picture as for generic pictures.
- If fix_for_texts is 0, that special way of computing the normalized
distance is disabled.
- PuzzleContext context;
PuzzleCvec cvec1, cvec2;
double d; - puzzle_init_context(&context);
puzzle_init_cvec(&context, &cvec1);
puzzle_init_cvec(&context, &cvec2);
puzzle_fill_cvec_from_file(&context, &cvec1, "test-picture-1.jpg");
puzzle_fill_cvec_from_file(&context, &cvec2, "test-picture-2.jpg");
d = puzzle_vector_normalized_distance(&context, &cvec1, &cvec2, 1);
if (d < PUZZLE_CVEC_SIMILARITY_THRESHOLD) {puts("Pictures are similar"); - }
puzzle_free_cvec(&context, &cvec2);
puzzle_free_cvec(&context, &cvec1);
puzzle_free_context(&context);
CVEC COMPRESSION
In order to reduce storage needs, PuzzleCvec objects can be compressed
to 1/3 of their original size.
PuzzleCompressedCvec structures hold the compressed data. Before and
after use, these structures have to be passed to
ppuuzzzzllee__iinniitt__ccoommpprreesssseedd__ccvveecc(()) and ppuuzzzzllee__ffrreeee__ccoommpprreesssseedd__ccvveecc(()).
ppuuzzzzllee__ccoommpprreessss__ccvveecc(()) compresses a PuzzleCvec object into a
PuzzleCompressedCvec object.
- And ppuuzzzzllee__uunnccoommpprreessss__ccvveecc(()) uncompresses a PuzzleCompressedCvec object
into a PuzzleCvec object.
- PuzzleContext context;
PuzzleCvec cvec;
PuzzleCompressedCvec c_cvec;
[...]
puzzle_init_compressed_cvec(&context, &c_cvec);
puzzle_compress_cvec(&context, &c_cvec, &cvec);
[...]
puzzle_free_compressed_cvec(&context, &c_cvec); - The PuzzleCompressedCvec structure has two important fields: vec that
is a pointer to the first element of the compressed data, and
sizeof_compressed_vec that contains the number of elements.
RETURN VALUE
Functions return 0 on success, and -1 if something went wrong.
AUTHORS
Frank DENIS libpuzzle at pureftpd dot org
ACKNOWLEDGMENTS
Xerox Research Center H. CHI WONG Marschall BERN David GOLDBERG Sameh
SCHAFIK
SEE ALSO
puzzle_set(3), puzzle-diff(8)
POD ERRORS
Hey! The above document had some coding errors, which are explained
below:
- Around line 57:
- You forgot a '=back' before '=head1'
- Around line 95:
- You forgot a '=back' before '=head1'
- Around line 129:
- You forgot a '=back' before '=head1'
- Around line 154:
- You forgot a '=back' before '=head1'