Digest hashes¶
mHash, BMH, Radial, ColorHash and ColorMoments, returned as a ph_digest_t.
| Types | |
|---|---|
ph_ |
What a digest's bytes mean, and therefore how two of them may be compared. |
ph_ |
A flat structure representing a hash digest. |
| Constants | |
|---|---|
PH_ |
|
PH_ |
Units of a PH_DIGEST_KIND_VECTOR16 feature: 1/128 of a channel level. |
| Functions | |
|---|---|
ph_ |
Computes Block Mean Hash (BMH). Returns a block_size * block_size-bit digest (256 bits / 32 bytes at the default block_size 16; see ph_context_set_block_params()). See BMH — Block Mean Hash. On an error out_digest is left untouched. |
ph_ |
Computes the color moments hash. Returns an 18-byte digest. |
ph_ |
Computes the color histogram hash. Returns a 108-byte digest. |
ph_ |
Computes the Marr-Hildreth hash. Returns a 72-byte (576-bit) digest. |
ph_ |
Computes the Radial variance hash. Returns a 40-byte digest. |
Types¶
ph_digest_kind_t¶
What a digest's bytes mean, and therefore how two of them may be compared.
Not every digest is a bit vector. Comparing quantized DCT coefficients by Hamming distance, or a histogram by L2, returns a plausible number that means nothing. This tag exists so that such a call fails instead: it is never used to pick a metric for you, only to refuse the wrong one. It survives storage: ph_digest_to_hex() writes it into the text and ph_digest_from_hex() restores it, so two digests read back from a database are protected exactly as two freshly computed ones are.
PH_DIGEST_KIND_VECTOR16 is PH_DIGEST_KIND_VECTOR with two bytes per feature and a sign, which ColorMoments needs because the third moment is a direction, not a size. The two are separate tags rather than one because they are not the same bytes: comparing a 16-bit vector as if it were a byte vector reads each feature's high and low halves as two independent features, and returns a plausible number that means nothing.
PH_DIGEST_KIND_UNSPECIFIED is what a hand-filled struct contains, since it is zero. Every comparison function accepts it — an FFI binding that fills in data and size and nothing else is accepted by every comparison, and gets no protection.
| Name | Value | Description |
|---|---|---|
PH_ |
0 |
Not stated. Accepted by every comparison. |
PH_ |
1 |
A bit vector. Hamming distance, similarity. BMH, mHash. |
PH_ |
2 |
Quantized transform coefficients. Radial. |
PH_ |
3 |
Real-valued features, one unsigned byte each. No algorithm here produces it: it tags a feature vector the caller builds, compared with ph_l2_distance(). |
PH_ |
4 |
Bin counts. Histogram intersection. ColorHash. |
PH_ |
5 |
Real-valued features, signed 16-bit. ColorMoments. |
PH_ |
PH_ |
Not a kind – see "Enum width". |
ph_digest_t¶
A flat structure representing a hash digest.
Note
This structure is FFI-safe and can be allocated on the stack. It does not own any heap memory.
| Type | Field | Description |
|---|---|---|
uint8_t |
data[PH_DIGEST_MAX_BYTES] |
The raw hash bytes. |
uint8_t |
size |
Number of valid bytes in 'data'. |
uint8_t |
kind |
A ph_digest_kind_t. 0 when not stated. |
uint8_t |
reserved[6] |
Zero. Room for future fields; makes the size a multiple of 8. Not alignment: every field is a byte, so _Alignof(ph_digest_t) is 1. |
Constants¶
PH_DIGEST_MAX_BYTES¶
Maximum size in bytes for any digest supported by the library (128 bytes = 1024 bits).
The widest digest the library produces is the Marr-Hildreth hash at 576 bits (72 bytes); the rest is headroom for the color histogram's bin count, reserved so that the size stays fixed for the whole 2.x series. ph_digest_t is passed and stored by value, so it costs 136 bytes wherever one lives.
PH_VECTOR16_SCALE¶
Units of a PH_DIGEST_KIND_VECTOR16 feature: 1/128 of a channel level.
A PH_DIGEST_KIND_VECTOR16 digest holds signed 16-bit big-endian fixed-point numbers, two bytes per feature, most significant byte first. Divide by this to get the value back. A caller that only compares digests never needs it — ph_l2_distance() decodes them — but a caller that wants the moments themselves does.
Functions¶
ph_compute_bmh()¶
Computes Block Mean Hash (BMH). Returns a block_size * block_size-bit digest (256 bits / 32 bytes at the default block_size 16; see ph_context_set_block_params()). See BMH — Block Mean Hash. On an error out_digest is left untouched.
Returns PH_SUCCESS, PH_ERR_INVALID_ARGUMENT for a NULL argument, PH_ERR_EMPTY_IMAGE if no image is loaded, or PH_ERR_ALLOCATION_FAILED.
ph_compute_color_moments_hash()¶
Computes the color moments hash. Returns an 18-byte digest.
The mean, the standard deviation and the cube root of the third central moment of each of the R, G and B channels, after Stricker & Orengo (1995): nine signed 16-bit big-endian numbers in units of 1/PH_VECTOR16_SCALE of a channel level. Compare with ph_l2_distance(), not with the bit metrics. See ColorMoments — Color Moments.
Requires a color image: the loaded image must have at least 3 channels. On a single-channel image — one loaded while ph_context_set_load_grayscale() was enabled, or handed to ph_load_from_pixels() with channels = 1 — this returns PH_ERR_REQUIRES_COLOR and leaves out_digest untouched.
Returns PH_SUCCESS, PH_ERR_INVALID_ARGUMENT for a NULL argument, PH_ERR_EMPTY_IMAGE if no image is loaded, or PH_ERR_REQUIRES_COLOR.
ph_compute_color_hash()¶
Computes the color histogram hash. Returns a 108-byte digest.
The image's pixels are counted into 108 bins of the opponent color space — red against green, blue against yellow, light against dark, at 6 x 6 x 3 — and each bin is scaled against the largest. This is a color histogram with histogram intersection, after Swain & Ballard (1991), implemented from secondary descriptions of the paper; no conformance to the paper itself is claimed. The quantization is this library's own, chosen by measurement.
Compare with ph_histogram_intersection(), not with the bit or vector metrics.
Requires a color image: the loaded image must have at least 3 channels. On a single-channel image — one loaded while ph_context_set_load_grayscale() was enabled, or handed to ph_load_from_pixels() with channels = 1 — this returns PH_ERR_REQUIRES_COLOR and leaves out_digest untouched.
Note
Like every color histogram it discards spatial layout entirely: an image and a shuffling of its pixels hash identically. Use it alongside a structural hash, not instead of one. See ColorHash — Color Histogram.
Returns PH_SUCCESS, PH_ERR_INVALID_ARGUMENT for a NULL argument, PH_ERR_EMPTY_IMAGE if no image is loaded, or PH_ERR_REQUIRES_COLOR.
ph_compute_mhash()¶
Computes the Marr-Hildreth hash. Returns a 72-byte (576-bit) digest.
The image is blurred at sigma 1, normalized to size x size (512 by default) and histogram-equalized over 256 levels; the Laplacian-of-Gaussian operator of Marr and Hildreth (alpha = 2, level = 1 by default; see ph_context_set_mhash_params()) is correlated with it; the response is summed into a 31x31 grid of blocks (16x16 pixels at the default size); and nine bits are emitted per 3x3 window of that grid at stride 4, each thresholded against its window's mean. That construction is pHash's ph_mh_imagehash(), which is its primary source — there is no paper for it. Values are close in spirit but not identical to pHash's; see Algorithm provenance, section 5.
The digest is a bit vector: compare it with ph_hamming_distance_digest() or ph_similarity_digest(). See mHash — Marr–Hildreth Hash.
On an error out_digest is left untouched.
Returns PH_SUCCESS, PH_ERR_INVALID_ARGUMENT for a NULL argument, PH_ERR_EMPTY_IMAGE if no image is loaded, or PH_ERR_ALLOCATION_FAILED.
ph_compute_radial_hash()¶
Computes the Radial variance hash. Returns a 40-byte digest.
The variance of the pixels along each of radial_projections lines through the image center (default 180, one per degree), reduced by a 1-D DCT to its first 40 coefficients, which are quantized into the digest. Uses the context gamma, and nothing else does.
An image with no angular structure – blank, or with nearly the same variance along every line, as a radially symmetric one has – gets an all-zero digest and PH_SUCCESS; ph_radial_similarity() answers any comparison with it by PH_ERR_NO_STRUCTURE.
Warning
Compare these digests with ph_radial_similarity(), not with ph_hamming_distance_digest(), ph_l2_distance() or ph_similarity_digest(): the bytes are quantized coefficients, not bits or a point in space. The digest tolerates a rotation of a few degrees and an exact half turn, not an arbitrary one. See Radial — Radial Variance Hash.
On an error out_digest is left untouched.
Returns PH_SUCCESS (the all-zero digest included), PH_ERR_INVALID_ARGUMENT for a NULL argument, PH_ERR_EMPTY_IMAGE if no image is loaded, or PH_ERR_ALLOCATION_FAILED.