You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Requires model to be in raw resources at e.g res/raw/image_encoder_quant_int8.onnx
112
-
val imageEmbedder =ClipImageEmbedder(context, ResourceId(R.raw.image_encoder_quant_int8))
118
+
// downloaded model
119
+
val imageEmbedder =ModelManager.getImageEmbedder(application, ModelName.DINOV2_SMALL)
120
+
121
+
// bundled model
122
+
val imageEmbedder =ClipImageEmbedder(application, ModelAssetSource.Resource(R.raw.clip_image_encoder_quant))
113
123
114
124
val embedding = imageEmbedder.embed(bitmap)
115
125
@@ -119,23 +129,23 @@ val embedding = imageEmbedder.embed(bitmap)
119
129
**Batch Example:**
120
130
121
131
```kotlin
122
-
val images:List<Bitmap>=...
123
-
val embeddings =imageEmbedder.embedBatch(images)
132
+
val images= listOf<Bitmap>()
133
+
val embeddings = embedBatch(context, imageEmbedder, images)
124
134
```
125
135
126
136
### Indexing
127
137
128
-
To get started with indexing media quickly, you can use the provided `ImageIndex` and `VideoIndexer` classes as shown below. You can optionally create your own indexers (including for text related data) by implementing the `BatchProcessor` interface. See docs for more details.
138
+
To get started with indexing media quickly, you can use the provided `ImageIndex` and `VideoIndexer` classes as shown below. You can optionally create your own indexers (including for text related data) by extending the `BatchProcessor`. See [docs](docs/core/processors.md) for more details.
129
139
130
140
#### Image Indexing
131
141
132
142
Index images to enable similarity search. The index is saved as a binary file and managed with a FileEmbeddingStore.
133
-
> **Important**: During indexing the MediaStore Id is used to as the id in the `Embedding` which is stored. This can later be used for retrieval.
143
+
> **Important**: During indexing the MediaStore Id is used to as the id in the `StoredEmbedding` which is stored. This can later be used for retrieval.
134
144
135
145
136
146
```kotlin
137
147
val imageEmbedder =ClipImageEmbedder(context, ResourceId(R.raw.image_encoder_quant_int8))
138
-
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim, useCache =false) // cache not needed for indexing
148
+
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim)
139
149
val imageIndexer =ImageIndexer(imageEmbedder, context=context, listener =null, store = imageStore) //optionally pass a listener to handle events
140
150
val ids = getImageIds() // placeholder function to get MediaStore image ids
141
151
imageIndexer.run(ids)
@@ -144,10 +154,11 @@ imageIndexer.run(ids)
144
154
#### Video Indexing
145
155
146
156
Index videos to enable similarity search. The index is saved as a binary file and managed with a FileEmbeddingStore.
157
+
> **Important**: During indexing the MediaStore Id is used to as the id in the `StoredEmbedding` which is stored. This can later be used for retrieval.
147
158
148
159
```kotlin
149
160
val imageEmbedder =ClipImageEmbedder(context, ResourceId(R.raw.image_encoder_quant_int8))
150
-
val videoStore =FileEmbeddingStore(File(context.filesDir, "video_index.bin"), imageEmbedder.embeddingDim, useCache =false )
161
+
val videoStore =FileEmbeddingStore(File(context.filesDir, "video_index.bin"), imageEmbedder.embeddingDim )
151
162
val videoIndexer =VideoIndexer(imageEmbedder, context=context, listener =null, store = videoStore, width =ClipConfig.IMAGE_SIZE_X, height =ClipConfig.IMAGE_SIZE_Y)
152
163
val ids = getVideoIds() // placeholder function to get MediaStore video ids
153
164
videoIndexer.run(ids)
@@ -160,30 +171,46 @@ Below shows how to search using both text queries and an image. The returns resu
160
171
#### Text-to-Image Search
161
172
162
173
```kotlin
163
-
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim, useCache =false) // cache not needed for indexing
164
-
val imageRetriever =FileEmbeddingRetriever(imageStore)
165
-
val textEmbedder =ClipTextEmbedder(context, ResourceId(R.raw.text_encoder_quant_int8))
174
+
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim)
166
175
val query ="my search query"
167
176
val embedding = textEmbedder.embed(query)
168
177
val topK =20
169
178
val similarityThreshold =0.2f
170
-
val results =retriever.query(embedding, topK, similarityThreshold)
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim, useCache =false) // cache not needed for indexing
178
-
val imageRetriever =FileEmbeddingRetriever(imageStore)
179
-
val imageEmbedder =ClipImageEmbedder(context, ResourceId(R.raw.image_encoder_quant_int8))
186
+
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim)
180
187
val embedding = imageEmbedder.embed(bitmap)
181
188
val topK =20
182
189
val similarityThreshold =0.2f
183
-
val results = retriever.query(embedding, topK, similarityThreshold)
190
+
val results = imageStore.query(embedding, topK, similarityThreshold)
191
+
```
192
+
193
+
#### ANN Search (HNSW Index)
184
194
195
+
```kotlin
196
+
val annIndex =HNSWIndex(dim=512)
197
+
val query ="my search query"
198
+
val embedding = textEmbedder.embed(query)
199
+
val topK =5
200
+
val results = annIndex.query(embedding, topK) // returns nearest neighbour indices must map to item id
185
201
```
186
202
203
+
### Clustering
204
+
205
+
Incremental clustering groups embeddings as they are added see [docs](docs/core/clustering.md) for more details.
206
+
207
+
```kotlin
208
+
val imageStore =FileEmbeddingStore(File(context.filesDir, "image_index.bin"), imageEmbedder.embeddingDim)
209
+
val itemEmbeds = store.get()
210
+
val existingClusters:Map<Long, Cluster> = emptyMap() // optionally pass existing clusters
211
+
val clusterer =IncrementalClusterer(existingClusters = existingClusters, defaultThreshold =0.4f)
0 commit comments