tharu22 commited on
Commit
7d2ad69
Β·
1 Parent(s): 2fb20fd
Files changed (1) hide show
  1. app.py +74 -33
app.py CHANGED
@@ -8,7 +8,7 @@ import numpy as np
8
  import torch
9
 
10
  # βœ… Initialize Pinecone
11
- pc = Pinecone(api_key="pcsk_6r4DPn_4P9LckhZak3PhebvSebnEBKQZuzYFeJL2X93LtLxZVBxyJ93inBAktefa8usvJC") # Replace with your API key
12
  index_name = "unsplash-index"
13
  unsplash_index = pc.Index(index_name)
14
 
@@ -26,16 +26,14 @@ def get_text_embedding(text):
26
  inputs = processor(text=[text], return_tensors="pt", padding=True, truncation=True)
27
  with torch.no_grad():
28
  text_features = model.get_text_features(**inputs)
29
- embedding = text_features.detach().cpu().numpy().flatten().tolist()
30
- return embedding
31
 
32
  # βœ… Function to Generate Embedding from Image
33
  def get_image_embedding(image):
34
  inputs = processor(images=image, return_tensors="pt")
35
  with torch.no_grad():
36
  image_features = model.get_image_features(**inputs)
37
- embedding = image_features.detach().cpu().numpy().flatten().tolist()
38
- return embedding
39
 
40
  # βœ… Function to Query Pinecone and Fetch Similar Images
41
  def search_similar_images(embedding, top_k=10):
@@ -47,6 +45,14 @@ def search_similar_images(embedding, top_k=10):
47
  )
48
  return results.get("matches", [])
49
 
 
 
 
 
 
 
 
 
50
  # βœ… Streamlit UI
51
  st.title("πŸ” Image & Text Search with CLIP & Pinecone")
52
  st.write("Search for images using text or upload an image to find similar ones!")
@@ -60,21 +66,25 @@ if st.button("πŸ” Search by Text"):
60
  with st.spinner("Generating embedding..."):
61
  embedding = get_text_embedding(search_query)
62
  with st.spinner("Searching for similar images..."):
63
- matches = search_similar_images(embedding, top_k=10)
64
 
65
  st.subheader("πŸ”Ž Top Similar Images")
66
- for match in matches:
67
- score = match.get("score", 0)
68
- photo_id = match.get("id", "Unknown ID")
69
- url = match.get("metadata", {}).get("url", None)
70
-
71
- st.write(f"**Photo ID**: {photo_id} | **Similarity Score**: {score:.4f}")
72
- if url:
73
- st.image(url, caption=f"Photo ID: {photo_id}", use_container_width=True)
74
- else:
75
- st.warning(f"Image URL not found for Photo ID: {photo_id}")
76
- else:
77
- st.warning("⚠️ Please enter a search query!")
 
 
 
 
78
 
79
  # πŸ“Œ **Option 2: Image-to-Image Search**
80
  st.subheader("πŸ–ΌοΈ Search by Image")
@@ -89,20 +99,51 @@ if uploaded_file:
89
  embedding = get_image_embedding(image)
90
 
91
  with st.spinner("Searching for similar images..."):
92
- matches = search_similar_images(embedding, top_k=10)
93
 
94
  st.subheader("πŸ”Ž Top Similar Images")
95
- for match in matches:
96
- score = match.get("score", 0)
97
- photo_id = match.get("id", "Unknown ID")
98
- url = match.get("metadata", {}).get("url", None)
99
-
100
- st.write(f"**Photo ID**: {photo_id} | **Similarity Score**: {score:.4f}")
101
- if url:
102
- st.image(url, caption=f"Photo ID: {photo_id}", use_container_width=True)
103
- else:
104
- st.warning(f"Image URL not found for Photo ID: {photo_id}")
105
-
106
- # Instructions
107
- st.write("---")
108
- st.write("Note: This app searches an Unsplash dataset indexed in Pinecone using CLIP embeddings for both text and images.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  import torch
9
 
10
  # βœ… Initialize Pinecone
11
+ pc = Pinecone(api_key="your-pinecone-api-key") # Replace with your Pinecone API key
12
  index_name = "unsplash-index"
13
  unsplash_index = pc.Index(index_name)
14
 
 
26
  inputs = processor(text=[text], return_tensors="pt", padding=True, truncation=True)
27
  with torch.no_grad():
28
  text_features = model.get_text_features(**inputs)
29
+ return text_features.detach().cpu().numpy().flatten().tolist()
 
30
 
31
  # βœ… Function to Generate Embedding from Image
32
  def get_image_embedding(image):
33
  inputs = processor(images=image, return_tensors="pt")
34
  with torch.no_grad():
35
  image_features = model.get_image_features(**inputs)
36
+ return image_features.detach().cpu().numpy().flatten().tolist()
 
37
 
38
  # βœ… Function to Query Pinecone and Fetch Similar Images
39
  def search_similar_images(embedding, top_k=10):
 
45
  )
46
  return results.get("matches", [])
47
 
48
+ # βœ… Sidebar for Customization
49
+ st.sidebar.title("βš™οΈ Settings")
50
+ top_k = st.sidebar.slider("πŸ”’ Number of Similar Images", 1, 20, 10)
51
+ theme = st.sidebar.radio("🎨 Theme", ["Light Mode", "Dark Mode"], index=0)
52
+
53
+ # Apply Theme
54
+ st.set_page_config(page_title="Image Search App", layout="wide", initial_sidebar_state="expanded")
55
+
56
  # βœ… Streamlit UI
57
  st.title("πŸ” Image & Text Search with CLIP & Pinecone")
58
  st.write("Search for images using text or upload an image to find similar ones!")
 
66
  with st.spinner("Generating embedding..."):
67
  embedding = get_text_embedding(search_query)
68
  with st.spinner("Searching for similar images..."):
69
+ matches = search_similar_images(embedding, top_k=top_k)
70
 
71
  st.subheader("πŸ”Ž Top Similar Images")
72
+
73
+ if matches:
74
+ cols = st.columns(3) # Arrange images in 3 columns
75
+ for i, match in enumerate(matches):
76
+ score = match.get("score", 0)
77
+ photo_id = match.get("id", "Unknown ID")
78
+ url = match.get("metadata", {}).get("url", None)
79
+
80
+ with cols[i % 3]: # Alternate images in columns
81
+ st.write(f"πŸ“· **Photo ID**: {photo_id} | πŸ”’ **Score**: {score:.4f}")
82
+ if url:
83
+ st.image(url, caption=f"Photo ID: {photo_id}", use_container_width=True)
84
+ else:
85
+ st.warning(f"⚠️ Image URL not found for Photo ID: {photo_id}")
86
+ else:
87
+ st.warning("⚠️ No similar images found!")
88
 
89
  # πŸ“Œ **Option 2: Image-to-Image Search**
90
  st.subheader("πŸ–ΌοΈ Search by Image")
 
99
  embedding = get_image_embedding(image)
100
 
101
  with st.spinner("Searching for similar images..."):
102
+ matches = search_similar_images(embedding, top_k=top_k)
103
 
104
  st.subheader("πŸ”Ž Top Similar Images")
105
+
106
+ if matches:
107
+ cols = st.columns(3) # Arrange in 3 columns
108
+ for i, match in enumerate(matches):
109
+ score = match.get("score", 0)
110
+ photo_id = match.get("id", "Unknown ID")
111
+ url = match.get("metadata", {}).get("url", None)
112
+
113
+ with cols[i % 3]: # Alternate images in columns
114
+ st.write(f"οΏ½οΏ½οΏ½ **Photo ID**: {photo_id} | πŸ”’ **Score**: {score:.4f}")
115
+ if url:
116
+ st.image(url, caption=f"Photo ID: {photo_id}", use_container_width=True)
117
+ else:
118
+ st.warning(f"⚠️ Image URL not found for Photo ID: {photo_id}")
119
+
120
+ # πŸ“₯ **Download Option**
121
+ with st.expander("⬇️ Download Images"):
122
+ for match in matches:
123
+ url = match.get("metadata", {}).get("url", None)
124
+ if url:
125
+ st.markdown(f"[Download Image]({url})", unsafe_allow_html=True)
126
+ else:
127
+ st.warning("⚠️ No similar images found!")
128
+
129
+ # βœ… Add Footer
130
+ st.markdown(
131
+ """
132
+ ---
133
+ πŸ’‘ **About:** This app uses **CLIP & Pinecone** to perform **Text-to-Image & Image-to-Image Search**.
134
+ Built with **Streamlit, Pinecone, and Hugging Face Transformers**.
135
+ πŸ“© Contact: [Your Email or GitHub](#)
136
+ """
137
+ )
138
+
139
+ # βœ… Apply Dark Mode if selected
140
+ if theme == "Dark Mode":
141
+ st.markdown(
142
+ """
143
+ <style>
144
+ body { background-color: #121212; color: white; }
145
+ .stTextInput, .stFileUploader, .stButton { background-color: #333; color: white; }
146
+ </style>
147
+ """,
148
+ unsafe_allow_html=True,
149
+ )