import gradio as gr import numpy as np import joblib # Import directly from joblib from sklearn.svm import LinearSVC from skimage.feature import local_binary_pattern, graycomatrix, graycoprops from PIL import Image IMAGE_SIZE_GLCM = 256 IMAGE_SIZE_LBP = 128 RADIUS = 1 N_POINTS = 8 * RADIUS LBP_METHOD = "uniform" def get_feature_vector(img, feature_type): img_gray = img.convert("L") if feature_type == "GLCM": img_resized = image_resize(img_gray, IMAGE_SIZE_GLCM) feature_vector = compute_glcm_histogram_pil(img_resized) else: img_resized = image_resize(img_gray, IMAGE_SIZE_LBP) feature_vector = get_lbp_hist(np.array(img_resized), N_POINTS, RADIUS, LBP_METHOD) return [feature_vector] def compute_glcm_histogram_pil(image, distances=[1], angles=[0], levels=8, symmetric=True): # Step 2: Convert the PIL image to a NumPy array image_np = np.array(image) # Step 3: Quantize the grayscale image to the specified number of levels (e.g., 256) image_np = (image_np * (levels - 1) / 255).astype(np.uint8) # Scale to desired levels # Step 4: Compute the GLCM using skimage's graycomatrix function glcm = graycomatrix(image_np, distances=distances, angles=angles, levels=levels, symmetric=symmetric, normed=True) # Extract GLCM properties homogeneity = graycoprops(glcm, 'homogeneity')[0, 0] correlation = graycoprops(glcm, 'correlation')[0, 0] # Create the feature vector feature_vector = np.array([homogeneity, correlation]) # feature_vector = np.array([contrast,homogeneity, correlation, energy, dissimilarity, asm, entropy]) return feature_vector def get_lbp_hist(gray_image, n_points, radius, method): # Step 3: Compute LBP for the image lbp = local_binary_pattern(gray_image, n_points, radius, method) # Step 4: Compute LBP histogram # The histogram will have 'n_points + 2' bins if using the 'uniform' method. lbp_hist, _ = np.histogram(lbp.ravel(), bins=np.arange(0, n_points + 3), range=(0, n_points + 2)) # Normalize the histogram lbp_hist = lbp_hist.astype("float") lbp_hist /= (lbp_hist.sum() + 1e-6) # Normalized histogram return lbp_hist def image_resize(img, n): # Crop the image to a square by finding the minimum dimension min_dimension = min(img.size) left = (img.width - min_dimension) / 2 top = (img.height - min_dimension) / 2 right = (img.width + min_dimension) / 2 bottom = (img.height + min_dimension) / 2 img = img.crop((left, top, right, bottom)) # Resize to 128x128 pixels img = img.resize((n, n)) return img def rgb_to_quantized_gray_pil(image, num_levels): """ Convert an RGB image to a quantized grayscale image using PIL. Parameters: - image: PIL Image object in grayscale format. - num_levels: Number of gray levels for quantization. Returns: - quantized_image: PIL Image object in quantized grayscale. """ # Convert the grayscale image to a NumPy array for manipulation gray_array = np.array(image) # Quantize the grayscale image to the specified number of gray levels max_val = 255 # Max value for an 8-bit grayscale image quantized_array = np.floor(gray_array / (max_val / (num_levels - 1))) * (max_val / (num_levels - 1)) quantized_array = quantized_array.astype(np.uint8) # Convert back to 8-bit values # Convert the quantized NumPy array back to a PIL Image quantized_image = Image.fromarray(quantized_array, mode="L") return quantized_image # Function to classify the image def classify(img, feature_type): # To load the model later loaded_model = joblib.load(feature_type + '_model.joblib') feature_vector = get_feature_vector(img, feature_type) # Make predictions with the loaded model label = loaded_model.predict(feature_vector) return f"{label[0]}" def main(): # Gradio interface with gr.Blocks() as interface: gr.Markdown("## Image Classifier") # Image upload input img_input = gr.Image(type="pil") # Dropdown for selecting classifier classifier_dropdown = gr.Dropdown(choices=["GLCM", "LBP"], label="Feature Vector Type") # Button for classification classify_button = gr.Button("Classify Image") # Output label output_label = gr.Textbox(label="Predicted Texture") # Set up interaction classify_button.click(fn=classify, inputs=[img_input, classifier_dropdown], outputs=output_label) # Launch the interface interface.launch() if __name__ == "__main__": main()