CoolFace
Apppublic

pidoko/textureClassification

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py176 linesDownload Raw Back to root
1import logging2from typing import Tuple3import numpy as np4import pandas as pd5import cv26import matplotlib.pyplot as plt7import seaborn as sns8from pathlib import Path9from sklearn.model_selection import train_test_split, GridSearchCV10from sklearn.preprocessing import StandardScaler11from sklearn.ensemble import RandomForestClassifier12from sklearn.svm import SVC13from sklearn.neighbors import KNeighborsClassifier14from sklearn.linear_model import LogisticRegression15from sklearn.metrics import accuracy_score, classification_report, confusion_matrix16import gradio as gr17from config import OUTPUT_DIR, IMAGE_SIZE, DISTANCES, ANGLES, LBP_RADIUS, LBP_POINTS, LBP_METHOD18 19# Setup Logging20logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")21 22# Paths to feature datasets23glcm_csv_path = Path(OUTPUT_DIR) / "texture_features_glcm.csv"24lbp_csv_path = Path(OUTPUT_DIR) / "texture_features_lbp.csv"25 26 27def load_datasets() -> Tuple[pd.DataFrame, pd.DataFrame]:28    """Load GLCM and LBP datasets separately with validation."""29    if not glcm_csv_path.exists() or not lbp_csv_path.exists():30        raise FileNotFoundError("One or both dataset files (GLCM or LBP) are missing.")31 32    df_glcm = pd.read_csv(glcm_csv_path)33    df_lbp = pd.read_csv(lbp_csv_path)34 35    return df_glcm, df_lbp36 37 38def preprocess_data(df: pd.DataFrame):39    """Splits data into train/test sets and applies standardization."""40    X = df.drop(columns=["label"])41    y = df["label"]42 43    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)44 45    scaler = StandardScaler()46    X_train_scaled = scaler.fit_transform(X_train)47    X_test_scaled = scaler.transform(X_test)48 49    return X_train_scaled, X_test_scaled, y_train, y_test, scaler50 51 52def train_models(X_train, y_train):53    """Trains multiple classifiers using GridSearchCV."""54    param_grids = {55        "Random Forest": {56            "model": RandomForestClassifier(random_state=42),57            "params": {"n_estimators": [50, 100, 200], "max_depth": [None, 10, 20]},58        },59        "SVM": {60            "model": SVC(random_state=42),61            "params": {"C": [0.1, 1, 10], "kernel": ["linear", "rbf"]},62        },63        "k-NN": {64            "model": KNeighborsClassifier(),65            "params": {"n_neighbors": [3, 5, 7], "weights": ["uniform", "distance"]},66        },67        "Logistic Regression": {68            "model": LogisticRegression(max_iter=1000, random_state=42),69            "params": {"C": [0.1, 1, 10]},70        },71    }72 73    best_models = {}74    confusion_matrices = {}75 76    for name, config in param_grids.items():77        logging.info(f"Training {name}...")78        grid_search = GridSearchCV(config["model"], config["params"], cv=5, scoring="accuracy", n_jobs=-1)79        grid_search.fit(X_train, y_train)80 81        best_models[name] = grid_search.best_estimator_82 83    return best_models84 85 86def plot_confusion_matrices(y_test, models, X_test, filename_prefix):87    """Plots and saves confusion matrices for multiple models."""88    for name, model in models.items():89        y_pred = model.predict(X_test)90        cm = confusion_matrix(y_test, y_pred)91 92        plt.figure(figsize=(6, 5))93        sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", xticklabels=np.unique(y_test), yticklabels=np.unique(y_test))94        plt.title(f"Confusion Matrix - {name}")95        plt.xlabel("Predicted")96        plt.ylabel("Actual")97 98        output_path = Path(OUTPUT_DIR) / f"{filename_prefix}_conf_matrix_{name}.png"99        plt.savefig(output_path)100        plt.close()101 102        logging.info(f"Confusion matrix for {name} saved to {output_path}")103 104 105def classify_texture(image, feature_type, model_name):106    """Classifies an input image using the selected feature type and model."""107    image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)108    image = cv2.equalizeHist(image)109    image = cv2.resize(image, IMAGE_SIZE)110 111    if feature_type == "GLCM":112        from feature import compute_glcm_features  # Import only when needed113 114        features = compute_glcm_features(image).reshape(1, -1)115        features = scaler_glcm.transform(features)116        prediction = best_models_glcm[model_name].predict(features)[0]117 118    elif feature_type == "LBP":119        from feature import compute_lbp_features120 121        features = compute_lbp_features(image).reshape(1, -1)122        features = scaler_lbp.transform(features)123        prediction = best_models_lbp[model_name].predict(features)[0]124 125    return prediction126 127try:128    # Load datasets129    df_glcm, df_lbp = load_datasets()130 131    # Preprocess GLCM and LBP datasets132    X_train_glcm, X_test_glcm, y_train_glcm, y_test_glcm, scaler_glcm = preprocess_data(df_glcm)133    X_train_lbp, X_test_lbp, y_train_lbp, y_test_lbp, scaler_lbp = preprocess_data(df_lbp)134 135    # Train models separately for GLCM and LBP136    best_models_glcm = train_models(X_train_glcm, y_train_glcm)137    best_models_lbp = train_models(X_train_lbp, y_train_lbp)138 139    # Plot confusion matrices140    plot_confusion_matrices(y_test_glcm, best_models_glcm, X_test_glcm, "GLCM")141    plot_confusion_matrices(y_test_lbp, best_models_lbp, X_test_lbp, "LBP")142 143    # Define Hugging Face App Title144    title = "Texture Classification Using GLCM and LBP"145 146    title += "\n\nUpload image of a texture, choose a feature extraction method, and pick a classifier to predict."147 148    title += "\n\nAppropriate image has little to no noise (only relevant texture)"149 150    # Define path to sample images151    sample_images = [152        ["sample_images/wood1.jpg", "GLCM", "SVM"],153        ["sample_images/brick1.jpg", "LBP", "Random Forest"],154        ["sample_images/stone1.jpg", "GLCM", "k-NN"]155    ]156    157    # Gradio Interface158    interface = gr.Interface(159        fn=classify_texture,160        inputs=[161            gr.Image(type="numpy"),162            gr.Radio(["GLCM", "LBP"], label="Feature Type"),163            gr.Dropdown(choices=list(best_models_glcm.keys()), label="Select Classifier"),164        ],165        outputs=gr.Label(),166        title=title,167        examples=sample_images168    )169 170    logging.info("Launching Gradio interface...")171    interface.launch()172 173except Exception as e:174    logging.error(f"An error occurred: {e}")175    exit(1)176