Note
Go to the end to download the full example code.
Image Pattern Recognition¶
Topics: Image classification, spatial encoding, pattern matching, computer vision Time: 15 minutes Prerequisites: 17_encoders_image.py, 16_encoders_vector.py Related: 20_app_text_classification.py, 25_app_integration_patterns.py
This example demonstrates practical image pattern recognition using hyperdimensional computing. Learn how to classify simple image patterns using spatial encoding techniques.
Key concepts: - Image encoding: Flatten pixels + VectorEncoder - Pattern prototypes: Bundle examples per class - Classification: Similarity-based matching - Practical considerations: Real-world trade-offs
Image recognition with HDC is efficient and works well for simple patterns, edge devices, and situations with limited training data.
24 import numpy as np
25 from holovec import VSA
26 from holovec.encoders import VectorEncoder, FractionalPowerEncoder
27 from holovec.retrieval import ItemStore
28
29 print("=" * 70)
30 print("Image Pattern Recognition")
31 print("=" * 70)
32 print()
33
34 # Create model and encoder
35 model = VSA.create('FHRR', dim=10000, seed=42)
36
37 # For 8x8 images (64 pixels)
38 scalar_encoder = FractionalPowerEncoder(model, min_val=0, max_val=255, seed=42)
39 image_encoder = VectorEncoder(model, scalar_encoder, n_dimensions=64, seed=43)
40
41 print(f"Model: {model.model_name}, dimension={model.dimension}")
42 print(f"Image encoder: 8x8 grayscale (64D flattened)")
43 print()
44
45 # ============================================================================
46 # Dataset: Simple Shape Patterns
47 # ============================================================================
48 print("=" * 70)
49 print("Dataset: Simple 8x8 Shapes")
50 print("=" * 70)
51
52 np.random.seed(42)
53
54 # Create simple synthetic patterns
55 def create_vertical_line():
56 """Vertical line pattern."""
57 img = np.zeros((8, 8), dtype=np.uint8)
58 img[:, 3:5] = 200 # Vertical line in middle
59 return img.flatten()
60
61 def create_horizontal_line():
62 """Horizontal line pattern."""
63 img = np.zeros((8, 8), dtype=np.uint8)
64 img[3:5, :] = 200 # Horizontal line in middle
65 return img.flatten()
66
67 def create_cross():
68 """Cross pattern."""
69 img = np.zeros((8, 8), dtype=np.uint8)
70 img[3:5, :] = 200 # Horizontal
71 img[:, 3:5] = 200 # Vertical
72 return img.flatten()
73
74 def create_square():
75 """Square pattern."""
76 img = np.zeros((8, 8), dtype=np.uint8)
77 img[2:6, 2:6] = 200 # Square
78 return img.flatten()
79
80 # Generate training examples with variations (noise)
81 print("\nGenerating training examples (4 classes, 5 examples each):")
82
83 training_data = []
84 noise_level = 15 # pixel noise
85
86 # Vertical lines
87 for i in range(5):
88 img = create_vertical_line() + np.random.randint(-noise_level, noise_level, 64)
89 img = np.clip(img, 0, 255)
90 training_data.append((img, "vertical"))
91
92 # Horizontal lines
93 for i in range(5):
94 img = create_horizontal_line() + np.random.randint(-noise_level, noise_level, 64)
95 img = np.clip(img, 0, 255)
96 training_data.append((img, "horizontal"))
97
98 # Crosses
99 for i in range(5):
100 img = create_cross() + np.random.randint(-noise_level, noise_level, 64)
101 img = np.clip(img, 0, 255)
102 training_data.append((img, "cross"))
103
104 # Squares
105 for i in range(5):
106 img = create_square() + np.random.randint(-noise_level, noise_level, 64)
107 img = np.clip(img, 0, 255)
108 training_data.append((img, "square"))
109
110 print(f" vertical: 5 examples")
111 print(f" horizontal: 5 examples")
112 print(f" cross: 5 examples")
113 print(f" square: 5 examples")
114 print(f"\nTotal: {len(training_data)} training examples")
115
116 # ============================================================================
117 # Training: Build Pattern Prototypes
118 # ============================================================================
119 print("\n" + "=" * 70)
120 print("Training: Building Pattern Prototypes")
121 print("=" * 70)
122
123 # Group by class
124 classes = {}
125 for img, label in training_data:
126 if label not in classes:
127 classes[label] = []
128 classes[label].append(img)
129
130 # Encode and bundle per class
131 pattern_prototypes = {}
132
133 print("\nEncoding patterns:")
134 for label, images in classes.items():
135 encoded = [image_encoder.encode(img.astype(float)) for img in images]
136 prototype = model.bundle(encoded)
137 pattern_prototypes[label] = prototype
138 print(f" {label:12s}: {len(images)} examples → prototype")
139
140 print(f"\nPattern prototypes created: {len(pattern_prototypes)}")
141
142 # ============================================================================
143 # Classification: Test on New Patterns
144 # ============================================================================
145 print("\n" + "=" * 70)
146 print("Classification: Testing on New Patterns")
147 print("=" * 70)
148
149 # Create test patterns with noise
150 test_patterns = [
151 (create_vertical_line() + np.random.randint(-10, 10, 64), "vertical"),
152 (create_horizontal_line() + np.random.randint(-10, 10, 64), "horizontal"),
153 (create_cross() + np.random.randint(-10, 10, 64), "cross"),
154 (create_square() + np.random.randint(-10, 10, 64), "square"),
155 ]
156
157 test_patterns = [(np.clip(img, 0, 255), label) for img, label in test_patterns]
158
159 print("\nClassifying test patterns:")
160 print()
161
162 correct = 0
163 for i, (img, expected) in enumerate(test_patterns, 1):
164 # Encode test pattern
165 test_hv = image_encoder.encode(img.astype(float))
166
167 # Find most similar prototype
168 best_label = None
169 best_sim = float('-inf')
170
171 for label, prototype in pattern_prototypes.items():
172 sim = float(model.similarity(test_hv, prototype))
173 if sim > best_sim:
174 best_sim = sim
175 best_label = label
176
177 is_correct = (best_label == expected)
178 correct += (1 if is_correct else 0)
179 marker = "✓" if is_correct else "✗"
180
181 print(f"{i}. Pattern: {expected:12s}")
182 print(f" Predicted: {best_label:12s} (similarity={best_sim:.3f}) {marker}")
183 print()
184
185 accuracy = correct / len(test_patterns)
186 print(f"Accuracy: {correct}/{len(test_patterns)} = {accuracy:.1%}")
187
188 # ============================================================================
189 # Analysis: Similarity Scores
190 # ============================================================================
191 print("\n" + "=" * 70)
192 print("Analysis: Pattern Similarity Matrix")
193 print("=" * 70)
194
195 print("\nSimilarity between pattern prototypes:")
196 labels = sorted(pattern_prototypes.keys())
197
198 # Print header
199 print(f"{'':12s}", end="")
200 for label in labels:
201 print(f" {label:>10s}", end="")
202 print()
203
204 # Print matrix
205 for label1 in labels:
206 print(f"{label1:12s}", end="")
207 for label2 in labels:
208 sim = float(model.similarity(pattern_prototypes[label1],
209 pattern_prototypes[label2]))
210 print(f" {sim:10.3f}", end="")
211 print()
212
213 print("\nKey observation:")
214 print(" - Diagonal = 1.0 (self-similarity)")
215 print(" - Off-diagonal shows inter-class confusion")
216 print(" - Cross similar to both vertical and horizontal")
217
218 # ============================================================================
219 # Practical Considerations
220 # ============================================================================
221 print("\n" + "=" * 70)
222 print("Practical Considerations")
223 print("=" * 70)
224
225 print("\n✓ Advantages of HDC Image Recognition:")
226 print(" - Fast: No backpropagation or gradient descent")
227 print(" - Small: Works with limited training data")
228 print(" - Efficient: Low memory and compute requirements")
229 print(" - Interpretable: Similarity scores show confidence")
230 print(" - Robust: Tolerant to noise and distortions")
231 print()
232
233 print("✗ Limitations:")
234 print(" - Accuracy: Not as good as CNNs for complex images")
235 print(" - Scale: Best for small images (8x8, 16x16, 28x28)")
236 print(" - Features: Doesn't learn features like deep learning")
237 print(" - Flattening: Loses 2D spatial structure")
238 print()
239
240 print("Best use cases:")
241 print(" - Edge devices (limited compute/memory)")
242 print(" - Few-shot learning (< 10 examples per class)")
243 print(" - Simple patterns (icons, symbols, digits)")
244 print(" - Rapid prototyping (baseline before CNN)")
245 print(" - Explainable AI (similarity scores)")
246 print()
247
248 # ============================================================================
249 # Extension: Efficient Multi-Pattern Recognition
250 # ============================================================================
251 print("=" * 70)
252 print("Extension: ItemStore for Efficient Recognition")
253 print("=" * 70)
254
255 # Build pattern store
256 pattern_store = ItemStore(model)
257 for label, prototype in pattern_prototypes.items():
258 pattern_store.add(label, prototype)
259
260 print(f"\nPattern store built with {len(pattern_prototypes)} classes")
261
262 # Test pattern
263 test_img = create_cross() + np.random.randint(-15, 15, 64)
264 test_img = np.clip(test_img, 0, 255)
265 test_hv = image_encoder.encode(test_img.astype(float))
266
267 # Query returns ranked results
268 results = pattern_store.query(test_hv, k=4)
269
270 print("\nTest pattern: cross (with noise)")
271 print("\nTop predictions:")
272 for i, (label, sim) in enumerate(results, 1):
273 print(f" {i}. {label:12s}: {sim:.3f}")
274
275 print("\nKey observation:")
276 print(" - ItemStore enables fast k-nearest pattern retrieval")
277 print(" - Can examine confidence of predictions")
278 print(" - Scales to many pattern classes")
279
280 # ============================================================================
281 # Summary
282 # ============================================================================
283 print("\n" + "=" * 70)
284 print("Summary: Image Pattern Recognition with HDC")
285 print("=" * 70)
286 print()
287 print("Complete workflow:")
288 print(" 1. Setup: Create model + VectorEncoder for flattened pixels")
289 print(" 2. Training: Encode images + bundle per pattern class")
290 print(" 3. Recognition: Encode test image + find nearest prototype")
291 print(" 4. Evaluation: Check similarity for confidence")
292 print()
293 print("Performance tips:")
294 print(" - Use FractionalPowerEncoder for pixel values (continuous)")
295 print(" - Normalize images to [0, 1] or [0, 255]")
296 print(" - More training examples → better prototypes")
297 print(" - Consider ImageEncoder (17) for true 2D spatial structure")
298 print()
299 print("Next steps:")
300 print(" → Try with MNIST digits (28x28 = 784D)")
301 print(" → Experiment with different scalar encoders")
302 print(" → Use ImageEncoder (17) for full spatial encoding")
303 print(" → Combine with 25_app_integration_patterns.py for multimodal")
304 print()
305 print("=" * 70)