import cv2 import numpy as np from skimage.feature.texture import graycomatrix, graycoprops from skimage.feature import local_binary_pattern, hog from sklearn.svm import SVC from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.metrics import accuracy_score, classification_report, precision_score, confusion_matrix from sklearn.preprocessing import StandardScaler def rgb_histogram(image, bins=256): hist_features = [] for i in range(3): hist, _ = np.histogram(image[:, :, i], bins=bins, range=(0, 256), density=True) hist_features.append(hist) return np.concatenate(hist_features) def hu_moments(image): gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) moments = cv2.moments(gray) hu_moments = cv2.HuMoments(moments).flatten() return hu_moments def glcm_features(image, distances=[1], angles=[0], levels=256, symmetric=True, normed=True): gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) glcm = graycomatrix(gray, distances=distances, angles=angles, levels=levels, symmetric=symmetric, normed=normed) contrast = graycoprops(glcm, 'contrast').flatten() dissimilarity = graycoprops(glcm, 'dissimilarity').flatten() homogeneity = graycoprops(glcm, 'homogeneity').flatten() energy = graycoprops(glcm, 'energy').flatten() correlation = graycoprops(glcm, 'correlation').flatten() asm = graycoprops(glcm, 'ASM').flatten() return np.concatenate([contrast, dissimilarity, homogeneity, energy, correlation, asm]) def local_binary_pattern_features(image, P=8, R=1): gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) lbp = local_binary_pattern(gray, P, R, method='uniform') (hist, _) = np.histogram(lbp.ravel(), bins=np.arange(0, P + 3), range=(0, P + 2), density=True) return hist def extract_features_from_image(image): hist_features = rgb_histogram(image, bins=64) hu_features = hu_moments(image) glcm_features_vector = glcm_features(image) lbp_features = local_binary_pattern_features(image) gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) hog_features = hog( gray, orientations=8, pixels_per_cell=(32, 32), cells_per_block=(2, 2), visualize=False, feature_vector=True ) color_moments_features = [] for channel in cv2.split(image): color_moments_features.append(np.mean(channel)) color_moments_features.append(np.std(channel)) color_moments_features = np.array(color_moments_features) edges = cv2.Canny(gray, 50, 150) edge_density = np.sum(edges > 0) / edges.size edge_features = np.array([edge_density]) image_features = np.concatenate([ hist_features, hu_features, glcm_features_vector, lbp_features, hog_features, color_moments_features, edge_features ]) return image_features def perform_pca(data, num_components): mean = np.mean(data, axis=0) std_dev = np.std(data, axis=0) data_standardized = (data - mean) / std_dev covariance_matrix = np.cov(data_standardized, rowvar=False) eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix) sorted_indices = np.argsort(eigenvalues)[::-1] sorted_eigenvalues = eigenvalues[sorted_indices] sorted_eigenvectors = eigenvectors[:, sorted_indices] top_k_eigenvectors = sorted_eigenvectors[:, :num_components] data_reduced = np.dot(data_standardized, top_k_eigenvectors) data_reduced = np.real(data_reduced) return data_reduced def train_svm_model(features, labels, test_size=0.2, use_grid_search=False, use_precision_optimization=False): if labels.ndim > 1 and labels.shape[1] > 1: labels = np.argmax(labels, axis=1) X_train, X_test, y_train, y_test = train_test_split( features, labels, test_size=test_size, random_state=42, stratify=labels ) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) if use_grid_search: print("Grid Search...") param_grid = { 'C': [0.1, 1, 10, 100, 1000], 'kernel': ['rbf', 'linear', 'poly'], 'gamma': ['scale', 'auto', 0.001, 0.01, 0.1], 'class_weight': ['balanced', None], 'degree': [2, 3, 4] } svm = SVC(random_state=42, probability=True) scoring = 'precision_weighted' if use_precision_optimization else 'accuracy' grid_search = GridSearchCV( svm, param_grid, cv=5, scoring=scoring, n_jobs=-1, verbose=1 ) grid_search.fit(X_train_scaled, y_train) svm_model = grid_search.best_estimator_ print(f"\nbest params: {grid_search.best_params_}") print(f" CV Score: {grid_search.best_score_:.4f}") else: svm_model = SVC( kernel='rbf', C=10, gamma='scale', class_weight='balanced', random_state=42, probability=True ) svm_model.fit(X_train_scaled, y_train) y_pred = svm_model.predict(X_test_scaled) accuracy = accuracy_score(y_test, y_pred) print(f'Test Accuracy: {accuracy:.2f}') if use_precision_optimization: precision_weighted = precision_score(y_test, y_pred, average='weighted', zero_division=0) precision_macro = precision_score(y_test, y_pred, average='macro', zero_division=0) print(f'Test Precision (Weighted): {precision_weighted:.4f}') print(f'Test Precision (Macro): {precision_macro:.4f}') print(f'\nClassification Report:') print(classification_report(y_test, y_pred, zero_division=0)) results = { 'model': svm_model, 'scaler': scaler, 'accuracy': accuracy, 'precision_weighted': precision_weighted, 'precision_macro': precision_macro, 'y_test': y_test, 'y_pred': y_pred } if use_grid_search: results['best_params'] = grid_search.best_params_ results['cv_score'] = grid_search.best_score_ return svm_model, results return svm_model