tinyimg 1.0.0
Lightweight image manipulation library for Cloudflare Workers
Loading...
Searching...
No Matches
detect.h File Reference

Face detection through a local binary pattern cascade. More...

#include <stddef.h>
#include <stdint.h>
#include "tinyimg/image.h"
#include "tinyimg/memory.h"
#include "tinyimg/tinyimg.h"

Go to the source code of this file.

Classes

struct  TinyFaceBox
 One detection, in the coordinates of the image that was searched. More...
struct  TinyDetectOpts
 How hard to look. More...

Macros

#define TINYIMG_MAX_RAW_DETECTIONS   2048u
 Raw detections collected before grouping.
#define TINYIMG_DETECT_LONG_SIDE   1200u
 Longest side tiny_image_detect_faces searches at.
#define TINYIMG_DETECT_SIZE_DIVISOR   10u
 What tiny_image_detect_faces divides the height by for its min_size.

Functions

void tiny_detect_opts (TinyDetectOpts *opts)
 Fills an options structure in with the defaults.
int tiny_image_detect_faces (const TinyImage *image, TinyFaceBox *boxes, uint32_t capacity, uint32_t *count)
 Finds faces, at a resolution and a minimum size chosen from the image.
int tiny_image_detect_faces_ex (const TinyImage *image, const TinyDetectOpts *opts, TinyFaceBox *boxes, uint32_t capacity, uint32_t *count)
 Finds faces exactly as asked, on the pixels given.
int tiny_cascade_check (const char *blob_id)
 Reports whether a cascade blob parses, without searching anything.
uint32_t tiny_face_box_sizeof (void)
 Size of a TinyFaceBox, for a host reading an array of them out of linear memory.
uint32_t tiny_detect_opts_sizeof (void)
 Size of a TinyDetectOpts, for the same reason.

Detailed Description

Face detection through a local binary pattern cascade.

Author
Gregory Mitchell (me@gm.nosp@m.itch.nosp@m.215.x.nosp@m.yz)
Version
1.0.0
Date
2026-09-03

Macro Definition Documentation

◆ TINYIMG_DETECT_LONG_SIDE

#define TINYIMG_DETECT_LONG_SIDE   1200u

Longest side tiny_image_detect_faces searches at.

A cascade needs the face to fill its window and to still carry texture, so reducing further than this loses faces rather than time. Measured: the frontal cascade finds smile.jpg at 800 pixels and at 1200 and misses it at 480, and 800 also produced a false positive on dog.jpg that 1200 does not.

◆ TINYIMG_DETECT_SIZE_DIVISOR

#define TINYIMG_DETECT_SIZE_DIVISOR   10u

What tiny_image_detect_faces divides the height by for its min_size.

A tenth of the height is about the smallest face worth finding in a photograph, and it is also where the cost lands somewhere a request can afford. An eighth misses the face in smile.jpg, which is 7% of its height; a sixteenth finds two boxes on it and triples the time.

◆ TINYIMG_MAX_RAW_DETECTIONS

#define TINYIMG_MAX_RAW_DETECTIONS   2048u

Raw detections collected before grouping.

A search over a large image at a small min_size can fire more than this, and the ones past it are dropped rather than growing a buffer inside a hot loop. Reaching it means the search was far wider than the picture needs.

Function Documentation

◆ tiny_cascade_check()

int tiny_cascade_check ( const char * blob_id)

Reports whether a cascade blob parses, without searching anything.

What a host calls after loading one, so a bad blob is a startup failure rather than a detection that silently finds nothing.

Parameters
blob_idThe id it was loaded under, or NULL for the first cascade.
Returns
int TINYIMG_OK, TINYIMG_ERR_BLOB_MISSING or TINYIMG_ERR_CORRUPT.

◆ tiny_detect_opts()

void tiny_detect_opts ( TinyDetectOpts * opts)

Fills an options structure in with the defaults.

min_size comes back zero, which means search every scale. That is the honest default for the explicit entry point and it is expensive; see tiny_image_detect_faces for the one that picks a size from the image.

Parameters
optsReceives them.

◆ tiny_detect_opts_sizeof()

uint32_t tiny_detect_opts_sizeof ( void )

Size of a TinyDetectOpts, for the same reason.

Returns
uint32_t sizeof(TinyDetectOpts).

◆ tiny_face_box_sizeof()

uint32_t tiny_face_box_sizeof ( void )

Size of a TinyFaceBox, for a host reading an array of them out of linear memory.

Returns
uint32_t sizeof(TinyFaceBox).

◆ tiny_image_detect_faces()

int tiny_image_detect_faces ( const TinyImage * image,
TinyFaceBox * boxes,
uint32_t capacity,
uint32_t * count )

Finds faces, at a resolution and a minimum size chosen from the image.

The entry point to reach for. It searches a copy reduced to TINYIMG_DETECT_LONG_SIDE with min_size set to a TINYIMG_DETECT_SIZE_DIVISOR of the height, then scales the boxes back, which on a 1470x1920 photograph is 155 ms against 993 for searching every scale of the original. The boxes are in the coordinates of the image passed in.

Both constants are measurements rather than preferences, and the reason the reduction is moderate is that a cascade stops working before it stops being slow: statistics elsewhere in this library run happily on a one-eighth decode, and face detection does not, because a face at 7% of an image's height is 17 pixels there against a 45 pixel window.

A cascade is scale-dependent, not just size-dependent, so no single setting finds every face. A frontal face is found at a moderate reduction and lost at full resolution; a side-facing one can be the other way round. This default is tuned for the first, which is the common case, and searching at another scale is what tiny_image_detect_faces_ex is for. The behavior is the cascade's rather than this implementation's: the same inputs through OpenCV's own detector move the same way.

Parameters
imageThe image to search. Any channel count; the luminance is taken.
boxesReceives the detections, ordered by neighbors descending.
capacityHow many boxes holds.
countReceives how many were written, which is capped at capacity.
Returns
int TINYIMG_OK, TINYIMG_ERR_BLOB_MISSING when no cascade is resident, TINYIMG_ERR_CORRUPT for a cascade that does not parse, or TINYIMG_ERR_MEMORY.

◆ tiny_image_detect_faces_ex()

int tiny_image_detect_faces_ex ( const TinyImage * image,
const TinyDetectOpts * opts,
TinyFaceBox * boxes,
uint32_t capacity,
uint32_t * count )

Finds faces exactly as asked, on the pixels given.

No reduction and no chosen size: it searches the image passed in with the options passed in, and the boxes are in that image's coordinates. Use it to search a region, to search at a size the default would skip, or to search a reduction the caller made itself.

Runs every blob of kind TINYIMG_BLOB_CASCADE and groups the results together, so loading a frontal and a profile cascade finds both kinds of face and a face that fires both is one box rather than two. Nothing here names a cascade; a caller loads the ones they have.

Parameters
imageThe image to search.
optsHow hard to look, or NULL for tiny_detect_opts' defaults, which search every scale.
boxesReceives the detections, ordered by neighbors descending.
capacityHow many boxes holds.
countReceives how many were written.
Returns
int TINYIMG_OK or a negative TinyImageError.