Build an Image Search Engine
Weaviate is a vector database that allows you to create and query embeddings with pre-trained deep learning models. It integrates with ResNet-50 to vectorize images, making it possible to build an image similarity search engine with relative ease.
Initial Setup
Docker Compose Wizard
To run Weaviate locally, use their wizard to generate a Docker Compose config that supports the image module.
Install the Weaviate Client
Create a new Node.js project and install the Weaviate TS client.
npm init -y
npm i weaviate-ts-client
Image Search Engine App
Initialize the Client
Initialize the client and fetch the schema just to make sure the database is up and running.
import weaviate from 'weaviate-ts-client';
const client = weaviate.client({
scheme: 'http',
host: 'localhost:8080',
});
const schemaRes = await client.schema.getter().do();
console.log(schemaRes)
Create a Schema
Create a schema that contains an image property.
const schemaConfig = {
'class': 'Meme',
'vectorizer': 'img2vec-neural',
'vectorIndexType': 'hnsw',
'moduleConfig': {
'img2vec-neural': {
'imageFields': [
'image'
]
}
},
'properties': [
{
'name': 'image',
'dataType': ['blob']
},
{
'name': 'text',
'dataType': ['string']
}
]
}
await client.schema
.classCreator()
.withClass(schemaConfig)
.do();
Store an Image
Images must first be converted to base64. Once converted, store it to the cooresponding class in the schema. Weaviate will automatically use the neural network in the background to vectorize it and update the embedding.
const img = readFileSync('./img/hi-mom.jpg');
const b64 = Buffer.from(img).toString('base64');
await client.data.creator()
.withClassName('Meme')
.withProperties({
image: b64,
text: 'matrix meme'
})
.do();
Query an Image
After storing a few images, we can provide an image as a query input. The database will use HNSW to quickly find similar looking images.
const test = Buffer.from( readFileSync('./test.jpg') ).toString('base64');
const resImage = await client.graphql.get()
.withClassName('Meme')
.withFields(['image'])
.withNearImage({ image: test })
.withLimit(1)
.do();
// Write result to filesystem
const result = resImage.data.Get.Meme[0].image;
writeFileSync('./result.jpg', result, 'base64');
And finally, run it with Node to your search engine in action!
node index.js