Spaces:
Runtime error
Runtime error
import streamlit as st | |
import cv2 | |
from PIL import Image | |
import numpy as np | |
import os | |
import matplotlib.pyplot as plt | |
# Define a function to search for similar images | |
def search_similar_images(img_path, num_results=10): | |
# Load the query image | |
query_image = cv2.imread(img_path) | |
# Convert the query image to grayscale | |
query_image_gray = cv2.cvtColor(query_image, cv2.COLOR_BGR2GRAY) | |
# Resize the query image to a fixed size | |
query_image_resized = cv2.resize(query_image_gray, (300, 300)) | |
# Calculate the histogram of the query image | |
query_hist = cv2.calcHist([query_image_resized], [0], None, [256], [0, 256]) | |
# Normalize the histogram | |
query_hist_norm = cv2.normalize(query_hist, query_hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX) | |
# Load all images from the 'images' directory | |
images_dir = "images" | |
image_files = os.listdir(images_dir) | |
images = [] | |
for image_file in image_files: | |
if image_file.endswith(".jpg") or image_file.endswith(".png"): | |
image_path = os.path.join(images_dir, image_file) | |
image = cv2.imread(image_path) | |
images.append(image) | |
# Calculate the histograms and similarities for each image | |
similarities = [] | |
for image in images: | |
# Convert the image to grayscale | |
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
# Resize the image to a fixed size | |
image_resized = cv2.resize(image_gray, (300, 300)) | |
# Calculate the histogram of the image | |
image_hist = cv2.calcHist([image_resized], [0], None, [256], [0, 256]) | |
# Normalize the histogram | |
image_hist_norm = cv2.normalize(image_hist, image_hist, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX) | |
# Calculate the correlation between the histograms | |
similarity = cv2.compareHist(query_hist_norm, image_hist_norm, cv2.HISTCMP_CORREL) | |
# Add the similarity to the list | |
similarities.append(similarity) | |
# Get the indices of the top num_results most similar images | |
indices = np.argsort(similarities)[-num_results:] | |
# Create a list of the top num_results most similar images | |
results = [] | |
for index in indices: | |
results.append(images[index]) | |
# Return the list of results | |
return results | |
def display_results(similar_images): | |
# Create a figure with a grid of 10 subplots | |
fig, axs = plt.subplots(2, 5, figsize=(10, 4)) | |
# Loop through the similar images and display each one in a subplot | |
for i,img in enumerate(similar_images): | |
# Load the image using OpenCV | |
# Convert to RGB for displaying with matplotlib | |
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | |
# Calculate the row and column index for the current subplot | |
row = i // 5 | |
col = i % 5 | |
# Display the image in the current subplot | |
axs[row, col].imshow(img) | |
axs[row, col].axis("off") | |
# Adjust the spacing between subplots and display the figure | |
plt.subplots_adjust(wspace=0.05, hspace=0.05) | |
st.pyplot(fig) | |
def app(): | |
# Set the page title and icon | |
st.set_page_config(page_title="Similar Images Search", page_icon=":mag:") | |
# Add a title to the app | |
st.title("Find Similar Images") | |
# Add a description to the app | |
st.markdown("This app allows you to search for similar images.") | |
# Allow the user to choose between "Browse a single image" and "Select from test dataset" | |
option = st.radio("Select an option:", ("Browse a single image", "Select from test dataset")) | |
# If the user selects "Browse a single image" | |
if option == "Browse a single image": | |
# Allow the user to upload an image | |
uploaded_file = st.file_uploader("Choose an image:", type=["jpg", "jpeg", "png"]) | |
# If the user has uploaded an image | |
if uploaded_file is not None: | |
# Load the image | |
image = Image.open(uploaded_file).convert("RGB") | |
# Display the uploaded image | |
st.image(image, caption="Uploaded Image", use_column_width=True) | |
# Search for similar images | |
# print("Uploaded file ==> ",uploaded_file) | |
# Save the image to a temporary file | |
temp_file_path = "temp.jpg" | |
image.save(temp_file_path) | |
results = search_similar_images(temp_file_path) | |
# Display the results as a grid of images | |
st.markdown("---") | |
st.subheader("Similar Images") | |
display_results(results) | |
# If the user selects "Select from test dataset" | |
else: | |
# Get a list of all test dataset image files | |
test_dataset_dir = "images" | |
test_dataset_files = os.listdir(test_dataset_dir) | |
test_dataset_images = [] | |
# Display the list of test dataset image files in a sidebar | |
st.sidebar.title("Test Dataset") | |
for test_dataset_file in test_dataset_files: | |
if test_dataset_file.endswith(".jpg") or test_dataset_file.endswith(".png"): | |
test_dataset_image_path = os.path.join(test_dataset_dir, test_dataset_file) | |
test_dataset_image = Image.open(test_dataset_image_path) | |
test_dataset_images.append(test_dataset_image) | |
# Display the file name as a text instead of an image | |
st.sidebar.write(test_dataset_file) | |
# Allow the user to select an image from the test dataset | |
selected_image_path = st.sidebar.selectbox("Select an image:", test_dataset_files) | |
# Load the selected image | |
selected_image_path = os.path.join(test_dataset_dir, selected_image_path) | |
selected_image = Image.open(selected_image_path) | |
# Display the selected image | |
st.image(selected_image, caption="Selected Image", use_column_width=True) | |
# Search for similar images | |
results = search_similar_images(selected_image_path) | |
# Display the results as a grid of images | |
if selected_image_path != os.path.join(test_dataset_dir, test_dataset_files[0]): | |
st.markdown("---") | |
st.subheader("Similar Images") | |
display_results(results) | |
# for result in results: | |
# st.image(result, caption="Similar Image", use_column_width=True) | |
# print("result==> ",result) | |
# Add a footer to the app | |
st.markdown("---") | |
st.markdown("Created by Pruthul") | |
app() | |
#### == Image feature extraction using Resnet == (Failed when run using streamlit) ### | |
# from sklearn.neighbors import NearestNeighbors | |
# from tensorflow.keras.preprocessing.image import load_img, img_to_array | |
# from tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input | |
# def extract_features(image_path, model): | |
# # Load and preprocess the image | |
# image = load_img(image_path, target_size=(224, 224)) | |
# image_array = img_to_array(image) | |
# image_array = preprocess_input(image_array) | |
# # Extract the features using the ResNet50 model | |
# features = model.predict(image_array.reshape(1, 224, 224, 3)) | |
# # Flatten the features and return them as a 1D array | |
# features = features.flatten() | |
# return features | |
# # Define a function to search for similar images | |
# def search_similar_images(img_path, num_results=10): | |
# #load feature dictionary | |
# with open("features.npy", "rb") as f: | |
# image_dict = np.load(f, allow_pickle=True).item() | |
# # Fit a nearest neighbor model on the features | |
# nn_model = NearestNeighbors(n_neighbors=num_results, metric='cosine') | |
# # Convert the dictionary to a matrix of feature vectors | |
# features_list = np.array(list(image_dict.values())) | |
# # Fit the model to the feature matrix | |
# nn_model.fit(features_list) | |
# # Define the file path to the test image | |
# test_image_path = img_path | |
# # Load all images from the 'images' directory | |
# images_dir = "images" | |
# image_files = os.listdir(images_dir) | |
# images = [] | |
# for image_file in image_files: | |
# if image_file.endswith(".jpg") or image_file.endswith(".png"): | |
# image_path = os.path.join(images_dir, image_file) | |
# image = cv2.imread(image_path) | |
# images.append(image) | |
# model = ResNet50(weights='imagenet', include_top=False) | |
# # Extract features from the test image | |
# test_image_features = extract_features(test_image_path, model) | |
# # Reshape the test image features to match the shape of the feature vectors | |
# test_image_features = test_image_features.reshape(1, -1) | |
# # # Find the 10 most similar images to the test image | |
# distances, indices = nn_model.kneighbors(test_image_features) | |
# # Create a list of the top num_results most similar images | |
# results = [] | |
# for index in indices[0]: | |
# results.append(images[index]) | |
# # Return the list of results | |
# return results |