145 lines
5.4 KiB
Python
145 lines
5.4 KiB
Python
import cv2
|
|
import os
|
|
import numpy as np
|
|
import xlsxwriter
|
|
from skimage.measure import regionprops, label
|
|
|
|
# Path folder gambar
|
|
folders = {
|
|
'Corynebacterium Diphteriae': 'D:/Skripsi/ekstraksi fitur/Corynebacterium Diphteriae',
|
|
'Mycobacterium Tuberculosis': 'D:/Skripsi/ekstraksi fitur/Mycobacterium Tuberculosis',
|
|
'Neiseria Gonorroea': 'D:/Skripsi/ekstraksi fitur/Neiseria Gonorroea',
|
|
'Staphylococcus Aureus': 'D:/Skripsi/ekstraksi fitur/Staphylococcus Aureus',
|
|
'Streptococcus Pneumoniae': 'D:/Skripsi/ekstraksi fitur/Streptococcus Pneumoniae'
|
|
}
|
|
|
|
# Fungsi untuk menghitung eccentricity
|
|
def calculate_eccentricity(region):
|
|
if region.minor_axis_length == 0:
|
|
return 0
|
|
else:
|
|
return np.sqrt(1 - (region.minor_axis_length / region.major_axis_length)**2)
|
|
|
|
# Membuat workbook dan worksheet
|
|
output_file = 'D:/Skripsi/ekstraksi fitur/data_fitur.xlsx'
|
|
workbook = xlsxwriter.Workbook(output_file)
|
|
worksheet = workbook.add_worksheet()
|
|
|
|
# Menulis header
|
|
headers = ['File Name', 'Jumlah Objek', 'Eccentricity Rata-Rata', 'Metric Rata-Rata', 'Area Total', 'Perimeter Total', 'Label']
|
|
for col, header in enumerate(headers):
|
|
worksheet.write(0, col, header)
|
|
|
|
row = 1
|
|
|
|
for label_name, image_folder in folders.items():
|
|
# Cek apakah folder gambar ada
|
|
if not os.path.isdir(image_folder):
|
|
print(f"Folder {image_folder} tidak ditemukan.")
|
|
continue
|
|
|
|
# Jumlah gambar dalam folder
|
|
image_files = [f for f in os.listdir(image_folder) if f.endswith('.jpg')]
|
|
num_images = len(image_files)
|
|
|
|
# Ekstraksi fitur
|
|
for i in range(num_images):
|
|
file_name = f'{image_folder}/{image_files[i]}'
|
|
|
|
# Preprocessing
|
|
img = cv2.imread(file_name, 1)
|
|
if img is None:
|
|
print(f"Gagal membaca file: {file_name}")
|
|
continue
|
|
|
|
blue, green, red = cv2.split(img)
|
|
|
|
# Thresholding
|
|
if label_name == 'Corynebacterium Diphteriae':
|
|
ret, img_bin = cv2.threshold(green, 115, 255, cv2.THRESH_BINARY_INV)
|
|
img_bin = cv2.erode(cv2.dilate(img_bin, None, iterations=1), None, iterations=4)
|
|
elif label_name == 'Mycobacterium Tuberculosis':
|
|
ret, img_bin = cv2.threshold(green, 135, 255, cv2.THRESH_BINARY_INV)
|
|
img_bin = cv2.dilate(img_bin, None, iterations=1)
|
|
|
|
# Labeling objek dan filtering berdasarkan ukuran
|
|
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img_bin, connectivity=8)
|
|
mask = np.zeros_like(img_bin)
|
|
min_size = 50
|
|
max_size = 400
|
|
|
|
for j in range(1, num_labels): # Mulai dari 1 untuk melewatkan background
|
|
if min_size <= stats[j, cv2.CC_STAT_AREA] <= max_size:
|
|
mask[labels == j] = 255
|
|
|
|
img_bin = mask
|
|
elif label_name == 'Neiseria Gonorroea':
|
|
ret, img_bin = cv2.threshold(green, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
|
|
img_bin = cv2.dilate(img_bin, None, iterations=1)
|
|
|
|
# Labeling objek dan filtering berdasarkan ukuran
|
|
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img_bin, connectivity=8)
|
|
mask = np.zeros_like(img_bin)
|
|
min_size = 200
|
|
max_size = 2500
|
|
|
|
for j in range(1, num_labels): # Mulai dari 1 untuk melewatkan background
|
|
if min_size <= stats[j, cv2.CC_STAT_AREA] <= max_size:
|
|
mask[labels == j] = 255
|
|
|
|
img_bin = mask
|
|
elif label_name == 'Staphylococcus Aureus':
|
|
ret, img1 = cv2.threshold(green, 110, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
|
|
img_bin = cv2.erode(cv2.dilate(img1.copy(), None, iterations=1), None, iterations=1)
|
|
img_bin = cv2.morphologyEx(img_bin.copy(), cv2.MORPH_OPEN, None)
|
|
elif label_name == 'Streptococcus Pneumoniae':
|
|
ret, img1 = cv2.threshold(green, 110, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
|
|
img_bin = cv2.erode(img1.copy(), None, iterations=1)
|
|
img_bin = cv2.dilate(img1.copy(), None, iterations=1)
|
|
|
|
# Labeling
|
|
labeled_img = label(img_bin)
|
|
regions = regionprops(labeled_img)
|
|
num_objects = len(regions)
|
|
|
|
if num_objects == 0:
|
|
continue
|
|
|
|
# Inisialisasi variabel untuk agregasi
|
|
total_eccentricity = 0
|
|
total_metric = 0
|
|
total_area = 0
|
|
total_perimeter = 0
|
|
|
|
for region in regions:
|
|
# Fitur bentuk
|
|
eccentricity = calculate_eccentricity(region)
|
|
area = region.area
|
|
perimeter = region.perimeter
|
|
metric = (4 * np.pi * area) / (perimeter ** 2) if perimeter != 0 else 0
|
|
|
|
# Agregasi fitur
|
|
total_eccentricity += eccentricity
|
|
total_metric += metric
|
|
total_area += area
|
|
total_perimeter += perimeter
|
|
|
|
# Hitung rata-rata
|
|
mean_eccentricity = total_eccentricity / num_objects
|
|
mean_metric = total_metric / num_objects
|
|
|
|
# Menulis hasil ke worksheet
|
|
worksheet.write(row, 0, image_files[i])
|
|
worksheet.write(row, 1, num_objects)
|
|
worksheet.write(row, 2, mean_eccentricity)
|
|
worksheet.write(row, 3, mean_metric)
|
|
worksheet.write(row, 4, total_area)
|
|
worksheet.write(row, 5, total_perimeter)
|
|
worksheet.write(row, 6, label_name) # Menambahkan label kelas
|
|
|
|
row += 1
|
|
|
|
# Menutup workbook
|
|
workbook.close()
|
|
print(f"Hasil ekstraksi fitur disimpan di {output_file}")
|