Image Analysis and Image Utilities

Campfire includes local image functions for comparing generated media, checking reusable reference assets, validating character continuity, making masks, making contact sheets, cropping images, splitting image grids, and inspecting or removing image metadata. These functions run inside the Campfire app and return structured results to CodeBot.

The goal is to keep numeric image work inside tools. CodeBot should receive compact scores, verdicts, face boxes, and metadata instead of raw crops or large embedding arrays whenever possible.

Function Groups

Native Image Metrics

  • calculateImagePHash computes a 64-bit perceptual hash for one image.
  • compareImagePHashes compares two pHashes with Hamming distance.
  • analyzeImageHygiene reports simple blur, brightness, clipping, and pHash metrics.
  • compareImageVectors compares numeric vectors with cosine similarity.
  • validateDuplicateImagePack checks a set of images for likely duplicates and basic hygiene issues.

Use these for duplicate detection, quick reference quality checks, and non-ML image hygiene.

Image Cropping and Metadata

These functions operate on local workspace image files:

  • createImageContactSheet creates a labeled PNG grid from multiple local images. Use it to compare generated variants, summarize a reference set, or make it easier to choose between several images.
  • cropImage writes one or more workspace-safe PNG crops from an image. Each crop uses pixel coordinates from the top-left of the source image and writes a separate target file.
  • splitImageGrid splits a grid or contact sheet into clean PNG crops without using AI. It detects separator seams, removes separator bands, and writes cells left-to-right, then top-to-bottom. Optional row, column, and minimum-cell-size hints can guide detection.
  • extractImageMetadata reads image metadata without modifying the image and returns structured details to CodeBot. It includes basic file and pixel data, PNG text chunks, JPEG APP/comment metadata, and likely AI-generation metadata such as prompt, workflow, seed, model, sampler, and steps when present.
  • stripImageMetadata re-encodes image pixels to remove shareable metadata before sending, posting, or handing the image to another workflow. It can update supported images in place or write a cleaned copy.

Use createImageContactSheet when you want one compact overview image instead of opening many individual files. CodeBot can label each image, choose a grid size, and save the contact sheet as a workspace PNG.

Use extractImageMetadata when you need to inspect how an image was made, especially for ComfyUI/Flux images that store the prompt graph and workflow in PNG text chunks. Use stripImageMetadata before sharing generated images outside the workspace when prompt, workflow, seed, GPS, EXIF, or provenance metadata should not travel with the file.

Metadata stripping removes ordinary file metadata exposed through the encoded image container. It does not guarantee removal of invisible pixel-level watermarks or visual signatures embedded in the image itself.

Vision Face Detection

  • detectFacesInImage uses Apple's Vision framework to detect face bounding boxes in a local image. The result includes normalized Vision coordinates and pixel coordinates measured from the top-left of the image. Face detection is separate from identity matching: it finds faces, but it does not decide whether two faces are the same character.

  • pickFaceRegion uses the same Vision face detection path, then shows the user a numbered visual picker with an annotated image and face thumbnails. It returns the selected region geometry, the picker preview path, and the full list of detected regions. Use it when CodeBot needs the user to choose which face should be repaired, cropped, masked, or used in a later image workflow. pickFaceRegion does not edit the image. It is a questioning tool that turns detected face boxes into a human-confirmed selection.

The model can use detectFacesInImage to get a list of all faces in an image. It can use pickFaceRegion to show the user a visual representation of all faces found and allow the user to identify a specific one for further processing, such as cropping, repair, or inpainting.

Image Masks and In-Painting Inputs

These functions create black/white PNG masks that can be passed to image-editing or in-painting workflows:

  • createFaceImageMask creates a mask for a detected or selected face. It can use a faceId, a bounding box from pickFaceRegion, or the largest detected face. Supported variants include fullFace, eyes, mouth, and skinOnly.
  • createImageMask creates a local CLIP-ranked clothing-like mask for a source image. The current candidate generator is aimed at person/portrait targets such as shirt, top, jacket, coat, dress, pants, or skirt. It can rank candidates against a text target or a reference image.

Use createFaceImageMask after the user has selected a face to repair. Use createImageMask when the edit target is a clothing-like region and a generated mask is acceptable as a starting point. For arbitrary objects or exact manual masks, use the Image Workbench mask painter instead.

Local Models

ArcFace Identity Matching

ArcFace functions compare face identity. They are useful when the question is whether a generated scene still contains the intended character.

Available tools:

  • calculateFaceEmbedding returns the primary face embedding for one image.
  • calculateFaceEmbeddingsForImage detects all faces in one image and returns one embedding per face.
  • compareFaceEmbeddings compares two embedding sets.
  • findMatchingFaces compares scene face embeddings against reference face embeddings.
  • findMatchingFacesInImages detects faces and computes embeddings from image files directly, then compares scene faces against one or more named reference sets.
  • compareFaceIdentity compares the primary faces in two images.

The model should prefer findMatchingFacesInImages when starting from files. It keeps detection, cropping, embedding, and comparison inside one tool call so raw embedding arrays do not need to pass through the chat.

Reference Sets

When checking multiple characters in one scene, pass named reference sets:

{
  "sceneImagePath": "scene.png",
  "referenceSets": [
    {
      "characterId": "shell",
      "images": ["shell-master-identity-sheet-v1.png"]
    },
    {
      "characterId": "lina",
      "images": ["lina-master-identity-sheet-v1.png"]
    }
  ]
}

Each reference set should contain anchors for one character. A multi-panel face detail or expression sheet is usually a stronger reference than a single scene crop.

The tool computes pairwise cosine scores, per-scene-face aggregates, centroid similarity, and a verdict such as same_character, review, or different_character.

CLIP Image Similarity

CLIP functions compare whole-image semantic or style similarity. They are useful when the question is whether two images feel visually related, have similar composition, or remain close to a reference style.

Available tools:

  • calculateClipImageEmbedding returns a normalized image embedding for one image.
  • compareClipImages computes CLIP image embeddings for two images and returns cosine similarity.

Do not use CLIP image similarity as face identity proof. Use ArcFace for character identity and CLIP for broader visual/reference similarity.

Bundled ONNX Models

Campfire bundles the local ONNX models under:

Resources/Models

The app links them as individual app resources, not as a model folder.

Local file Purpose Source / version note
arcface.onnx ArcFace/InsightFace-compatible face identity embeddings arcface_w600k_r50.onnx, bundled locally as arcface.onnx. The current file hash matches public Hugging Face copies of that model.
clip-image.onnx CLIP ViT-B/32 image embeddings Downloaded from Hugging Face Qdrant/clip-ViT-B-32-vision as model.onnx, then bundled as clip-image.onnx.

Both model-backed function groups use ONNX Runtime through Campfire's native Toffee code. Campfire owns image loading, preprocessing, inference setup, vector normalization, scoring, and JSON reporting.

Preprocessing Assumptions

ArcFace:

  • Detect faces with Vision.
  • Crop around each face box.
  • Resize face crops to 112x112.
  • Normalize RGB channels to the ArcFace input range.
  • Run ONNX inference.
  • L2-normalize the output embedding before comparison.

CLIP image embeddings:

  • Center-crop the source image to a square.
  • Resize to 224x224.
  • Normalize RGB channels with CLIP mean and standard deviation.
  • Run ONNX inference.
  • L2-normalize the output embedding before comparison.

Matching exact preprocessing to the model file matters. If the bundled model changes, update this page and the preprocessing code together.

When To Use Which Tool

Use pHash when you need near-duplicate detection.

Use image hygiene checks when you need a quick blur or exposure signal.

Use metadata extraction when you need the original prompt, workflow, seed, model, sampler, or ordinary EXIF/XMP-style information.

Use metadata stripping when an image is about to be shared, uploaded, or reused without carrying its prompt/workflow/provenance data.

Use contact sheets when you want to compare several generated images or reference images in one labeled overview.

Use cropping when CodeBot needs precise local sub-images, face crops, or derived reference images.

Use grid splitting when a contact sheet, generated grid, or comparison image needs to become separate workspace image files.

Use Vision face detection when you need face boxes or want the user to choose a face region.

Use mask creation when a later edit should change only a face, clothing-like region, or selected image area.

Use ArcFace when you need to decide whether a scene face matches a known character reference.

Use CLIP image similarity when you need broader visual, semantic, or style similarity between images.