Spaces:
Runtime error
Runtime error
File size: 14,436 Bytes
12efb2a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# app.py (QUANTUM FINAL: Қарапайым, Әдемі & Нақты)
import gradio as gr
import requests
import pandas as pd
from openmeteo_requests import Client
import openmeteo_requests
from PIL import Image
import torch
import timm
from torchvision import transforms
from datetime import datetime
import pytz
import numpy as np
# --- 0. Қазақша Классификация Сөздігі (Өсімдіктерге басымдықпен) ---
# Бұл ImageNet-ке негізделген, бірақ қазақшаға бейімделген
KZ_LABELS = {
0: "Ауылшаруашылық техникасы",
1: "Мал (Жылқы/Сиыр)",
2: "Ит / Қасқыр",
3: "Құс",
4: "Қоқыс (Пластик/Қағаз)",
5: "Шыны / Металл қалдықтары",
6: "Өсімдік Ауруы (Шіріген)", # Өсімдік ауруларына нақтырақ
7: "Өсімдік (Дені сау)",
10: "Көлік / Жүк машинасы",
12: "Қой/Ешкі",
16: "Дәнді дақылдар",
20: "Ағаш / Орман",
25: "Шөп / Жайылым",
}
# --- 1. Тұрақты Параметрлер & Геодеректер ---
BAYAN_ULGII_LAT = 48.97
BAYAN_ULGII_LON = 89.97
DEVICE = "cpu"
TIMEZONE = "Asia/Ulaanbaatar"
# --- 2. Ауа Райы Кодтарының Қазақша Аудармасы ---
def translate_weather_code(code):
if code in [0]: return "Күн ашық ☀️"
if code in [1, 2]: return "Аздаған бұлт 🌤️"
if code in [3]: return "Бұлтты ☁️"
if code in [45, 48]: return "Тұман 🌫️"
if code in [51, 53, 55, 61, 63]: return "Аздаған жаңбыр 🌧️"
if code in [65, 80, 81, 82]: return "Нөсер/Қатты жаңбыр ⛈️"
if code in [56, 57, 66, 67, 71, 73]: return "Қар/Аязды жаңбыр 🌨️"
if code in [75, 77, 85, 86]: return "Қалың қар ❄️"
if code in [95, 96, 99]: return "Найзағай ⚡"
return "Белгісіз"
# --- 3. Модельдерді Жүктеу (Тұрақтылықты күшейту) ---
TRASH_AVAILABLE = False
ANIMAL_PLANT_AVAILABLE = False
try:
# Ең жеңіл ML моделі (Мал/Өсімдік)
animal_plant_model = timm.create_model('shufflenet_v2_x0_5', pretrained=True).to(DEVICE).eval()
# Жақсы дәлдікті ML моделі (Қоқыс)
trash_model = timm.create_model('efficientnet_b0', pretrained=True).to(DEVICE).eval()
transform_common = transforms.Compose([
transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
ANIMAL_PLANT_AVAILABLE = True
TRASH_AVAILABLE = True
print("✅ Барлық жеңіл модельдер сәтті жүктелді.")
except Exception as e:
print(f"❌ Модельдерді жүктеу кезінде қате: {e}. ML функциялары іске қосылмайды.")
# --- 4. Ауа Райы Логикасы ---
def get_weather_data():
lat, lon = BAYAN_ULGII_LAT, BAYAN_ULGII_LON
try:
openmeteo = Client(requests)
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": lat, "longitude": lon,
"daily": ["weather_code", "temperature_2m_max", "temperature_2m_min", "precipitation_sum", "wind_speed_10m_max"],
"timezone": "auto", "forecast_days": 7
}
responses = openmeteo.weather_api(url, params=params)
response = responses[0]
daily = response.Daily()
time_stamps = daily.Time()
time_series = pd.to_datetime(time_stamps, unit="s").tz_localize(pytz.utc).tz_convert(TIMEZONE)
# Деректерді алу және дөңгелектеу
temp_max = daily.Variables(1).ValuesAsNumpy()
temp_min = daily.Variables(2).ValuesAsNumpy()
precip_sum = daily.Variables(3).ValuesAsNumpy()
wind_speed = daily.Variables(4).ValuesAsNumpy()
weather_code = daily.Variables(0).ValuesAsNumpy()
daily_data = {
"Күн": time_series.strftime('%d.%m'),
"Сипаттама": [translate_weather_code(code) for code in weather_code],
"Макс. Темп (°C)": temp_max.round(1),
"Мин. Темп (°C)": temp_min.round(1),
"Жауын-шашын (мм)": precip_sum.round(1),
"Жел Жылдамдығы (км/сағ)": wind_speed.round(1)
}
df = pd.DataFrame(daily_data)
# 4.1.1. ⚠️ Ерекше Экологиялық Ескертулер (Бас интерфейске шығатын)
warnings = []
if np.any(wind_speed > 45): warnings.append("🚨 **ҚАТТЫ ЖЕЛ:** Жел 45 км/сағ-тан асады. Мал бағуға қауіпті.")
if np.any(temp_min < -20): warnings.append("❄️ **ӨТЕ ҚАТТЫ АЯЗ:** -20°C төмен. Жылытуды күшейтіңіз.")
if np.any(np.isin(weather_code, [75, 85, 86])): warnings.append("🌨️ **ЫҚТИМАЛ ҚАЛЫҢ ҚАР:** Қалың қар күтілуде. Жолдарға назар аударыңыз.")
if np.any(precip_sum > 10): warnings.append("💧 **СУ ТАСҚЫНЫ ҚАУПІ:** Жауын-шашын күшті. Су басу қаупі бар.")
warning_message = "✅ Қауіпсіздік ескертулері жоқ. Ауа райы тұрақты." if not warnings else "⚠️ **МАҢЫЗДЫ ҚАУІПСІЗДІК ЕСКЕРТУЛЕРІ:**\n- " + "\n- ".join(warnings)
# 4.1.2. 🧠 Қазақша Болжам/Талдау
analysis = []
if np.any(temp_max > 15): analysis.append("Алдағы күндері **күн жылы** болады.")
if np.any(np.isin(weather_code, [0, 1])): analysis.append("Көп күндері **күн ашық** болады.")
analysis_text = "✨ **Апталық Болжам Талдауы:**\n- " + ("\n- ".join(analysis) if analysis else "Жалпы алғанда ауа райы айтарлықтай өзгеріссіз.")
return warning_message, df, analysis_text
except Exception as e:
return f"❌ Ауа райы деректерін алу қатесі: {e}", pd.DataFrame(), "Талдау қолжетімсіз."
# 4.2. ML Жіктеу (Өзгеріссіз)
def classify_image(image, task):
if (task in ["animal", "plant"] and not ANIMAL_PLANT_AVAILABLE) or (task == "trash" and not TRASH_AVAILABLE):
return "❌ Суретті жіктеу моделі іске қосылмады. Серверді қайта жүктеңіз немесе 'requirements' тексеріңіз."
try:
model, model_name = (
(trash_model, "EfficientNet B0 (5.3M)") if task == "trash"
else (animal_plant_model, "ShuffleNet V2 (1.3M)")
)
input_tensor = transform_common(image).unsqueeze(0).to(DEVICE)
with torch.no_grad():
outputs = model(input_tensor)
_, predicted = torch.max(outputs.data, 1)
predicted_index = predicted.item()
predicted_kz_label = KZ_LABELS.get(predicted_index, f"Белгісіз Код #{predicted_index}")
if task == "trash": type_kz = "Қоқыс түрі"
elif task == "animal": type_kz = "Мал Ауруы"
else: type_kz = "Өсімдік Түрі / Ауруы"
kz_response = f"**{type_kz}** болжамды нәтиже:\nБолжам: **{predicted_kz_label}**.\n\n"
kz_response += f"✅ **Қолданылған Жеңіл Модель:** {model_name}.\n"
kz_response += "❗ **Ескерту:** Бұл модельдер жалпы деректерде оқытылған. Дәл диагноз үшін **жергілікті маманға** жүгініңіз."
return kz_response
except Exception as e:
return f"❌ Суретті жіктеу қатесі: {e}"
# 4.3. Уақытты жаңарту (Әр минут сайын)
def get_current_time():
try:
tz = pytz.timezone(TIMEZONE)
now = datetime.now(tz)
return now.strftime("⌚ %H:%M:%S (%d.%m.%Y)")
except Exception:
return "⌚ Уақыт дерегі қолжетімсіз"
# Қосымша іске қосылғанда деректерді алдын ала жүктеу
initial_warning, initial_df, initial_analysis = get_weather_data()
# --- 5. Ғажап Интерфейс (Gradio) ---
# Әдемі, қарапайым және түсінікті тақырыпты таңдаймыз
with gr.Blocks(title="Quantum FINAL: Баян-Өлгий AI", theme=gr.themes.Soft()) as demo:
current_time_display = gr.Textbox(label=f"Баян-Өлгий Уақыты", value=get_current_time(), interactive=False, container=False)
# 5.1. Басты HTML блок (Қарапайым және таза дизайн)
header_html = gr.HTML(
f"""
<div style="text-align: center; padding: 10px; background-color: #4CAF50; color: white; border-radius: 10px;">
<h1 style="margin: 0;">⚛️ QUANTUM FINAL: Баян-Өлгий AI Кеңесшісі ⛰️</h1>
</div>
<div style="margin: 15px 0; padding: 10px; border: 2px solid {'#FF5733' if 'ҚАУІПСІЗДІК' in initial_warning else '#33FF57'}; border-radius: 5px; background-color: #f0f0f0;">
<h3 style="margin: 0; color: #333;">{initial_warning.split(':')[0]}</h3>
<p style="white-space: pre-wrap; margin: 5px 0 0 0; color: #555;">{initial_warning.split(':')[1] if len(initial_warning.split(':')) > 1 else initial_warning}</p>
</div>
"""
)
with gr.Tabs():
# --- 1. Ауа Райы & Карта ---
with gr.TabItem("🌤️ Ауа Райы, Талдау & Карта"):
gr.Markdown(f"### Баян-Өлгий үшін ең сенімді 7 күндік болжам")
# Толық деректер кестесі
gr.DataFrame(
value=initial_df,
headers=list(initial_df.columns),
row_count="dynamic",
interactive=False,
label="Ауа Райының Толық Деректері (Жел, Қар, Аяз)",
wrap=True,
type="pandas"
)
# Қазақша Болжам/Талдауды көрсету
gr.Markdown("### 🧠 Quantum Талдауы (Қазақша)")
gr.Markdown(initial_analysis)
gr.Markdown("### 🗺️ Баян-Өлгий Картасы")
gr.HTML(f"""
<iframe
width="100%" height="300" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
src="http://maps.google.com/maps?q=48.97,89.97&z=10&output=embed0{BAYAN_ULGII_LAT},{BAYAN_ULGII_LON}&z=10&output=embed">
</iframe>
""")
# --- 2. ML Қолданбалары (Мамандандырылған Болжамдар) ---
with gr.TabItem("🔬 ML Болжамдары (Өсімдік, Мал, Қоқыс)"):
gr.Markdown("### 🔬 Мамандандырылған Модельдермен Талдау (Қазақша)")
with gr.Row():
# Мал Ауруын Анықтау
with gr.Column():
gr.Markdown("#### 🐑 Мал Ауруын Анықтау (ShuffleNet V2)")
input_image_animal = gr.Image(type="pil", label="Мал суретін жүктеу")
output_text_animal = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False)
classify_btn_animal = gr.Button("Ауруды Анықтау")
classify_btn_animal.click(fn=lambda img: classify_image(img, task="animal"), inputs=input_image_animal, outputs=output_text_animal)
# Өсімдік Түрін/Ауруын Анықтау
with gr.Column():
gr.Markdown("#### 🌱 Өсімдік Түрін/Ауруын Анықтау (ShuffleNet V2)")
input_image_plant = gr.Image(type="pil", label="Өсімдік суретін жүктеу")
output_text_plant = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False)
classify_btn_plant = gr.Button("Түрін/Ауруын Анықтау")
classify_btn_plant.click(fn=lambda img: classify_image(img, task="plant"), inputs=input_image_plant, outputs=output_text_plant)
gr.Markdown("---")
# Қоқыс Түрін Анықтау
gr.Markdown("#### 🗑️ Қоқыс Түрін Анықтау (EfficientNet B0)")
with gr.Row():
input_image_trash = gr.Image(type="pil", label="Қоқыс суретін жүктеу")
output_text_trash = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False)
classify_btn_trash = gr.Button("Түрін Анықтау")
classify_btn_trash.click(fn=lambda img: classify_image(img, task="trash"), inputs=input_image_trash, outputs=output_text_trash)
# --- 3. Анықтамалық Сөздік ---
with gr.TabItem("📚 Анықтамалық Сөздік"):
gr.Markdown("### 📚 Ауылшаруашылық Терминдері")
gr.Markdown("""
* **Жайлау:** Жыл мезгіліне байланысты мал жайылатын жер.
* **Қыстақ:** Қысқы уақытта малды ұстайтын жылы жер.
* **Күйіс қайыру:** Малдың жеген шөбін қайта ауызға шығарып шайнауы.
""")
# Уақытты әр минут сайын жаңарту (Ауа райы емес, тек сағат)
demo.load(get_current_time, None, current_time_display, every=60)
demo.launch() |