Pruthul commited on
Commit
f937de8
1 Parent(s): c725d08

Part-4 done (Streamlit)

Browse files

The image similarity performed here is done using cosine similarity.Including Resnet model and Tensorflow created problems while running on streamlit

Files changed (1) hide show
  1. app.py +239 -0
app.py ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ from PIL import Image
4
+ import numpy as np
5
+ import os
6
+ import matplotlib.pyplot as plt
7
+
8
+ # Define a function to search for similar images
9
+ def search_similar_images(img_path, num_results=10):
10
+ # Load the query image
11
+ query_image = cv2.imread(img_path)
12
+
13
+ # Convert the query image to grayscale
14
+ query_image_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY)
15
+
16
+ # Resize the query image to a fixed size
17
+ query_image_resized = cv2.resize(query_image_gray, (300, 300))
18
+
19
+ # Calculate the histogram of the query image
20
+ query_hist = cv2.calcHist([query_image_resized], [0], None, [256], [0, 256])
21
+
22
+ # Normalize the histogram
23
+ query_hist_norm = cv2.normalize(query_hist, query_hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
24
+
25
+ # Load all images from the 'images' directory
26
+ images_dir = "images"
27
+ image_files = os.listdir(images_dir)
28
+ images = []
29
+ for image_file in image_files:
30
+ if image_file.endswith(".jpg") or image_file.endswith(".png"):
31
+ image_path = os.path.join(images_dir, image_file)
32
+ image = cv2.imread(image_path)
33
+ images.append(image)
34
+
35
+ # Calculate the histograms and similarities for each image
36
+ similarities = []
37
+ for image in images:
38
+ # Convert the image to grayscale
39
+ image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
40
+
41
+ # Resize the image to a fixed size
42
+ image_resized = cv2.resize(image_gray, (300, 300))
43
+
44
+ # Calculate the histogram of the image
45
+ image_hist = cv2.calcHist([image_resized], [0], None, [256], [0, 256])
46
+
47
+ # Normalize the histogram
48
+ image_hist_norm = cv2.normalize(image_hist, image_hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
49
+
50
+ # Calculate the correlation between the histograms
51
+ similarity = cv2.compareHist(query_hist_norm, image_hist_norm, cv2.HISTCMP_CORREL)
52
+
53
+ # Add the similarity to the list
54
+ similarities.append(similarity)
55
+
56
+ # Get the indices of the top num_results most similar images
57
+ indices = np.argsort(similarities)[-num_results:]
58
+
59
+ # Create a list of the top num_results most similar images
60
+ results = []
61
+ for index in indices:
62
+ results.append(images[index])
63
+
64
+ # Return the list of results
65
+ return results
66
+
67
+ def display_results(similar_images):
68
+ # Create a figure with a grid of 10 subplots
69
+ fig, axs = plt.subplots(2, 5, figsize=(10, 4))
70
+
71
+ # Loop through the similar images and display each one in a subplot
72
+ for i,img in enumerate(similar_images):
73
+ # Load the image using OpenCV
74
+ # Convert to RGB for displaying with matplotlib
75
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
76
+
77
+ # Calculate the row and column index for the current subplot
78
+ row = i // 5
79
+ col = i % 5
80
+
81
+ # Display the image in the current subplot
82
+ axs[row, col].imshow(img)
83
+ axs[row, col].axis("off")
84
+
85
+ # Adjust the spacing between subplots and display the figure
86
+ plt.subplots_adjust(wspace=0.05, hspace=0.05)
87
+ st.pyplot(fig)
88
+
89
+ def app():
90
+ # Set the page title and icon
91
+ st.set_page_config(page_title="Similar Images Search", page_icon=":mag:")
92
+ # Add a title to the app
93
+ st.title("Find Similar Images")
94
+
95
+ # Add a description to the app
96
+ st.markdown("This app allows you to search for similar images.")
97
+
98
+ # Allow the user to choose between "Browse a single image" and "Select from test dataset"
99
+ option = st.radio("Select an option:", ("Browse a single image", "Select from test dataset"))
100
+
101
+ # If the user selects "Browse a single image"
102
+ if option == "Browse a single image":
103
+ # Allow the user to upload an image
104
+ uploaded_file = st.file_uploader("Choose an image:", type=["jpg", "jpeg", "png"])
105
+
106
+ # If the user has uploaded an image
107
+ if uploaded_file is not None:
108
+ # Load the image
109
+ image = Image.open(uploaded_file).convert("RGB")
110
+
111
+ # Display the uploaded image
112
+ st.image(image, caption="Uploaded Image", use_column_width=True)
113
+
114
+ # Search for similar images
115
+ # print("Uploaded file ==> ",uploaded_file)
116
+ # Save the image to a temporary file
117
+ temp_file_path = "temp.jpg"
118
+ image.save(temp_file_path)
119
+
120
+ results = search_similar_images(temp_file_path)
121
+
122
+ # Display the results as a grid of images
123
+ st.markdown("---")
124
+ st.subheader("Similar Images")
125
+ display_results(results)
126
+
127
+ # If the user selects "Select from test dataset"
128
+ else:
129
+ # Get a list of all test dataset image files
130
+ test_dataset_dir = "images"
131
+ test_dataset_files = os.listdir(test_dataset_dir)
132
+ test_dataset_images = []
133
+
134
+ # Display the list of test dataset image files in a sidebar
135
+ st.sidebar.title("Test Dataset")
136
+ for test_dataset_file in test_dataset_files:
137
+ if test_dataset_file.endswith(".jpg") or test_dataset_file.endswith(".png"):
138
+ test_dataset_image_path = os.path.join(test_dataset_dir, test_dataset_file)
139
+ test_dataset_image = Image.open(test_dataset_image_path)
140
+ test_dataset_images.append(test_dataset_image)
141
+
142
+ # Display the file name as a text instead of an image
143
+ st.sidebar.write(test_dataset_file)
144
+
145
+ # Allow the user to select an image from the test dataset
146
+ selected_image_path = st.sidebar.selectbox("Select an image:", test_dataset_files)
147
+
148
+ # Load the selected image
149
+ selected_image_path = os.path.join(test_dataset_dir, selected_image_path)
150
+ selected_image = Image.open(selected_image_path)
151
+
152
+ # Display the selected image
153
+ st.image(selected_image, caption="Selected Image", use_column_width=True)
154
+
155
+ # Search for similar images
156
+ results = search_similar_images(selected_image_path)
157
+
158
+ # Display the results as a grid of images
159
+ if selected_image_path != os.path.join(test_dataset_dir, test_dataset_files[0]):
160
+ st.markdown("---")
161
+ st.subheader("Similar Images")
162
+ display_results(results)
163
+ # for result in results:
164
+ # st.image(result, caption="Similar Image", use_column_width=True)
165
+ # print("result==> ",result)
166
+
167
+ # Add a footer to the app
168
+ st.markdown("---")
169
+ st.markdown("Created by Pruthul")
170
+
171
+
172
+ app()
173
+
174
+
175
+
176
+ #### == Image feature extraction using Resnet == (Failed when run using streamlit) ###
177
+
178
+ # from sklearn.neighbors import NearestNeighbors
179
+ # from tensorflow.keras.preprocessing.image import load_img, img_to_array
180
+ # from tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input
181
+
182
+ # def extract_features(image_path, model):
183
+ # # Load and preprocess the image
184
+ # image = load_img(image_path, target_size=(224, 224))
185
+ # image_array = img_to_array(image)
186
+ # image_array = preprocess_input(image_array)
187
+ # # Extract the features using the ResNet50 model
188
+ # features = model.predict(image_array.reshape(1, 224, 224, 3))
189
+
190
+ # # Flatten the features and return them as a 1D array
191
+ # features = features.flatten()
192
+ # return features
193
+
194
+
195
+ # # Define a function to search for similar images
196
+ # def search_similar_images(img_path, num_results=10):
197
+ # #load feature dictionary
198
+ # with open("features.npy", "rb") as f:
199
+ # image_dict = np.load(f, allow_pickle=True).item()
200
+
201
+ # # Fit a nearest neighbor model on the features
202
+ # nn_model = NearestNeighbors(n_neighbors=num_results, metric='cosine')
203
+
204
+ # # Convert the dictionary to a matrix of feature vectors
205
+ # features_list = np.array(list(image_dict.values()))
206
+
207
+ # # Fit the model to the feature matrix
208
+ # nn_model.fit(features_list)
209
+
210
+ # # Define the file path to the test image
211
+ # test_image_path = img_path
212
+
213
+ # # Load all images from the 'images' directory
214
+ # images_dir = "images"
215
+ # image_files = os.listdir(images_dir)
216
+ # images = []
217
+ # for image_file in image_files:
218
+ # if image_file.endswith(".jpg") or image_file.endswith(".png"):
219
+ # image_path = os.path.join(images_dir, image_file)
220
+ # image = cv2.imread(image_path)
221
+ # images.append(image)
222
+
223
+ # model = ResNet50(weights='imagenet', include_top=False)
224
+ # # Extract features from the test image
225
+ # test_image_features = extract_features(test_image_path, model)
226
+
227
+ # # Reshape the test image features to match the shape of the feature vectors
228
+ # test_image_features = test_image_features.reshape(1, -1)
229
+
230
+ # # # Find the 10 most similar images to the test image
231
+ # distances, indices = nn_model.kneighbors(test_image_features)
232
+
233
+ # # Create a list of the top num_results most similar images
234
+ # results = []
235
+ # for index in indices[0]:
236
+ # results.append(images[index])
237
+
238
+ # # Return the list of results
239
+ # return results