File size: 4,940 Bytes
63d22c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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()