TIFNGK_E41222722/utils/feature_extraction.py

100 lines
3.6 KiB
Python

import numpy as np
import cv2
from skimage.feature import graycomatrix, graycoprops
import pandas as pd
from sqlalchemy import Extract
class FeatureExtractor:
def __init__(self):
# Fitur: Average RGB (3) + GLCM (4) = 7 features total
self.feature_names = ['avg_red', 'avg_green', 'avg_blue',
'contrast', 'homogeneity', 'correlation', 'energy']
def extract_rgb_average(self, image_rgb):
"""Extract average values for R, G, B channels
Parameters:
- image_rgb: RGB image (uint8)
Return: list [avg_red, avg_green, avg_blue]
"""
if image_rgb is None:
print("[WARNING] image_rgb is None in extract_rgb_average")
return [0.0, 0.0, 0.0]
try:
avg_red = np.mean(image_rgb[:, :, 0])
avg_green = np.mean(image_rgb[:, :, 1])
avg_blue = np.mean(image_rgb[:, :, 2])
return [avg_red, avg_green, avg_blue]
except Exception as e:
print(f"[ERROR] extract_rgb_average failed: {str(e)}")
return [0.0, 0.0, 0.0]
def glcm_features(self, gray_image):
"""Extract GLCM texture features (4)
Parameters:
- gray_image: Grayscale image hasil threshold (uint8)
Return: list [contrast, homogeneity, correlation, energy]
"""
# Validate input
if gray_image is None:
print("[WARNING] gray_image is None in glcm_features")
return [0.0, 0.0, 0.0, 0.0]
try:
gray = gray_image.astype(np.uint8)
glcm = graycomatrix(gray, distances=[1, 2, 3],
angles=[0, np.pi/4, np.pi/2, 3*np.pi/4],
levels=256, symmetric=True, normed=True)
features = []
for prop in ['contrast', 'homogeneity', 'correlation', 'energy']:
prop_values = graycoprops(glcm, prop)
features.append(np.mean(prop_values))
return features
except Exception as e:
print(f"[ERROR] glcm_features failed: {str(e)}")
return [0.0, 0.0, 0.0, 0.0]
def extract_all_features(self, image_rgb, gray_processed):
"""Extract 7 features: Average RGB (3) + GLCM (4)
Parameters:
- image_rgb: RGB image from preprocessing pipeline (uint8)
- gray_processed: Grayscale hasil threshold dari preprocessing pipeline (uint8)
Return: list of 7 features
"""
# Validate inputs
if image_rgb is None:
print("[ERROR] image_rgb is None in extract_all_features")
return [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
if gray_processed is None:
print("[ERROR] gray_processed is None in extract_all_features")
return [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Extract average RGB values (3)
rgb_features = self.extract_rgb_average(image_rgb)
# Extract GLCM texture features (4)
glcm_features_list = self.glcm_features(gray_processed)
all_features = rgb_features + glcm_features_list
return all_features
def save_features_to_csv(self, features_list, labels, filename):
"""Save extracted features to CSV"""
df = pd.DataFrame(features_list, columns=self.feature_names)
df['label'] = labels
# Save to CSV
df.to_csv(filename, index=False)
print(f"Fitur disimpan ke: {filename}")
return df