ArsanForEver commited on
Commit
4e65103
·
verified ·
1 Parent(s): cf11566

Add: Feature segmentation

Browse files
Files changed (1) hide show
  1. app.py +74 -7
app.py CHANGED
@@ -2,6 +2,7 @@ from fastapi import FastAPI, UploadFile, File
2
  import tensorflow as tf
3
  import numpy as np
4
  from PIL import Image
 
5
  import io
6
  import uvicorn
7
 
@@ -26,15 +27,81 @@ labels = [
26
  def home():
27
  return {"message": "Aksara Lontara API is running"}
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  @app.post("/predict")
30
  async def predict(file: UploadFile = File(...)):
31
  # Baca gambar
32
- image = Image.open(io.BytesIO(await file.read())).convert("L").resize((128, 128))
33
- image = np.array(image) / 255.0
34
- image = image.reshape(1, 128, 128, 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- # Prediksi
37
- prediction = model.predict(image)
38
- label = labels[np.argmax(prediction)]
39
 
40
- return {"prediction": label}
 
 
2
  import tensorflow as tf
3
  import numpy as np
4
  from PIL import Image
5
+ import cv2
6
  import io
7
  import uvicorn
8
 
 
27
  def home():
28
  return {"message": "Aksara Lontara API is running"}
29
 
30
+ def preprocess_image(image: np.array):
31
+ """Mengolah gambar untuk segmentasi huruf sebelum prediksi"""
32
+
33
+ # **1️⃣ Edge Detection (Canny)**
34
+ edges = cv2.Canny(image, 50, 150) # Menangkap batas huruf
35
+
36
+ # **2️⃣ Morphological Operations untuk membersihkan noise**
37
+ kernel = np.ones((3,3), np.uint8)
38
+ edges_cleaned = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel, iterations=2)
39
+
40
+ # **3️⃣ Connected Component Analysis (CCA)**
41
+ num_labels, labels, stats, _ = cv2.connectedComponentsWithStats(edges_cleaned, connectivity=8)
42
+
43
+ # **4️⃣ Filter Huruf Berdasarkan Area**
44
+ min_area = 500 # Sesuaikan berdasarkan ukuran huruf
45
+ bounding_boxes = []
46
+
47
+ for i in range(1, num_labels): # Skip background
48
+ x, y, w, h, area = stats[i]
49
+ if area > min_area: # Filter noise kecil
50
+ bounding_boxes.append((x, y, w, h))
51
+
52
+ # **5️⃣ Urutkan huruf berdasarkan posisi X**
53
+ bounding_boxes.sort(key=lambda b: b[0])
54
+
55
+ # **6️⃣ Gabungkan Bounding Box yang Berdekatan**
56
+ merged_boxes = []
57
+ merge_threshold = 20 # Jika jarak antar bounding box < 20 piksel, gabungkan
58
+
59
+ for i in range(len(bounding_boxes)):
60
+ x, y, w, h = bounding_boxes[i]
61
+
62
+ if merged_boxes and (x - (merged_boxes[-1][0] + merged_boxes[-1][2])) < merge_threshold:
63
+ # Gabungkan bounding box terakhir dengan yang sekarang
64
+ x_prev, y_prev, w_prev, h_prev = merged_boxes.pop()
65
+ x_new = min(x_prev, x)
66
+ y_new = min(y_prev, y)
67
+ w_new = max(x_prev + w_prev, x + w) - x_new
68
+ h_new = max(y_prev + h_prev, y + h) - y_new
69
+ merged_boxes.append((x_new, y_new, w_new, h_new))
70
+ else:
71
+ # Tambahkan sebagai bounding box baru
72
+ merged_boxes.append((x, y, w, h))
73
+
74
+ # **7️⃣ Potong karakter hasil segmentasi**
75
+ segmented_chars = []
76
+ for (x, y, w, h) in merged_boxes:
77
+ char_segment = image[y:y+h, x:x+w] # Potong area karakter
78
+ segmented_chars.append(char_segment)
79
+
80
+ return segmented_chars
81
+
82
  @app.post("/predict")
83
  async def predict(file: UploadFile = File(...)):
84
  # Baca gambar
85
+ image = Image.open(io.BytesIO(await file.read())).convert("L") # Konversi ke grayscale
86
+ image = np.array(image)
87
+
88
+ # Preprocessing: Segmentasi huruf
89
+ segmented_chars = preprocess_image(image)
90
+
91
+ predictions = []
92
+ for char_img in segmented_chars:
93
+ # Resize ke ukuran yang diharapkan oleh model
94
+ char_img_resized = cv2.resize(char_img, (128, 128))
95
+ char_img_resized = char_img_resized / 255.0 # Normalisasi
96
+ char_img_resized = char_img_resized.reshape(1, 128, 128, 1) # Ubah ke bentuk input model
97
+
98
+ # Prediksi
99
+ prediction = model.predict(char_img_resized)
100
+ label = labels[np.argmax(prediction)]
101
+
102
+ predictions.append(label)
103
 
104
+ return {"predictions": predictions}
 
 
105
 
106
+ if __name__ == "__main__":
107
+ uvicorn.run(app, host="0.0.0.0", port=8000)