Spaces:
Sleeping
Sleeping
from fastapi import FastAPI, UploadFile, File | |
import numpy as np | |
import cv2 | |
import tensorflow as tf | |
from PIL import Image | |
import io | |
app = FastAPI() | |
# Load model Keras | |
model = tf.keras.models.load_model("lontara_model_finetuning.keras") | |
def home(): | |
return {"message": "Aksara Lontara API is running"} | |
def preprocess_image(image: np.ndarray): | |
""" Melakukan segmentasi karakter menggunakan OpenCV """ | |
# **1️⃣ Edge Detection (Canny)** | |
edges = cv2.Canny(image, 50, 150) | |
# **2️⃣ Morphological Cleaning** | |
kernel = np.ones((3, 3), np.uint8) | |
edges_cleaned = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel, iterations=2) | |
# **3️⃣ Connected Component Analysis (CCA)** | |
num_labels, labels, stats, _ = cv2.connectedComponentsWithStats(edges_cleaned, connectivity=8) | |
# **4️⃣ Filter huruf berdasarkan area** | |
min_area = 500 | |
bounding_boxes = [] | |
for i in range(1, num_labels): # Skip background | |
x, y, w, h, area = stats[i] | |
if area > min_area: | |
bounding_boxes.append((x, y, w, h)) | |
# **5️⃣ Urutkan huruf berdasarkan posisi X** | |
bounding_boxes.sort(key=lambda b: b[0]) | |
# **6️⃣ Gabungkan Bounding Box yang Berdekatan** | |
merged_boxes = [] | |
merge_threshold = 20 | |
for i in range(len(bounding_boxes)): | |
x, y, w, h = bounding_boxes[i] | |
if merged_boxes and (x - (merged_boxes[-1][0] + merged_boxes[-1][2])) < merge_threshold: | |
x_prev, y_prev, w_prev, h_prev = merged_boxes.pop() | |
x_new = min(x_prev, x) | |
y_new = min(y_prev, y) | |
w_new = max(x_prev + w_prev, x + w) - x_new | |
h_new = max(y_prev + h_prev, y + h) - y_new | |
merged_boxes.append((x_new, y_new, w_new, h_new)) | |
else: | |
merged_boxes.append((x, y, w, h)) | |
# **7️⃣ Potong dan proses karakter** | |
segmented_chars = [] | |
for (x, y, w, h) in merged_boxes: | |
char_segment = image[y:y+h, x:x+w] | |
char_segment = cv2.resize(char_segment, (128, 128), interpolation=cv2.INTER_AREA) | |
segmented_chars.append(char_segment) | |
return segmented_chars | |
async def predict(file: UploadFile = File(...)): | |
# Baca gambar dari file upload | |
image = Image.open(io.BytesIO(await file.read())).convert("L") | |
image = np.array(image) | |
# **Segmentasi huruf** | |
segmented_chars = preprocess_image(image) | |
# Jika tidak ada huruf terdeteksi | |
if not segmented_chars: | |
return {"prediction": "No characters detected"} | |
# **Prediksi untuk setiap karakter** | |
predictions = [] | |
for char in segmented_chars: | |
char_norm = np.array(char) / 255.0 # Normalisasi | |
char_norm = char_norm.reshape(1, 128, 128, 1) # Reshape untuk model | |
prediction = model.predict(char_norm) | |
predicted_label = labels[np.argmax(prediction)] | |
predictions.append(predicted_label) | |
return {"predictions": predictions} |