TensorCruncher commited on
Commit
816eb0d
·
verified ·
1 Parent(s): 809555a

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +83 -0
  2. image_embeddings.npy +3 -0
  3. image_paths.json +0 -0
  4. requirements.txt +6 -0
app.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import open_clip
4
+ import faiss
5
+ import numpy as np
6
+ import json
7
+ from PIL import Image
8
+ from transformers import BlipProcessor, BlipForConditionalGeneration
9
+
10
+ with open("image_paths.json", "r") as f:
11
+ image_paths = json.load(f)
12
+
13
+ image_embeddings = np.load("image_embeddings.npy")
14
+
15
+ model, _, preprocess = open_clip.create_model_and_transforms('ViT-B-32', pretrained='laion2b_s34b_b79k')
16
+ tokenizer = open_clip.get_tokenizer('ViT-B-32')
17
+
18
+ d = image_embeddings.shape[1]
19
+ index = faiss.IndexFlatIP(d)
20
+ index.add(image_embeddings)
21
+
22
+ processor_cap = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
23
+ model_cap = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
24
+
25
+ def search_text(query, top_k=3):
26
+ with torch.no_grad():
27
+ tokenized = tokenizer([query])
28
+ text_embed = model.encode_text(tokenized)
29
+ text_embed = text_embed / text_embed.norm(dim=-1, keepdim=True)
30
+ text_np = text_embed.cpu().numpy()
31
+ _, I = index.search(text_np, top_k)
32
+ return [image_paths[i] for i in I[0]]
33
+
34
+ def search_image(image, top_k=3):
35
+ image_tensor = preprocess(image).unsqueeze(0)
36
+ with torch.no_grad():
37
+ image_embed = model.encode_image(image_tensor)
38
+ image_embed = image_embed / image_embed.norm(dim=-1, keepdim=True)
39
+ image_np = image_embed.cpu().numpy()
40
+ _, I = index.search(image_np, top_k)
41
+ return [image_paths[i] for i in I[0]]
42
+
43
+ def generate_captions(paths):
44
+ imgs = [Image.open(p).convert("RGB") for p in paths]
45
+ inputs = processor_cap(images=imgs, return_tensors="pt")
46
+ out = model_cap.generate(**inputs)
47
+ captions = [processor_cap.decode(out[i], skip_special_tokens=True) for i in range(len(imgs))]
48
+ return captions
49
+
50
+ def predict(input_text, input_image):
51
+ if input_text:
52
+ paths = search_text(input_text)
53
+ elif input_image:
54
+ paths = search_image(input_image)
55
+ else:
56
+ return None, None
57
+
58
+ captions = generate_captions(paths)
59
+ return [(Image.open(p), c) for p, c in zip(paths, captions)]
60
+
61
+ with gr.Blocks() as demo:
62
+ gr.Markdown("## Animal Image Search 🐈 🏞️ 🔎 ")
63
+
64
+ with gr.Row():
65
+ text_input = gr.Textbox(label="Type your query")
66
+ image_input = gr.Image(type="pil", label="Or upload an image")
67
+
68
+ gr.Examples(
69
+ examples=[
70
+ "examples/sample1.jpg",
71
+ "examples/sample2.jpg",
72
+ "examples/sample3.jpg"
73
+ ],
74
+ inputs=[image_input],
75
+ label="Choose a sample image"
76
+ )
77
+
78
+ output = gr.Gallery(label="Top Matches with Captions").style(grid=[1], height="auto")
79
+
80
+ submit = gr.Button("Search")
81
+ submit.click(predict, inputs=[text_input, image_input], outputs=output)
82
+
83
+ demo.launch()
image_embeddings.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8a48867e7ee345749a9e16d79ff4d78a2d01c2fbc2b8cd8705aa5dfc92171764
3
+ size 11059328
image_paths.json ADDED
The diff for this file is too large to render. See raw diff
 
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ torch
3
+ torchvision
4
+ open-clip-torch
5
+ faiss-cpu
6
+ transformers