fatima02 commited on
Commit
fe8cd4e
·
verified ·
1 Parent(s): e21fb8a

Upload 4 files

Browse files
Files changed (2) hide show
  1. gradio_app.py +250 -0
  2. requirements.txt +8 -8
gradio_app.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import cv2
4
+ from tensorflow.keras.applications import ResNet50
5
+ from tensorflow.keras.applications.resnet50 import preprocess_input
6
+ from tensorflow.keras.preprocessing import image
7
+ from skimage.metrics import structural_similarity as ssim
8
+ import os
9
+ import tempfile
10
+ from PIL import Image
11
+
12
+ class ImageCharacterClassifier:
13
+ def __init__(self, similarity_threshold=0.5):
14
+ # Initialize ResNet50 model without top classification layer
15
+ self.model = ResNet50(weights='imagenet', include_top=False, pooling='avg')
16
+ self.similarity_threshold = similarity_threshold
17
+
18
+ def load_and_preprocess_image(self, image_path, target_size=(224, 224)):
19
+ # Load and preprocess image for ResNet50
20
+ img = image.load_img(image_path, target_size=target_size)
21
+ img_array = image.img_to_array(img)
22
+ img_array = np.expand_dims(img_array, axis=0)
23
+ img_array = preprocess_input(img_array)
24
+ return img_array
25
+
26
+ def extract_features(self, image_path):
27
+ # Extract deep features using ResNet50
28
+ preprocessed_img = self.load_and_preprocess_image(image_path)
29
+ features = self.model.predict(preprocessed_img)
30
+ return features
31
+
32
+ def calculate_ssim(self, img1_path, img2_path):
33
+ # Calculate SSIM between two images
34
+ img1 = cv2.imread(img1_path)
35
+ img2 = cv2.imread(img2_path)
36
+
37
+ if img1 is None or img2 is None:
38
+ return 0.0
39
+
40
+ # Convert to grayscale if images are in color
41
+ if len(img1.shape) == 3:
42
+ img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
43
+ if len(img2.shape) == 3:
44
+ img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
45
+
46
+ # Resize images to same dimensions
47
+ img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
48
+
49
+ score = ssim(img1, img2)
50
+ return score
51
+
52
+ def process_images(reference_image, comparison_images, similarity_threshold):
53
+ try:
54
+ if reference_image is None:
55
+ return "Please upload a reference image.", []
56
+
57
+ if not comparison_images:
58
+ return "Please upload comparison images.", []
59
+
60
+ # Create temporary directory for saving uploaded files
61
+ with tempfile.TemporaryDirectory() as temp_dir:
62
+ # Initialize classifier with the threshold
63
+ classifier = ImageCharacterClassifier(similarity_threshold=similarity_threshold)
64
+
65
+ # Save reference image
66
+ ref_path = os.path.join(temp_dir, "reference.jpg")
67
+ cv2.imwrite(ref_path, cv2.cvtColor(reference_image, cv2.COLOR_RGB2BGR))
68
+
69
+ results = []
70
+ html_output = """
71
+ <div style='text-align: center; margin-bottom: 20px;'>
72
+ <h2 style='color: #2c3e50;'>Results</h2>
73
+ <p style='color: #7f8c8d;'>Reference image compared with uploaded images</p>
74
+ </div>
75
+ """
76
+
77
+ # Extract reference features once
78
+ ref_features = classifier.extract_features(ref_path)
79
+
80
+ # Process each comparison image
81
+ for i, comp_image in enumerate(comparison_images):
82
+ try:
83
+ # Save comparison image
84
+ comp_path = os.path.join(temp_dir, f"comparison_{i}.jpg")
85
+
86
+ try:
87
+ # First attempt: Try using PIL
88
+ with Image.open(comp_image.name) as img:
89
+ img = img.convert('RGB')
90
+ img_array = np.array(img)
91
+ cv2.imwrite(comp_path, cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR))
92
+ except Exception as e1:
93
+ print(f"PIL failed: {str(e1)}")
94
+ # Second attempt: Try using OpenCV directly
95
+ img = cv2.imread(comp_image.name)
96
+ if img is not None:
97
+ cv2.imwrite(comp_path, img)
98
+ else:
99
+ raise ValueError(f"Could not read image: {comp_image.name}")
100
+
101
+ # Calculate SSIM for structural similarity
102
+ ssim_score = classifier.calculate_ssim(ref_path, comp_path)
103
+
104
+ # Extract features for physical feature comparison
105
+ comp_features = classifier.extract_features(comp_path)
106
+
107
+ # Calculate feature differences
108
+ feature_diff = np.abs(ref_features - comp_features)
109
+ max_feature_diff = np.max(feature_diff)
110
+
111
+ # Determine similarity based on max feature difference
112
+ is_similar = max_feature_diff > 6.0
113
+
114
+ if is_similar:
115
+ reason = "Physical features match the reference image"
116
+ else:
117
+ reason = "Physical features don't match the reference image"
118
+
119
+ # Debug information
120
+ print(f"\nDebug for {os.path.basename(comp_image.name)}:")
121
+ print(f"SSIM Score: {ssim_score:.3f}")
122
+ print(f"Max Feature Difference: {max_feature_diff:.3f}")
123
+
124
+ # Create HTML output with improved styling and reason
125
+ status_color = "#27ae60" if is_similar else "#c0392b" # Green or Red
126
+ status_text = "SIMILAR" if is_similar else "NOT SIMILAR"
127
+ status_icon = "✓" if is_similar else "✗"
128
+
129
+ html_output += f"""
130
+ <div style='
131
+ margin: 15px 0;
132
+ padding: 15px;
133
+ border-radius: 8px;
134
+ background-color: {status_color}1a;
135
+ border: 2px solid {status_color};
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ '>
140
+ <div style='display: flex; align-items: center;'>
141
+ <span style='
142
+ font-size: 24px;
143
+ margin-right: 10px;
144
+ color: {status_color};
145
+ '>{status_icon}</span>
146
+ <div>
147
+ <span style='color: #2c3e50; font-weight: bold; display: block;'>
148
+ {os.path.basename(comp_image.name)}
149
+ </span>
150
+ <span style='color: {status_color}; font-size: 12px;'>
151
+ {reason}
152
+ </span>
153
+ </div>
154
+ </div>
155
+ <div style='
156
+ color: {status_color};
157
+ font-weight: bold;
158
+ font-size: 16px;
159
+ '>{status_text}</div>
160
+ </div>
161
+ """
162
+
163
+ # Read the processed image back for display
164
+ display_img = cv2.imread(comp_path)
165
+ if display_img is not None:
166
+ display_img = cv2.cvtColor(display_img, cv2.COLOR_BGR2RGB)
167
+ results.append(display_img)
168
+
169
+ except Exception as e:
170
+ print(f"Error processing {comp_image.name}: {str(e)}")
171
+ html_output += f"""
172
+ <div style='
173
+ margin: 15px 0;
174
+ padding: 15px;
175
+ border-radius: 8px;
176
+ background-color: #e74c3c1a;
177
+ border: 2px solid #e74c3c;
178
+ '>
179
+ <h3 style='color: #e74c3c; margin: 0;'>
180
+ Error processing: {os.path.basename(comp_image.name)}
181
+ </h3>
182
+ <p style='color: #e74c3c; margin: 5px 0 0 0;'>{str(e)}</p>
183
+ </div>
184
+ """
185
+
186
+ return html_output, results
187
+
188
+ except Exception as e:
189
+ print(f"Main error: {str(e)}")
190
+ return f"""
191
+ <div style='
192
+ padding: 15px;
193
+ border-radius: 8px;
194
+ background-color: #e74c3c1a;
195
+ border: 2px solid #e74c3c;
196
+ '>
197
+ <h3 style='color: #e74c3c; margin: 0;'>Error</h3>
198
+ <p style='color: #e74c3c; margin: 5px 0 0 0;'>{str(e)}</p>
199
+ </div>
200
+ """, []
201
+
202
+ # Update the interface creation
203
+ def create_interface():
204
+ with gr.Blocks() as interface:
205
+ gr.Markdown("# Image Similarity Classifier")
206
+ gr.Markdown("Upload a reference image and up to 10 comparison images to check similarity.")
207
+
208
+ with gr.Row():
209
+ with gr.Column():
210
+ reference_input = gr.Image(
211
+ label="Reference Image",
212
+ type="numpy",
213
+ image_mode="RGB"
214
+ )
215
+ comparison_input = gr.File(
216
+ label="Comparison Images (Upload up to 10)",
217
+ file_count="multiple",
218
+ file_types=["image"],
219
+ maximum=10
220
+ )
221
+ threshold_slider = gr.Slider(
222
+ minimum=0.0,
223
+ maximum=1.0,
224
+ value=0.5,
225
+ step=0.05,
226
+ label="Similarity Threshold"
227
+ )
228
+ submit_button = gr.Button("Compare Images", variant="primary")
229
+
230
+ with gr.Column():
231
+ output_html = gr.HTML(label="Results")
232
+ output_gallery = gr.Gallery(
233
+ label="Processed Images",
234
+ columns=5,
235
+ show_label=True,
236
+ height="auto"
237
+ )
238
+
239
+ submit_button.click(
240
+ fn=process_images,
241
+ inputs=[reference_input, comparison_input, threshold_slider],
242
+ outputs=[output_html, output_gallery]
243
+ )
244
+
245
+ return interface
246
+
247
+ # Launch the app
248
+ if __name__ == "__main__":
249
+ interface = create_interface()
250
+ interface.launch(share=True)
requirements.txt CHANGED
@@ -1,8 +1,8 @@
1
- tensorflow==2.10.0
2
- tensorflow-gpu==2.10.0
3
- keras==2.10.0
4
- numpy==1.23.5
5
- opencv-python==4.7.0.72
6
- scikit-image==0.19.3
7
- Pillow==9.3.0
8
- gradio==3.50.2
 
1
+ tensorflow==2.10.0
2
+ tensorflow-gpu==2.10.0
3
+ keras==2.10.0
4
+ numpy==1.23.5
5
+ opencv-python==4.7.0.72
6
+ scikit-image==0.19.3
7
+ Pillow==9.3.0
8
+ gradio==3.50.2