LAB-2 / app.py
nnibras's picture
Update app.py
cceec7c verified
raw
history blame
9.82 kB
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
#import os
# Visualize GLCM features for grass and wood
def plot_features(features, title):
plt.figure(figsize=(10, 6))
for i, feature in enumerate(features.T): # Transpose to plot feature by feature
plt.plot(feature, label=f"Feature {i+1}")
plt.title(title)
plt.legend()
plt.show()
# Define directories for grass and wood images
grass_dir = "images/Grass/Train_Grass"
wood_dir = "images/Wood/Train_Wood"
# Constants for LBP
RADIUS = 1
N_POINTS = 12 * RADIUS
TARGET_SIZE = (30, 30)
# for GLCM
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) # Construct full image path
img = cv2.imread(img_path) # Read the image
if img is not None:
# resized_image = cv2.resize(img, TARGET_SIZE, interpolation=cv2.INTER_AREA) #resize the images
gray_image = cv2.cvtColor(
img, cv2.COLOR_BGR2GRAY
) # Convert to grayscale
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
# Function to extract LBP features from an image
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
# Load datasets
grass_dataset = load_and_convert_images(grass_dir)
wood_dataset = load_and_convert_images(wood_dir)
# Create labels (0 for grass, 1 for wood)
grass_labels = [0] * len(grass_dataset) # Label all grass images as 0
wood_labels = [1] * len(wood_dataset) # Label all wood images as 1
# Calculate features
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)
####TESTING...
# GLCM features for grass and wood
plot_features(np.array(grass_glcm_features), "GLCM Features for Grass Images")
plot_features(np.array(wood_glcm_features), "GLCM Features for Wood Images")
# LBP features for grass and wood
plot_features(np.array(grass_lbp_features), "LBP Features for Grass Images")
plot_features(np.array(wood_lbp_features), "LBP Features for Wood Images")
###MATPLOTLIB....
# Combine labels and features for GLCM classifier
glcm_features = grass_glcm_features + wood_glcm_features
glcm_labels = grass_labels + wood_labels
# Convert to numpy array
glcm_features = np.array(glcm_features)
# Prepare labels and features for LBP classifier
lbp_features = grass_lbp_features + wood_lbp_features
lbp_labels = grass_labels + wood_labels
# Convert to numpy array
lbp_features = np.array(lbp_features)
print("block 2 run")
num_grass = len(grass_dataset) # Number of grass images
num_wood = len(wood_dataset) # Number of wood images
# Create the labels: 0 for grass, 1 for wood
y = np.array([0] * num_grass + [1] * num_wood)
# Define KFold cross-validation
k = 5
kf = KFold(n_splits=k, shuffle=True, random_state=42)
# Store results for GLCM and LBP classifiers
glcm_accuracy_list = []
lbp_accuracy_list = []
# Parameter tuning using GridSearchCV for KNN classifier
param_grid = {"n_neighbors": [3, 5, 7], "p": [1, 2]}
# GLCM Classifier Training and Evaluation
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_)
# Perform cross-validation and evaluate GLCM classifier
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)
# Optionally: Print confusion matrix and precision
# print(f"Confusion Matrix for GLCM Fold:\n{confusion_matrix(y_test, y_pred)}")
# print(f"Classification Report for GLCM Fold:\n{classification_report(y_test, y_pred, zero_division=0)}")
# Print overall GLCM accuracy
print(f"GLCM Cross-validated accuracy: {np.mean(glcm_accuracy_list) * 100:.2f}%")
# LBP Classifier Training and Evaluation
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_)
# Perform cross-validation and evaluate LBP classifier
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)
# Optionally: Print confusion matrix and precision
# print(f"Confusion Matrix for LBP Fold:\n{confusion_matrix(y_test, y_pred)}")
# print(f"Classification Report for LBP Fold:\n{classification_report(y_test, y_pred, zero_division=0)}")
# Print overall LBP accuracy
print(f"LBP Cross-validated accuracy: {np.mean(lbp_accuracy_list) * 100:.2f}%")
def classify_texture(image, algorithm):
# Resize and convert the image to grayscale
resized_image = cv2.resize(image, TARGET_SIZE, interpolation=cv2.INTER_AREA)
gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY) # Convert to grayscale
# Select the feature extraction method based on the algorithm
if algorithm == "GLCM":
features = calc_glcm_features([gray_image]) # Use parentheses, pass as a list
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"
# Function to highlight regions
def highlight_texture(image, result):
overlay = image.copy()
if result == "Grass":
overlay[:, :] = [0, 255, 0] # Highlight grass regions in green
else:
overlay[:, :] = [165, 42, 42] # Highlight wood regions in brown
return overlay
# Define the Gradio interface
def classify_uploaded_image(image, algorithm):
# Convert the uploaded image to a format that OpenCV can process
image = np.array(image, dtype=np.uint8) # Ensure correct type
# Call the classify_texture function
result = classify_texture(image, algorithm)
return result
# Gradio Interface Setup
iface = gr.Interface(
fn=classify_uploaded_image,
inputs=[
gr.Image(
type="numpy", label="Upload an Image"
), # Image input, passing as NumPy array
gr.Dropdown(choices=["GLCM", "LBP"], label="Algorithm"),
],
outputs="text",
title="Texture Classification",
)
# Launch the interface
iface.launch()
# # Create Gradio interface
# iface = gr.Interface(
# fn=lambda image, algorithm: (result := classify_texture(image, algorithm), highlight_texture(image, result)),
# inputs=[
# gr.Image(type='numpy', label="Upload Image"),
# gr.Radio(choices=['GLCM', 'LBP'], label="Select Algorithm")
# ],
# outputs=[gr.Textbox(label="Classification Result"), gr.Image(label="Highlighted Result")],
# title="Texture Classification",
# description="Upload an image and select the classification algorithm (GLCM or LBP). The result will show the classification and highlight the detected texture."
# )
# # Launch the interface
# iface.launch()
# Example of testing with a specific image
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"))