IVALab Python Libraries
Collection of code for computer vision and robotics with specific API.
Classes | Functions | Variables
puzzle.pieces.BoW Namespace Reference

Classes

class  CfgBoW
 Configuration setting specifier for ColorBoWMatcher class. More...
 
class  ColorBoWMatcher
 

Functions

np.ndarray build_vocabulary (list[RGBMatrix] groups, int n_words=20, *int max_iter=100, float epsilon=1.0, int attempts=5, int random_seed=42)
 
list[Histogramencode_all (list[RGBMatrix] groups, np.ndarray centroids, *bool normalize=True)
 
Histogram encode_histogram (RGBMatrix group, np.ndarray centroids, *bool normalize=True)
 
float histogram_distance (Histogram h1, Histogram h2, DistanceMetric metric="chi2")
 

Variables

int best = top[1] if top[0]["distance"] < 1e-6 else top[0]
 
 DistanceMetric = Literal["chi2", "intersection", "hellinger", "l2", "cosine"]
 Literal type enumerating supported histogram distance metrics. More...
 
 groups
 
 hist_img = matcher.histogram_image(group_idx=0)
 
 Histogram = np.ndarray
 A (n_words,) float32 numpy ndarray representing an L1-normalized BoW histogram. More...
 
 labels
 
 matcher = ColorBoWMatcher(n_words=20, metric="chi2")
 
 metric
 
 n_groups
 
 n_pixels_per_group
 
 n_true_colors
 
dictionary nonzero = {f"w{i}": f"{v:.3f}" for i, v in enumerate(hist) if v > 0}
 
 query_group = groups[0]
 
 results = matcher.query(query_group)
 
 RGBMatrix = np.ndarray
 A (3, N) numpy ndarray of dtype uint8 or float32 holding RGB pixel data. More...
 
 rng = np.random.default_rng(42)
 
 top = matcher.query(query_group, top_k=2)
 
 vocab_img = matcher.vocabulary_as_image(swatch_size=50)
 

Function Documentation

◆ build_vocabulary()

np.ndarray puzzle.pieces.BoW.build_vocabulary ( list[RGBMatrix groups,
int   n_words = 20,
*int   max_iter = 100,
float   epsilon = 1.0,
int   attempts = 5,
int   random_seed = 42 
)
@brief Discover a color vocabulary by running K-Means on pooled RGB samples.

@details
All samples from every group are concatenated into a single point cloud and
passed to cv2.kmeans with K-Means++ initialization.  The resulting cluster
centroids form the "color words" of the vocabulary.  Running multiple
independent attempts and keeping the best result (lowest compactness) guards
against degenerate local minima.

@param groups      List of (3, N) RGB matrices whose pixels will be pooled.
@param n_words     Number of cluster centroids (vocabulary size). Default 20.
@param max_iter    Maximum number of K-Means iterations per attempt. Default 100.
@param epsilon     Convergence threshold in pixel-space Euclidean distance. Default 1.0.
@param attempts    Number of independent K-Means runs; the best is retained. Default 5.
@param random_seed NumPy random seed for reproducibility. Default 42.

@return (n_words, 3) float32 ndarray of centroid RGB values -- the color vocabulary.

◆ encode_all()

list[Histogram] puzzle.pieces.BoW.encode_all ( list[RGBMatrix groups,
np.ndarray  centroids,
*bool   normalize = True 
)
@brief Encode every group in the list into a BoW histogram.

@details
Convenience wrapper that calls encode_histogram() on each element of
@p groups using the shared @p centroids vocabulary.

@param groups     List of (3, N) RGB matrices.
@param centroids  (n_words, 3) float32 vocabulary from build_vocabulary().
@param normalize  If True (default), L1-normalize each histogram.

@return List of (n_words,) float32 histograms, one per group.

◆ encode_histogram()

Histogram puzzle.pieces.BoW.encode_histogram ( RGBMatrix  group,
np.ndarray  centroids,
*bool   normalize = True 
)
@brief Encode a single group as a Bag-of-Words histogram over the color vocabulary.

@details
Each pixel in the group is hard-assigned to its nearest centroid in RGB space
using squared Euclidean distance computed via broadcasting.  The resulting
assignment indices are tallied with numpy.bincount to produce a raw frequency
vector, which is optionally L1-normalized so that groups of different sizes
are directly comparable.

@param group      (3, N) RGB matrix for a single group.
@param centroids  (n_words, 3) float32 vocabulary returned by build_vocabulary().
@param normalize  If True (default), L1-normalize the histogram so it sums to 1.

@return (n_words,) float32 histogram over the color vocabulary.

◆ histogram_distance()

float puzzle.pieces.BoW.histogram_distance ( Histogram  h1,
Histogram  h2,
DistanceMetric   metric = "chi2" 
)
@brief Compute a scalar distance between two normalized BoW histograms.

@details
All returned values are distances (lower = more similar).  Supported metrics:
- **chi2**         : Chi-Squared distance; sensitive to differences in rare color words.
                     Formula: sum((h1-h2)^2 / (h1+h2+eps))
- **intersection** : 1 - Histogram Intersection similarity (via cv2.compareHist).
- **hellinger**    : Bhattacharyya / Hellinger distance (via cv2.compareHist);
                     robust to outliers and scale differences.
- **l2**           : Standard Euclidean distance.
- **cosine**       : 1 - Cosine similarity; ignores magnitude, focuses on direction.

@param h1      First (n_words,) float32 histogram.
@param h2      Second (n_words,) float32 histogram.
@param metric  Distance metric to use. Default "chi2".

@return Scalar float distance value (lower = more similar).

@throws ValueError if @p metric is not one of the supported strings.

Variable Documentation

◆ best

int best = top[1] if top[0]["distance"] < 1e-6 else top[0]

◆ DistanceMetric

DistanceMetric = Literal["chi2", "intersection", "hellinger", "l2", "cosine"]

Literal type enumerating supported histogram distance metrics.

Valid values: "chi2", "intersection", "hellinger", "l2", "cosine".

◆ groups

groups

◆ hist_img

hist_img = matcher.histogram_image(group_idx=0)

◆ Histogram

Histogram = np.ndarray

A (n_words,) float32 numpy ndarray representing an L1-normalized BoW histogram.

◆ labels

labels

◆ matcher

matcher = ColorBoWMatcher(n_words=20, metric="chi2")

◆ metric

metric

◆ n_groups

n_groups

◆ n_pixels_per_group

n_pixels_per_group

◆ n_true_colors

n_true_colors

◆ nonzero

dictionary nonzero = {f"w{i}": f"{v:.3f}" for i, v in enumerate(hist) if v > 0}

◆ query_group

query_group = groups[0]

◆ results

results = matcher.query(query_group)

◆ RGBMatrix

RGBMatrix = np.ndarray

A (3, N) numpy ndarray of dtype uint8 or float32 holding RGB pixel data.

◆ rng

rng = np.random.default_rng(42)

◆ top

top = matcher.query(query_group, top_k=2)

◆ vocab_img

vocab_img = matcher.vocabulary_as_image(swatch_size=50)