| import cv2 |
| import gradio as gr |
| import numpy as np |
| import matplotlib.pyplot as plt |
| from sklearn.model_selection import KFold |
| from skimage.feature import graycomatrix, graycoprops |
| from sklearn.neighbors import KNeighborsClassifier |
| from sklearn.metrics import accuracy_score, classification_report, confusion_matrix |
| import pandas as pd |
| from sklearn.model_selection import GridSearchCV |
| from sklearn.neighbors import KNeighborsClassifier |
| from skimage.feature import local_binary_pattern |
| |
|
|
|
|
| |
| def plot_features(features, title): |
| plt.figure(figsize=(10, 6)) |
| for i, feature in enumerate(features.T): |
| plt.plot(feature, label=f"Feature {i+1}") |
| plt.title(title) |
| plt.legend() |
| plt.show() |
|
|
|
|
| |
| grass_dir = "images/Grass/Train_Grass" |
| wood_dir = "images/Wood/Train_Wood" |
|
|
| |
| RADIUS = 1 |
| N_POINTS = 12 * RADIUS |
| TARGET_SIZE = (30, 30) |
|
|
| |
| distances = [1] |
| angles = [0] |
|
|
|
|
| def load_and_convert_images(directory): |
| """Load images from a directory and convert them to grayscale.""" |
| dataset = [] |
| for filename in os.listdir(directory): |
| if filename.endswith((".jpg", ".png", ".jpeg")): |
| img_path = os.path.join(directory, filename) |
| img = cv2.imread(img_path) |
| if img is not None: |
| |
| gray_image = cv2.cvtColor( |
| img, cv2.COLOR_BGR2GRAY |
| ) |
| resized_image = cv2.resize( |
| gray_image, TARGET_SIZE, interpolation=cv2.INTER_AREA |
| ) |
| dataset.append(resized_image) |
| return dataset |
|
|
|
|
| def calc_glcm_features(images): |
| features = [] |
| for img in images: |
| glcm = graycomatrix(img, distances, angles, symmetric=True, normed=True) |
|
|
| contrast = graycoprops(glcm, "contrast")[0, 0] |
| dissimilarity = graycoprops(glcm, "dissimilarity")[0, 0] |
| homogeneity = graycoprops(glcm, "homogeneity")[0, 0] |
| energy = graycoprops(glcm, "energy")[0, 0] |
| correlation = graycoprops(glcm, "correlation")[0, 0] |
|
|
| features.append([contrast, dissimilarity, homogeneity, energy, correlation]) |
| return features |
|
|
|
|
| |
| def extract_lbp_features(images): |
| """Extract LBP features from a list of images.""" |
|
|
| lbp_features = [] |
| for image in images: |
| lbp = local_binary_pattern(image, N_POINTS, RADIUS, method="uniform") |
| n_bins = int(lbp.max() + 1) |
| lbp_hist, _ = np.histogram(lbp, bins=n_bins, range=(0, n_bins), density=True) |
| lbp_features.append(lbp_hist) |
| return lbp_features |
|
|
|
|
| |
| grass_dataset = load_and_convert_images(grass_dir) |
| wood_dataset = load_and_convert_images(wood_dir) |
|
|
| |
| grass_labels = [0] * len(grass_dataset) |
| wood_labels = [1] * len(wood_dataset) |
|
|
|
|
| |
| grass_glcm_features = calc_glcm_features(grass_dataset) |
| wood_glcm_features = calc_glcm_features(wood_dataset) |
|
|
|
|
| grass_lbp_features = extract_lbp_features(grass_dataset) |
| wood_lbp_features = extract_lbp_features(wood_dataset) |
|
|
| |
|
|
| |
| plot_features(np.array(grass_glcm_features), "GLCM Features for Grass Images") |
| plot_features(np.array(wood_glcm_features), "GLCM Features for Wood Images") |
|
|
| |
| plot_features(np.array(grass_lbp_features), "LBP Features for Grass Images") |
| plot_features(np.array(wood_lbp_features), "LBP Features for Wood Images") |
|
|
|
|
| |
|
|
| |
| glcm_features = grass_glcm_features + wood_glcm_features |
| glcm_labels = grass_labels + wood_labels |
|
|
| |
| glcm_features = np.array(glcm_features) |
|
|
|
|
| |
| lbp_features = grass_lbp_features + wood_lbp_features |
| lbp_labels = grass_labels + wood_labels |
|
|
| |
| lbp_features = np.array(lbp_features) |
|
|
| print("block 2 run") |
|
|
| num_grass = len(grass_dataset) |
| num_wood = len(wood_dataset) |
|
|
| |
| y = np.array([0] * num_grass + [1] * num_wood) |
|
|
| |
| k = 5 |
| kf = KFold(n_splits=k, shuffle=True, random_state=42) |
|
|
| |
| glcm_accuracy_list = [] |
| lbp_accuracy_list = [] |
|
|
| |
| param_grid = {"n_neighbors": [3, 5, 7], "p": [1, 2]} |
|
|
| |
| glcm_knn = KNeighborsClassifier() |
| glcm_grid_search = GridSearchCV(glcm_knn, param_grid, cv=kf) |
| glcm_grid_search.fit(glcm_features, y) |
|
|
| print("Best parameters for GLCM KNN:", glcm_grid_search.best_params_) |
|
|
| |
| for train_index, test_index in kf.split(glcm_features): |
| x_train, x_test = glcm_features[train_index], glcm_features[test_index] |
| y_train, y_test = y[train_index], y[test_index] |
|
|
| glcm_classifier = KNeighborsClassifier( |
| n_neighbors=glcm_grid_search.best_params_["n_neighbors"] |
| ) |
| glcm_classifier.fit(x_train, y_train) |
| y_pred = glcm_classifier.predict(x_test) |
|
|
| accuracy = accuracy_score(y_test, y_pred) |
| glcm_accuracy_list.append(accuracy) |
|
|
| |
|
|
| |
| |
|
|
| |
| print(f"GLCM Cross-validated accuracy: {np.mean(glcm_accuracy_list) * 100:.2f}%") |
|
|
| |
| lbp_knn = KNeighborsClassifier() |
| lbp_grid_search = GridSearchCV(lbp_knn, param_grid, cv=kf) |
| lbp_grid_search.fit(lbp_features, y) |
|
|
| print("Best parameters for LBP KNN:", lbp_grid_search.best_params_) |
|
|
| |
| for train_index, test_index in kf.split(lbp_features): |
| x_train, x_test = lbp_features[train_index], lbp_features[test_index] |
| y_train, y_test = y[train_index], y[test_index] |
|
|
| lbp_classifier = KNeighborsClassifier( |
| n_neighbors=lbp_grid_search.best_params_["n_neighbors"] |
| ) |
| lbp_classifier.fit(x_train, y_train) |
| y_pred = lbp_classifier.predict(x_test) |
|
|
| accuracy = accuracy_score(y_test, y_pred) |
| lbp_accuracy_list.append(accuracy) |
|
|
| |
|
|
| |
| |
|
|
| |
| print(f"LBP Cross-validated accuracy: {np.mean(lbp_accuracy_list) * 100:.2f}%") |
|
|
|
|
| def classify_texture(image, algorithm): |
| |
| resized_image = cv2.resize(image, TARGET_SIZE, interpolation=cv2.INTER_AREA) |
| gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY) |
|
|
| |
| if algorithm == "GLCM": |
| features = calc_glcm_features([gray_image]) |
| prediction = glcm_grid_search.predict(features) |
| elif algorithm == "LBP": |
| features = extract_lbp_features([gray_image]) |
| prediction = lbp_grid_search.predict(features) |
| else: |
| raise ValueError(f"Algorithm '{algorithm}' is not recognized.") |
|
|
| return "Grass" if prediction[0] == 0 else "Wood" |
|
|
|
|
| |
| def highlight_texture(image, result): |
| overlay = image.copy() |
| if result == "Grass": |
| overlay[:, :] = [0, 255, 0] |
| else: |
| overlay[:, :] = [165, 42, 42] |
| return overlay |
|
|
|
|
| |
| def classify_uploaded_image(image, algorithm): |
| |
| image = np.array(image, dtype=np.uint8) |
|
|
| |
| result = classify_texture(image, algorithm) |
|
|
| return result |
|
|
|
|
| |
| iface = gr.Interface( |
| fn=classify_uploaded_image, |
| inputs=[ |
| gr.Image( |
| type="numpy", label="Upload an Image" |
| ), |
| gr.Dropdown(choices=["GLCM", "LBP"], label="Algorithm"), |
| ], |
| outputs="text", |
| title="Texture Classification", |
| ) |
|
|
| |
| iface.launch() |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
|
|
| |
| test_grass_image = cv2.imread("grass.jpg") |
| test_wood_image = cv2.imread("wood.jpg") |
|
|
| print("Testing with Grass Image Prediction:", classify_texture(test_grass_image, "LBP")) |
| print("Testing with Wood Image Prediction:", classify_texture(test_wood_image, "LBP")) |
|
|