Maulidaaa commited on
Commit
b0828b5
·
1 Parent(s): 3f72371

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -19
app.py CHANGED
@@ -1,9 +1,12 @@
1
  import os
2
  import numpy as np
3
  import pandas as pd
 
 
 
4
  from flask import Flask, request, jsonify, render_template_string
5
- from tensorflow.keras.models import load_model
6
- from tensorflow.keras.utils import load_img, img_to_array
7
  from math import radians, cos, sin, sqrt, atan2
8
  import joblib
9
  import requests
@@ -19,30 +22,46 @@ app = Flask(__name__)
19
  UPLOAD_FOLDER = '/tmp/uploads'
20
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
21
 
22
- # Load model dan data
23
- soil_model = load_model("models/best_vit_model.pth")
 
 
 
 
 
 
 
 
 
24
  crop_model = joblib.load("models/model_random_forest.joblib")
25
  crop_model_label = joblib.load("models/label_encoder.joblib")
 
 
26
  soil_df = pd.read_csv("data/soil_data_with_class.csv")
27
  agri_df = pd.read_csv("data/tips_menanam_dan_manfaat_tanaman.csv")
28
- class_labels = ['Black Soil', 'Cinder Soil', 'Laterite Soil', 'Peat Soil', 'Yellow Soil']
29
 
30
- # Fungsi preprocessing gambar
31
  def preprocess_image(img_path):
32
- img = load_img(img_path, target_size=(224, 224))
33
- img_array = img_to_array(img) / 255.0
34
- return np.expand_dims(img_array, axis=0)
 
 
 
 
35
 
36
  # Fungsi prediksi jenis tanah
37
  def predict_soil_type(img_path):
38
- img_array = preprocess_image(img_path)
39
- prediction = soil_model.predict(img_array)
40
- predicted_index = np.argmax(prediction)
 
 
41
  predicted_class = class_labels[predicted_index]
42
- accuracy = float(prediction[0][predicted_index])
43
  return predicted_class, accuracy
44
 
45
- # Fungsi hitung jarak terdekat
46
  def find_nearest_soil_data_weighted(soil_type, lat, lon, n_points=1):
47
  filtered = soil_df[soil_df['Class_Name'] == soil_type].copy()
48
  if filtered.empty:
@@ -54,7 +73,7 @@ def find_nearest_soil_data_weighted(soil_type, lat, lon, n_points=1):
54
  lat2, lon2 = radians(row['Location_Latitude']), radians(row['Location_Longitude'])
55
  dlat = lat2 - user_lat
56
  dlon = lon2 - user_lon
57
- a = sin(dlat / 2) ** 2 + cos(user_lat) * cos(lat2) * sin(dlon / 2) ** 2
58
  c = 2 * atan2(sqrt(a), sqrt(1 - a))
59
  return 6371 * c
60
 
@@ -72,7 +91,7 @@ def find_nearest_soil_data_weighted(soil_type, lat, lon, n_points=1):
72
  "distance_km": float(row['Distance_km'])
73
  }
74
 
75
- # Ambil data cuaca
76
  def get_weather_data(lat, lon):
77
  url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}&units=metric"
78
  res = requests.get(url)
@@ -84,7 +103,7 @@ def get_weather_data(lat, lon):
84
  "humidity": float(data['main']['humidity']),
85
  }
86
 
87
- # Fungsi untuk mengambil tips bertani dan manfaat dari agri_df
88
  def get_farming_tips(df, crop_name):
89
  crop_name_str = str(crop_name)
90
  match = df[df['Nama Tanaman'].str.lower() == crop_name_str.lower()]
@@ -98,7 +117,7 @@ def get_farming_tips(df, crop_name):
98
  }
99
  return None
100
 
101
- # Fungsi reverse geocoding
102
  def get_location_name(lat, lon):
103
  try:
104
  url = f"https://nominatim.openstreetmap.org/reverse?lat={lat}&lon={lon}&format=json"
@@ -136,7 +155,7 @@ def index():
136
  """
137
  return render_template_string(html_content)
138
 
139
- # Endpoint analisis utama
140
  @app.route('/analyze', methods=['POST'])
141
  def analyze():
142
  if 'image' not in request.files:
@@ -222,5 +241,6 @@ def analyze():
222
 
223
  return jsonify(result)
224
 
 
225
  if __name__ == '__main__':
226
  app.run(debug=True)
 
1
  import os
2
  import numpy as np
3
  import pandas as pd
4
+ import torch
5
+ import timm
6
+ import torch.nn as nn
7
  from flask import Flask, request, jsonify, render_template_string
8
+ from torchvision import transforms
9
+ from PIL import Image
10
  from math import radians, cos, sin, sqrt, atan2
11
  import joblib
12
  import requests
 
22
  UPLOAD_FOLDER = '/tmp/uploads'
23
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
24
 
25
+ # Label klasifikasi tanah
26
+ class_labels = ['Black Soil', 'Cinder Soil', 'Laterite Soil', 'Peat Soil', 'Yellow Soil']
27
+ num_classes = len(class_labels)
28
+
29
+ # Load model ViT (PyTorch)
30
+ soil_model = timm.create_model("vit_base_patch16_224", pretrained=False, num_classes=num_classes)
31
+ soil_model.head = nn.Linear(soil_model.head.in_features, num_classes)
32
+ soil_model.load_state_dict(torch.load("models/best_vit_model.pth", map_location=torch.device("cpu")))
33
+ soil_model.eval()
34
+
35
+ # Load model crop recommendation
36
  crop_model = joblib.load("models/model_random_forest.joblib")
37
  crop_model_label = joblib.load("models/label_encoder.joblib")
38
+
39
+ # Load data referensi
40
  soil_df = pd.read_csv("data/soil_data_with_class.csv")
41
  agri_df = pd.read_csv("data/tips_menanam_dan_manfaat_tanaman.csv")
 
42
 
43
+ # Fungsi preprocessing gambar (PyTorch style)
44
  def preprocess_image(img_path):
45
+ transform = transforms.Compose([
46
+ transforms.Resize((224, 224)),
47
+ transforms.ToTensor(),
48
+ transforms.Normalize(mean=[0.5]*3, std=[0.5]*3)
49
+ ])
50
+ img = Image.open(img_path).convert("RGB")
51
+ return transform(img).unsqueeze(0)
52
 
53
  # Fungsi prediksi jenis tanah
54
  def predict_soil_type(img_path):
55
+ img_tensor = preprocess_image(img_path)
56
+ with torch.no_grad():
57
+ outputs = soil_model(img_tensor)
58
+ probabilities = torch.softmax(outputs, dim=1).numpy()[0]
59
+ predicted_index = np.argmax(probabilities)
60
  predicted_class = class_labels[predicted_index]
61
+ accuracy = float(probabilities[predicted_index])
62
  return predicted_class, accuracy
63
 
64
+ # Hitung jarak dengan haversine
65
  def find_nearest_soil_data_weighted(soil_type, lat, lon, n_points=1):
66
  filtered = soil_df[soil_df['Class_Name'] == soil_type].copy()
67
  if filtered.empty:
 
73
  lat2, lon2 = radians(row['Location_Latitude']), radians(row['Location_Longitude'])
74
  dlat = lat2 - user_lat
75
  dlon = lon2 - user_lon
76
+ a = sin(dlat / 2)**2 + cos(user_lat) * cos(lat2) * sin(dlon / 2)**2
77
  c = 2 * atan2(sqrt(a), sqrt(1 - a))
78
  return 6371 * c
79
 
 
91
  "distance_km": float(row['Distance_km'])
92
  }
93
 
94
+ # Ambil data cuaca dari OpenWeather
95
  def get_weather_data(lat, lon):
96
  url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}&units=metric"
97
  res = requests.get(url)
 
103
  "humidity": float(data['main']['humidity']),
104
  }
105
 
106
+ # Ambil tips bertani dan manfaat tanaman
107
  def get_farming_tips(df, crop_name):
108
  crop_name_str = str(crop_name)
109
  match = df[df['Nama Tanaman'].str.lower() == crop_name_str.lower()]
 
117
  }
118
  return None
119
 
120
+ # Reverse geocoding
121
  def get_location_name(lat, lon):
122
  try:
123
  url = f"https://nominatim.openstreetmap.org/reverse?lat={lat}&lon={lon}&format=json"
 
155
  """
156
  return render_template_string(html_content)
157
 
158
+ # Endpoint analisis
159
  @app.route('/analyze', methods=['POST'])
160
  def analyze():
161
  if 'image' not in request.files:
 
241
 
242
  return jsonify(result)
243
 
244
+ # Jalankan server
245
  if __name__ == '__main__':
246
  app.run(debug=True)