prastya commited on
Commit
de94cf7
·
verified ·
1 Parent(s): eeb55a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -30
app.py CHANGED
@@ -1,25 +1,31 @@
1
- from fastapi import FastAPI, File, UploadFile, HTTPException
 
2
  from fastapi.middleware.cors import CORSMiddleware
3
- from tensorflow.keras.models import load_model
4
  import numpy as np
 
 
 
5
  from PIL import Image
6
- import io
7
- import os
8
 
 
9
  app = FastAPI()
10
 
11
- # Untuk mengizinkan akses dari frontend kamu (misal domain lain)
12
  app.add_middleware(
13
  CORSMiddleware,
14
- allow_origins=["*"], # Ganti dengan domain frontend-mu kalau sudah pasti
15
  allow_credentials=True,
16
  allow_methods=["*"],
17
  allow_headers=["*"],
18
  )
19
 
20
- MODEL_PATH = 'model_cnn.h5'
 
21
  IMG_HEIGHT = 224
22
  IMG_WIDTH = 224
 
23
  class_names = [
24
  'freshapples', 'freshbanana', 'freshbittergroud', 'freshcapsicum', 'freshcucumber',
25
  'freshokra', 'freshoranges', 'freshpotato', 'freshtomato',
@@ -27,33 +33,47 @@ class_names = [
27
  'rottenokra', 'rottenoranges', 'rottenpotato', 'rottentomato'
28
  ]
29
 
30
- try:
31
- full_model_path = os.path.join(os.getcwd(), MODEL_PATH)
32
- model = load_model(full_model_path)
33
- print(f"Model loaded successfully from: {full_model_path}")
34
- except Exception as e:
35
- print(f"Error loading model: {e}")
36
- raise RuntimeError(f"Failed to load model: {e}")
 
 
 
 
 
 
 
 
 
 
37
 
 
 
 
38
  @app.post("/predict")
39
  async def predict_image(file: UploadFile = File(...)):
40
  try:
41
- contents = await file.read()
42
- image_pil = Image.open(io.BytesIO(contents)).convert("RGB")
43
- image_pil = image_pil.resize((IMG_WIDTH, IMG_HEIGHT))
44
- img_array = np.array(image_pil)
45
- img_array = np.expand_dims(img_array, axis=0)
46
-
47
- prediction = model.predict(img_array)
48
- predicted_class_index = np.argmax(prediction[0])
49
- confidence = float(prediction[0][predicted_class_index]) * 100
50
- pred_class_name = class_names[predicted_class_index]
51
-
52
- return {
53
- "title": pred_class_name,
54
  "confidence": f"{confidence:.2f}",
55
- "message": f"Prediksi: {pred_class_name} dengan kepercayaan {confidence:.2f}%",
56
- "details": []
57
  }
 
 
58
  except Exception as e:
59
- raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile
2
+ from fastapi.responses import JSONResponse
3
  from fastapi.middleware.cors import CORSMiddleware
4
+ import uvicorn
5
  import numpy as np
6
+ import tensorflow as tf
7
+ from tensorflow.keras.models import load_model
8
+ from tensorflow.keras.preprocessing import image
9
  from PIL import Image
10
+ from io import BytesIO
 
11
 
12
+ # === Inisialisasi FastAPI ===
13
  app = FastAPI()
14
 
15
+ # === Middleware CORS agar bisa diakses dari frontend (JS) ===
16
  app.add_middleware(
17
  CORSMiddleware,
18
+ allow_origins=["*"], # Ganti dengan domain frontend-mu untuk keamanan
19
  allow_credentials=True,
20
  allow_methods=["*"],
21
  allow_headers=["*"],
22
  )
23
 
24
+ # === Konfigurasi Model ===
25
+ MODEL_PATH = 'model_cnn.h5' # Pastikan path model benar
26
  IMG_HEIGHT = 224
27
  IMG_WIDTH = 224
28
+
29
  class_names = [
30
  'freshapples', 'freshbanana', 'freshbittergroud', 'freshcapsicum', 'freshcucumber',
31
  'freshokra', 'freshoranges', 'freshpotato', 'freshtomato',
 
33
  'rottenokra', 'rottenoranges', 'rottenpotato', 'rottentomato'
34
  ]
35
 
36
+ # Muat model sekali saja saat startup
37
+ model = load_model(MODEL_PATH)
38
+
39
+ # === Fungsi bantu ===
40
+ def read_imagefile(file) -> Image.Image:
41
+ image = Image.open(BytesIO(file)).convert("RGB") # Pastikan RGB
42
+ return image
43
+
44
+ def predict(img: Image.Image):
45
+ # Resize dan ubah ke array tanpa normalisasi ulang (karena model sudah punya Rescaling)
46
+ img = img.resize((IMG_WIDTH, IMG_HEIGHT))
47
+ img_array = image.img_to_array(img) # [0,255]
48
+ img_array = np.expand_dims(img_array, axis=0) # [1, 224, 224, 3]
49
+
50
+ prediction = model.predict(img_array)
51
+ predicted_class = np.argmax(prediction[0])
52
+ confidence = float(prediction[0][predicted_class]) * 100
53
 
54
+ return class_names[predicted_class], confidence
55
+
56
+ # === Endpoint utama ===
57
  @app.post("/predict")
58
  async def predict_image(file: UploadFile = File(...)):
59
  try:
60
+ img = read_imagefile(await file.read())
61
+ pred_class, confidence = predict(img)
62
+
63
+ response = {
64
+ "filename": file.filename,
65
+ "title": "Prediction Result",
66
+ "message": f"The item is classified as: {pred_class}",
 
 
 
 
 
 
67
  "confidence": f"{confidence:.2f}",
68
+ "details": [f"Class: {pred_class}", f"Confidence: {confidence:.2f}%"]
 
69
  }
70
+
71
+ return JSONResponse(content=response)
72
  except Exception as e:
73
+ return JSONResponse(content={"error": str(e)}, status_code=500)
74
+
75
+ # === Untuk menjalankan secara lokal ===
76
+ if __name__ == "__main__":
77
+ uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)
78
+
79
+ # uvicorn app:app --reload