nnibras commited on
Commit
3884aa8
·
verified ·
1 Parent(s): 4d852d0

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +286 -0
  2. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import gradio as gr
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ from sklearn.model_selection import KFold
6
+ from skimage.feature import graycomatrix, graycoprops
7
+ from sklearn.neighbors import KNeighborsClassifier
8
+ from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
9
+ import pandas as pd
10
+ from sklearn.model_selection import GridSearchCV
11
+ from sklearn.neighbors import KNeighborsClassifier
12
+ from skimage.feature import local_binary_pattern
13
+ import os
14
+
15
+
16
+ # Visualize GLCM features for grass and wood
17
+ def plot_features(features, title):
18
+ plt.figure(figsize=(10, 6))
19
+ for i, feature in enumerate(features.T): # Transpose to plot feature by feature
20
+ plt.plot(feature, label=f"Feature {i+1}")
21
+ plt.title(title)
22
+ plt.legend()
23
+ plt.show()
24
+
25
+
26
+ # Define directories for grass and wood images
27
+ grass_dir = "images/Grass/Train_Grass"
28
+ wood_dir = "images/Wood/Train_Wood"
29
+
30
+ # Constants for LBP
31
+ RADIUS = 1
32
+ N_POINTS = 12 * RADIUS
33
+ TARGET_SIZE = (30, 30)
34
+
35
+ # for GLCM
36
+ distances = [1]
37
+ angles = [0]
38
+
39
+
40
+ def load_and_convert_images(directory):
41
+ """Load images from a directory and convert them to grayscale."""
42
+ dataset = []
43
+ for filename in os.listdir(directory):
44
+ if filename.endswith((".jpg", ".png", ".jpeg")):
45
+ img_path = os.path.join(directory, filename) # Construct full image path
46
+ img = cv2.imread(img_path) # Read the image
47
+ if img is not None:
48
+ # resized_image = cv2.resize(img, TARGET_SIZE, interpolation=cv2.INTER_AREA) #resize the images
49
+ gray_image = cv2.cvtColor(
50
+ img, cv2.COLOR_BGR2GRAY
51
+ ) # Convert to grayscale
52
+ resized_image = cv2.resize(
53
+ gray_image, TARGET_SIZE, interpolation=cv2.INTER_AREA
54
+ )
55
+ dataset.append(resized_image)
56
+ return dataset
57
+
58
+
59
+ def calc_glcm_features(images):
60
+ features = []
61
+ for img in images:
62
+ glcm = graycomatrix(img, distances, angles, symmetric=True, normed=True)
63
+
64
+ contrast = graycoprops(glcm, "contrast")[0, 0]
65
+ dissimilarity = graycoprops(glcm, "dissimilarity")[0, 0]
66
+ homogeneity = graycoprops(glcm, "homogeneity")[0, 0]
67
+ energy = graycoprops(glcm, "energy")[0, 0]
68
+ correlation = graycoprops(glcm, "correlation")[0, 0]
69
+
70
+ features.append([contrast, dissimilarity, homogeneity, energy, correlation])
71
+ return features
72
+
73
+
74
+ # Function to extract LBP features from an image
75
+ def extract_lbp_features(images):
76
+ """Extract LBP features from a list of images."""
77
+
78
+ lbp_features = []
79
+ for image in images:
80
+ lbp = local_binary_pattern(image, N_POINTS, RADIUS, method="uniform")
81
+ n_bins = int(lbp.max() + 1)
82
+ lbp_hist, _ = np.histogram(lbp, bins=n_bins, range=(0, n_bins), density=True)
83
+ lbp_features.append(lbp_hist)
84
+ return lbp_features
85
+
86
+
87
+ # Load datasets
88
+ grass_dataset = load_and_convert_images(grass_dir)
89
+ wood_dataset = load_and_convert_images(wood_dir)
90
+
91
+ # Create labels (0 for grass, 1 for wood)
92
+ grass_labels = [0] * len(grass_dataset) # Label all grass images as 0
93
+ wood_labels = [1] * len(wood_dataset) # Label all wood images as 1
94
+
95
+
96
+ # Calculate features
97
+ grass_glcm_features = calc_glcm_features(grass_dataset)
98
+ wood_glcm_features = calc_glcm_features(wood_dataset)
99
+
100
+
101
+ grass_lbp_features = extract_lbp_features(grass_dataset)
102
+ wood_lbp_features = extract_lbp_features(wood_dataset)
103
+
104
+ ####TESTING...
105
+
106
+ # GLCM features for grass and wood
107
+ plot_features(np.array(grass_glcm_features), "GLCM Features for Grass Images")
108
+ plot_features(np.array(wood_glcm_features), "GLCM Features for Wood Images")
109
+
110
+ # LBP features for grass and wood
111
+ plot_features(np.array(grass_lbp_features), "LBP Features for Grass Images")
112
+ plot_features(np.array(wood_lbp_features), "LBP Features for Wood Images")
113
+
114
+
115
+ ###MATPLOTLIB....
116
+
117
+ # Combine labels and features for GLCM classifier
118
+ glcm_features = grass_glcm_features + wood_glcm_features
119
+ glcm_labels = grass_labels + wood_labels
120
+
121
+ # Convert to numpy array
122
+ glcm_features = np.array(glcm_features)
123
+
124
+
125
+ # Prepare labels and features for LBP classifier
126
+ lbp_features = grass_lbp_features + wood_lbp_features
127
+ lbp_labels = grass_labels + wood_labels
128
+
129
+ # Convert to numpy array
130
+ lbp_features = np.array(lbp_features)
131
+
132
+ print("block 2 run")
133
+
134
+ num_grass = len(grass_dataset) # Number of grass images
135
+ num_wood = len(wood_dataset) # Number of wood images
136
+
137
+ # Create the labels: 0 for grass, 1 for wood
138
+ y = np.array([0] * num_grass + [1] * num_wood)
139
+
140
+ # Define KFold cross-validation
141
+ k = 5
142
+ kf = KFold(n_splits=k, shuffle=True, random_state=42)
143
+
144
+ # Store results for GLCM and LBP classifiers
145
+ glcm_accuracy_list = []
146
+ lbp_accuracy_list = []
147
+
148
+ # Parameter tuning using GridSearchCV for KNN classifier
149
+ param_grid = {"n_neighbors": [3, 5, 7], "p": [1, 2]}
150
+
151
+ # GLCM Classifier Training and Evaluation
152
+ glcm_knn = KNeighborsClassifier()
153
+ glcm_grid_search = GridSearchCV(glcm_knn, param_grid, cv=kf)
154
+ glcm_grid_search.fit(glcm_features, y)
155
+
156
+ print("Best parameters for GLCM KNN:", glcm_grid_search.best_params_)
157
+
158
+ # Perform cross-validation and evaluate GLCM classifier
159
+ for train_index, test_index in kf.split(glcm_features):
160
+ x_train, x_test = glcm_features[train_index], glcm_features[test_index]
161
+ y_train, y_test = y[train_index], y[test_index]
162
+
163
+ glcm_classifier = KNeighborsClassifier(
164
+ n_neighbors=glcm_grid_search.best_params_["n_neighbors"]
165
+ )
166
+ glcm_classifier.fit(x_train, y_train)
167
+ y_pred = glcm_classifier.predict(x_test)
168
+
169
+ accuracy = accuracy_score(y_test, y_pred)
170
+ glcm_accuracy_list.append(accuracy)
171
+
172
+ # Optionally: Print confusion matrix and precision
173
+
174
+ # print(f"Confusion Matrix for GLCM Fold:\n{confusion_matrix(y_test, y_pred)}")
175
+ # print(f"Classification Report for GLCM Fold:\n{classification_report(y_test, y_pred, zero_division=0)}")
176
+
177
+ # Print overall GLCM accuracy
178
+ print(f"GLCM Cross-validated accuracy: {np.mean(glcm_accuracy_list) * 100:.2f}%")
179
+
180
+ # LBP Classifier Training and Evaluation
181
+ lbp_knn = KNeighborsClassifier()
182
+ lbp_grid_search = GridSearchCV(lbp_knn, param_grid, cv=kf)
183
+ lbp_grid_search.fit(lbp_features, y)
184
+
185
+ print("Best parameters for LBP KNN:", lbp_grid_search.best_params_)
186
+
187
+ # Perform cross-validation and evaluate LBP classifier
188
+ for train_index, test_index in kf.split(lbp_features):
189
+ x_train, x_test = lbp_features[train_index], lbp_features[test_index]
190
+ y_train, y_test = y[train_index], y[test_index]
191
+
192
+ lbp_classifier = KNeighborsClassifier(
193
+ n_neighbors=lbp_grid_search.best_params_["n_neighbors"]
194
+ )
195
+ lbp_classifier.fit(x_train, y_train)
196
+ y_pred = lbp_classifier.predict(x_test)
197
+
198
+ accuracy = accuracy_score(y_test, y_pred)
199
+ lbp_accuracy_list.append(accuracy)
200
+
201
+ # Optionally: Print confusion matrix and precision
202
+
203
+ # print(f"Confusion Matrix for LBP Fold:\n{confusion_matrix(y_test, y_pred)}")
204
+ # print(f"Classification Report for LBP Fold:\n{classification_report(y_test, y_pred, zero_division=0)}")
205
+
206
+ # Print overall LBP accuracy
207
+ print(f"LBP Cross-validated accuracy: {np.mean(lbp_accuracy_list) * 100:.2f}%")
208
+
209
+
210
+ def classify_texture(image, algorithm):
211
+ # Resize and convert the image to grayscale
212
+ resized_image = cv2.resize(image, TARGET_SIZE, interpolation=cv2.INTER_AREA)
213
+ gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY) # Convert to grayscale
214
+
215
+ # Select the feature extraction method based on the algorithm
216
+ if algorithm == "GLCM":
217
+ features = calc_glcm_features([gray_image]) # Use parentheses, pass as a list
218
+ prediction = glcm_grid_search.predict(features)
219
+ elif algorithm == "LBP":
220
+ features = extract_lbp_features([gray_image])
221
+ prediction = lbp_grid_search.predict(features)
222
+ else:
223
+ raise ValueError(f"Algorithm '{algorithm}' is not recognized.")
224
+
225
+ return "Grass" if prediction[0] == 0 else "Wood"
226
+
227
+
228
+ # Function to highlight regions
229
+ def highlight_texture(image, result):
230
+ overlay = image.copy()
231
+ if result == "Grass":
232
+ overlay[:, :] = [0, 255, 0] # Highlight grass regions in green
233
+ else:
234
+ overlay[:, :] = [165, 42, 42] # Highlight wood regions in brown
235
+ return overlay
236
+
237
+
238
+ # Define the Gradio interface
239
+ def classify_uploaded_image(image, algorithm):
240
+ # Convert the uploaded image to a format that OpenCV can process
241
+ image = np.array(image, dtype=np.uint8) # Ensure correct type
242
+
243
+ # Call the classify_texture function
244
+ result = classify_texture(image, algorithm)
245
+
246
+ return result
247
+
248
+
249
+ # Gradio Interface Setup
250
+ iface = gr.Interface(
251
+ fn=classify_uploaded_image,
252
+ inputs=[
253
+ gr.Image(
254
+ type="numpy", label="Upload an Image"
255
+ ), # Image input, passing as NumPy array
256
+ gr.Dropdown(choices=["GLCM", "LBP"], label="Algorithm"),
257
+ ],
258
+ outputs="text",
259
+ title="Texture Classification",
260
+ )
261
+
262
+ # Launch the interface
263
+ iface.launch()
264
+
265
+
266
+ # # Create Gradio interface
267
+ # iface = gr.Interface(
268
+ # fn=lambda image, algorithm: (result := classify_texture(image, algorithm), highlight_texture(image, result)),
269
+ # inputs=[
270
+ # gr.Image(type='numpy', label="Upload Image"),
271
+ # gr.Radio(choices=['GLCM', 'LBP'], label="Select Algorithm")
272
+ # ],
273
+ # outputs=[gr.Textbox(label="Classification Result"), gr.Image(label="Highlighted Result")],
274
+ # title="Texture Classification",
275
+ # description="Upload an image and select the classification algorithm (GLCM or LBP). The result will show the classification and highlight the detected texture."
276
+ # )
277
+
278
+ # # Launch the interface
279
+ # iface.launch()
280
+
281
+ # Example of testing with a specific image
282
+ test_grass_image = cv2.imread("grass.jpg")
283
+ test_wood_image = cv2.imread("wood.jpg")
284
+
285
+ print("Testing with Grass Image Prediction:", classify_texture(test_grass_image, "LBP"))
286
+ print("Testing with Wood Image Prediction:", classify_texture(test_wood_image, "LBP"))
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ opencv-python
2
+ gradio
3
+ numpy
4
+ matplotlib
5
+ scikit-learn
6
+ scikit-image
7
+ pandas