Upload 51 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- main.py +97 -0
- templates/index.html +76 -0
- templates/result.html +20 -0
- test_folder/download (1).jpeg +0 -0
- test_folder/download (10).jpeg +0 -0
- test_folder/download (11).jpeg +0 -0
- test_folder/download (12).jpeg +0 -0
- test_folder/download (13).jpeg +0 -0
- test_folder/download (14).jpeg +0 -0
- test_folder/download (15).jpeg +0 -0
- test_folder/download (16).jpeg +0 -0
- test_folder/download (17).jpeg +0 -0
- test_folder/download (18).jpeg +0 -0
- test_folder/download (19).jpeg +0 -0
- test_folder/download (2).jpeg +0 -0
- test_folder/download (20).jpeg +0 -0
- test_folder/download (21).jpeg +0 -0
- test_folder/download (22).jpeg +0 -0
- test_folder/download (23).jpeg +0 -0
- test_folder/download (24).jpeg +0 -0
- test_folder/download (25).jpeg +0 -0
- test_folder/download (26).jpeg +0 -0
- test_folder/download (27).jpeg +0 -0
- test_folder/download (28).jpeg +0 -0
- test_folder/download (29).jpeg +0 -0
- test_folder/download (3).jpeg +0 -0
- test_folder/download (30).jpeg +0 -0
- test_folder/download (4).jpeg +0 -0
- test_folder/download (5).jpeg +0 -0
- test_folder/download (6).jpeg +0 -0
- test_folder/download (7).jpeg +0 -0
- test_folder/download (8).jpeg +0 -0
- test_folder/download (9).jpeg +0 -0
- test_folder/download.jpeg +0 -0
- test_folder/flowers/download (10).jpeg +0 -0
- test_folder/flowers/download (11).jpeg +0 -0
- test_folder/flowers/download (12).jpeg +0 -0
- test_folder/flowers/download (13).jpeg +0 -0
- test_folder/flowers/download (14).jpeg +0 -0
- test_folder/flowers/download (15).jpeg +0 -0
- test_folder/flowers/download (16).jpeg +0 -0
- test_folder/flowers/download (6).jpeg +0 -0
- test_folder/flowers/download (7).jpeg +0 -0
- test_folder/flowers/download (8).jpeg +0 -0
- test_folder/flowers/download (9).jpeg +0 -0
- test_folder/flowers/images (1).jpeg +0 -0
- test_folder/flowers/images (2).jpeg +0 -0
- test_folder/flowers/images.jpeg +0 -0
- test_folder/images (1).jpeg +0 -0
- test_folder/images (2).jpeg +0 -0
main.py
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import numpy as np
|
3 |
+
from tensorflow.keras.applications import VGG16
|
4 |
+
from tensorflow.keras.models import Model
|
5 |
+
from tensorflow.keras.preprocessing.image import img_to_array
|
6 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
7 |
+
from flask import Flask, request, render_template
|
8 |
+
import os
|
9 |
+
|
10 |
+
# Constants
|
11 |
+
IMAGE_SIZE = (224, 224)
|
12 |
+
SIMILARITY_THRESHOLD = 0.8 # Default value
|
13 |
+
|
14 |
+
def resize_image(image, size=IMAGE_SIZE):
|
15 |
+
return image.resize(size)
|
16 |
+
|
17 |
+
def normalize_image(image):
|
18 |
+
return np.array(image) / 255.0
|
19 |
+
|
20 |
+
def extract_features(image):
|
21 |
+
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
|
22 |
+
model = Model(inputs=base_model.input, outputs=base_model.layers[-1].output)
|
23 |
+
image = img_to_array(image)
|
24 |
+
image = np.expand_dims(image, axis=0)
|
25 |
+
return model.predict(image).flatten()
|
26 |
+
|
27 |
+
def find_most_similar(input_features, image_features):
|
28 |
+
similarities = cosine_similarity([input_features], image_features)
|
29 |
+
similar_indices = [i for i, score in enumerate(similarities[0]) if score >= SIMILARITY_THRESHOLD]
|
30 |
+
return similar_indices
|
31 |
+
|
32 |
+
def compare_images(input_image, comparison_images):
|
33 |
+
input_image = resize_image(input_image)
|
34 |
+
input_image = normalize_image(input_image)
|
35 |
+
input_features = extract_features(input_image)
|
36 |
+
|
37 |
+
comparison_features = []
|
38 |
+
image_names = []
|
39 |
+
|
40 |
+
static_folder = os.path.join('static')
|
41 |
+
if not os.path.exists(static_folder):
|
42 |
+
os.makedirs(static_folder)
|
43 |
+
|
44 |
+
for i, image in enumerate(comparison_images):
|
45 |
+
image_name = f"image_{i}.png"
|
46 |
+
image_path = os.path.join(static_folder, image_name)
|
47 |
+
|
48 |
+
# Save the image using PIL Image object
|
49 |
+
img = resize_image(image)
|
50 |
+
img.save(image_path)
|
51 |
+
|
52 |
+
img_array = normalize_image(img)
|
53 |
+
comparison_features.append(extract_features(img_array))
|
54 |
+
image_names.append(image_name)
|
55 |
+
|
56 |
+
most_similar_indices = find_most_similar(input_features, comparison_features)
|
57 |
+
similar_images = [image_names[index] for index in most_similar_indices]
|
58 |
+
|
59 |
+
return similar_images
|
60 |
+
|
61 |
+
app = Flask(__name__)
|
62 |
+
|
63 |
+
@app.route('/', methods=['GET', 'POST'])
|
64 |
+
def upload_file():
|
65 |
+
global SIMILARITY_THRESHOLD
|
66 |
+
|
67 |
+
if request.method == 'POST':
|
68 |
+
try:
|
69 |
+
# Read similarity threshold from form
|
70 |
+
SIMILARITY_THRESHOLD = float(request.form.get('similarity_threshold', 0.8))
|
71 |
+
|
72 |
+
input_image = request.files['input_image']
|
73 |
+
comparison_images = request.files.getlist('comparison_images')
|
74 |
+
|
75 |
+
# Ensure input image is not empty
|
76 |
+
if input_image.filename == '':
|
77 |
+
return "No selected file for input image."
|
78 |
+
|
79 |
+
# Read and process input image
|
80 |
+
input_image = Image.open(input_image.stream)
|
81 |
+
|
82 |
+
# Process comparison images
|
83 |
+
comparison_images_pil = [Image.open(img.stream) for img in comparison_images]
|
84 |
+
|
85 |
+
similar_images = compare_images(input_image, comparison_images_pil)
|
86 |
+
|
87 |
+
return render_template('result.html', images=similar_images)
|
88 |
+
|
89 |
+
except Exception as e:
|
90 |
+
# Print the error details for debugging
|
91 |
+
print(f"Error: {e}")
|
92 |
+
return "An error occurred. Please try again."
|
93 |
+
|
94 |
+
return render_template('index.html')
|
95 |
+
|
96 |
+
if __name__ == '__main__':
|
97 |
+
app.run(debug=True)
|
templates/index.html
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Image Comparison</title>
|
7 |
+
<style>
|
8 |
+
body {
|
9 |
+
font-family: Arial, sans-serif;
|
10 |
+
background-color: #333;
|
11 |
+
color: #fff;
|
12 |
+
margin: 0;
|
13 |
+
padding: 0;
|
14 |
+
}
|
15 |
+
.container {
|
16 |
+
width: 80%;
|
17 |
+
margin: auto;
|
18 |
+
overflow: hidden;
|
19 |
+
padding: 20px;
|
20 |
+
}
|
21 |
+
h1 {
|
22 |
+
text-align: center;
|
23 |
+
color: #4CAF50;
|
24 |
+
}
|
25 |
+
form {
|
26 |
+
background: #444;
|
27 |
+
padding: 20px;
|
28 |
+
border-radius: 8px;
|
29 |
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
30 |
+
}
|
31 |
+
label, input {
|
32 |
+
display: block;
|
33 |
+
margin: 10px 0;
|
34 |
+
}
|
35 |
+
input[type="file"] {
|
36 |
+
margin-top: 5px;
|
37 |
+
}
|
38 |
+
input[type="submit"] {
|
39 |
+
background: #4CAF50;
|
40 |
+
color: white;
|
41 |
+
border: none;
|
42 |
+
padding: 10px 20px;
|
43 |
+
cursor: pointer;
|
44 |
+
border-radius: 4px;
|
45 |
+
}
|
46 |
+
input[type="submit"]:hover {
|
47 |
+
background: #45a049;
|
48 |
+
}
|
49 |
+
.threshold-container {
|
50 |
+
margin-top: 20px;
|
51 |
+
}
|
52 |
+
.threshold-container input {
|
53 |
+
width: 100px;
|
54 |
+
}
|
55 |
+
</style>
|
56 |
+
</head>
|
57 |
+
<body>
|
58 |
+
<div class="container">
|
59 |
+
<h1>Upload Images for Comparison</h1>
|
60 |
+
<form action="/" method="POST" enctype="multipart/form-data">
|
61 |
+
<label for="input_image">Upload an image to compare:</label>
|
62 |
+
<input type="file" id="input_image" name="input_image" accept="image/*" required>
|
63 |
+
|
64 |
+
<label for="comparison_images">Upload images for comparison (select multiple):</label>
|
65 |
+
<input type="file" id="comparison_images" name="comparison_images" accept="image/*" multiple required>
|
66 |
+
|
67 |
+
<div class="threshold-container">
|
68 |
+
<label for="similarity_threshold">Similarity Threshold (0.0 - 1.0):</label>
|
69 |
+
<input type="number" id="similarity_threshold" name="similarity_threshold" step="0.01" min="0" max="1" value="0.8">
|
70 |
+
</div>
|
71 |
+
|
72 |
+
<input type="submit" value="Submit">
|
73 |
+
</form>
|
74 |
+
</div>
|
75 |
+
</body>
|
76 |
+
</html>
|
templates/result.html
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Similar Images</title>
|
7 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
8 |
+
</head>
|
9 |
+
<body>
|
10 |
+
<h1>Similar Images</h1>
|
11 |
+
<div class="gallery">
|
12 |
+
{% for image in images %}
|
13 |
+
<div class="image-item">
|
14 |
+
<img src="{{ url_for('static', filename=image) }}" alt="Similar Image">
|
15 |
+
</div>
|
16 |
+
{% endfor %}
|
17 |
+
</div>
|
18 |
+
<a href="/">Try Again</a>
|
19 |
+
</body>
|
20 |
+
</html>
|
test_folder/download (1).jpeg
ADDED
test_folder/download (10).jpeg
ADDED
test_folder/download (11).jpeg
ADDED
test_folder/download (12).jpeg
ADDED
test_folder/download (13).jpeg
ADDED
test_folder/download (14).jpeg
ADDED
test_folder/download (15).jpeg
ADDED
test_folder/download (16).jpeg
ADDED
test_folder/download (17).jpeg
ADDED
test_folder/download (18).jpeg
ADDED
test_folder/download (19).jpeg
ADDED
test_folder/download (2).jpeg
ADDED
test_folder/download (20).jpeg
ADDED
test_folder/download (21).jpeg
ADDED
test_folder/download (22).jpeg
ADDED
test_folder/download (23).jpeg
ADDED
test_folder/download (24).jpeg
ADDED
test_folder/download (25).jpeg
ADDED
test_folder/download (26).jpeg
ADDED
test_folder/download (27).jpeg
ADDED
test_folder/download (28).jpeg
ADDED
test_folder/download (29).jpeg
ADDED
test_folder/download (3).jpeg
ADDED
test_folder/download (30).jpeg
ADDED
test_folder/download (4).jpeg
ADDED
test_folder/download (5).jpeg
ADDED
test_folder/download (6).jpeg
ADDED
test_folder/download (7).jpeg
ADDED
test_folder/download (8).jpeg
ADDED
test_folder/download (9).jpeg
ADDED
test_folder/download.jpeg
ADDED
test_folder/flowers/download (10).jpeg
ADDED
test_folder/flowers/download (11).jpeg
ADDED
test_folder/flowers/download (12).jpeg
ADDED
test_folder/flowers/download (13).jpeg
ADDED
test_folder/flowers/download (14).jpeg
ADDED
test_folder/flowers/download (15).jpeg
ADDED
test_folder/flowers/download (16).jpeg
ADDED
test_folder/flowers/download (6).jpeg
ADDED
test_folder/flowers/download (7).jpeg
ADDED
test_folder/flowers/download (8).jpeg
ADDED
test_folder/flowers/download (9).jpeg
ADDED
test_folder/flowers/images (1).jpeg
ADDED
test_folder/flowers/images (2).jpeg
ADDED
test_folder/flowers/images.jpeg
ADDED
test_folder/images (1).jpeg
ADDED
test_folder/images (2).jpeg
ADDED