File size: 4,921 Bytes
e06826c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# image_processing.py
import cv2
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from skimage.feature import graycomatrix, graycoprops, local_binary_pattern
import joblib
import warnings

warnings.filterwarnings("ignore")

# Load model and preprocessing tools
model = joblib.load("model.pkl")
label_encoder = joblib.load("label_encoder.pkl")
scaler = joblib.load("scaler.pkl")

# Preprocessing: Resize, apply CLAHE, sharpen
def preprocessing(single_image, count=1):
    single_image = cv2.resize(single_image, (256,256))
    rgb_image = cv2.cvtColor(single_image, cv2.COLOR_BGR2RGB)

    r, g, b = cv2.split(rgb_image)
    clahe = cv2.createCLAHE(clipLimit=0.4, tileGridSize=(8, 8))
    r_clahe = clahe.apply(r)
    g_clahe = clahe.apply(g)
    b_clahe = clahe.apply(b)
    clahe_image = cv2.merge((r_clahe, g_clahe, b_clahe))
    clahe_bgr = cv2.cvtColor(clahe_image, cv2.COLOR_RGB2BGR)

    blurred = cv2.GaussianBlur(clahe_bgr, (5, 5), 1.5)
    sharp = cv2.addWeighted(clahe_bgr, 1.5, blurred, -0.5, 0)

    return rgb_image, clahe_image, cv2.cvtColor(sharp, cv2.COLOR_BGR2RGB)

# RGB histogram plotting
def plot_rgb_histogram(image):
    color = ('b', 'g', 'r')
    fig, ax = plt.subplots()
    for i, col in enumerate(color):
        hist = cv2.calcHist([image], [i], None, [256], [0,256])
        ax.plot(hist, color=col)
    ax.set_title("RGB Histogram")
    ax.set_xlim([0, 256])
    return fig

# Extract features: GLCM, LBP, color, edge, etc.
def feature_extraction(image, return_df=True):
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    glcm = graycomatrix(gray, distances=[1], angles=[0], levels=256, symmetric=True, normed=True)
    contrast = graycoprops(glcm, 'contrast')[0, 0]
    correlation = graycoprops(glcm, 'correlation')[0, 0]
    energy = graycoprops(glcm, 'energy')[0, 0]
    homogeneity = graycoprops(glcm, 'homogeneity')[0, 0]

    lbp = local_binary_pattern(gray, P=8, R=1, method='uniform')
    lbp_mean = np.mean(lbp)

    mean_r = np.mean(image[:, :, 0])
    mean_g = np.mean(image[:, :, 1])
    mean_b = np.mean(image[:, :, 2])
    diff_black = ((1-(mean_r-255)/255) + (1-(mean_g-255)/255) + (1-(mean_b-255)/255))/3

    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)
    edge_count = np.sum(cv2.magnitude(sobelx, sobely) > 0)

    features = [contrast, correlation, energy, homogeneity, lbp_mean,
                mean_r, mean_g, mean_b, edge_count, diff_black]

    if return_df:
        df = pd.DataFrame([features], columns=[
            "Contrast", "Correlation", "Energy", "Homogeneity", "LBP_Mean",
            "Mean_R", "Mean_G", "Mean_B", "Edge_Count", "Black"
        ])
        return df
    else:
        return np.array([features])

# Predict class and confidence from image
def predict_image_class_with_features(image):
    _, _, sharp = preprocessing(image, count=0)
    features_df = feature_extraction(sharp)
    features_scaled = scaler.transform(features_df)
    prediction = model.predict(features_scaled)
    predicted_class = label_encoder.inverse_transform(prediction)[0]
    confidence = np.max(model.predict_proba(features_scaled))
    return features_df, predicted_class, confidence

# Segment image and classify each region
def segment_and_classify_regions(image, k_clusters=2):
    rgb_img, _, sharp_img = preprocessing(image)
    reshaped = sharp_img.reshape((-1, 3)).astype(np.float32)

    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
    _, labels, centers = cv2.kmeans(reshaped, k_clusters, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
    segmented = labels.flatten().reshape(sharp_img.shape[:2])

    output = image.copy()
    region_predictions = []

    for i in range(k_clusters):
        mask = (segmented == i).astype(np.uint8) * 255
        region = cv2.bitwise_and(sharp_img, sharp_img, mask=mask)

        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        if not contours:
            continue

        x, y, w, h = cv2.boundingRect(max(contours, key=cv2.contourArea))
        region_crop = region[y:y+h, x:x+w]

        if region_crop.size == 0:
            continue

        features_df = feature_extraction(region_crop)
        features_scaled = scaler.transform(features_df)
        prediction = model.predict(features_scaled)
        predicted_class = label_encoder.inverse_transform(prediction)[0]
        confidence = np.max(model.predict_proba(features_scaled))

        region_predictions.append({
            "class": predicted_class,
            "confidence": confidence,
            "bbox": (x, y, w, h)
        })

        cv2.rectangle(output, (x, y), (x+w, y+h), (0,255,0), 2)
        cv2.putText(output, f"{predicted_class} ({confidence*100:.1f}%)", (x, y-10), 
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1)

    return output, region_predictions