reyhane1222 commited on
Commit
f728bc5
·
verified ·
1 Parent(s): 65408cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -75
app.py CHANGED
@@ -8,22 +8,21 @@ import math
8
 
9
  # ============================== (همان پارامترها و توابع قبلی)
10
  material_params = {
11
- "brick": {"alpha": 0.3, "eps": 0.9, "I": 1600},
12
- "stone": {"alpha": 0.25, "eps": 0.92, "I": 2000},
13
- "polishedstone": {"alpha": 0.2, "eps": 0.9, "I": 2100},
14
- "concrete": {"alpha": 0.35, "eps": 0.9, "I": 1800},
15
- "metal": {"alpha": 0.5, "eps": 0.2, "I": 4000},
16
- "glass": {"alpha": 0.1, "eps": 0.85, "I": 1500},
17
- "wood": {"alpha": 0.35, "eps": 0.9, "I": 800},
18
- "tile": {"alpha": 0.4, "eps": 0.9, "I": 1200},
19
- "ceramic": {"alpha": 0.45, "eps": 0.92, "I": 1300},
20
- "painted": {"alpha": 0.3, "eps": 0.9, "I": 1000},
21
- "plastic": {"alpha": 0.1, "eps": 0.95, "I": 800},
22
- "paper": {"alpha": 0.6, "eps": 0.95, "I": 500},
23
- "mirror": {"alpha": 0.7, "eps": 0.1, "I": 2000},
24
- "foliage": {"alpha": 0.25, "eps": 0.98, "I": 900},
25
- "water": {"alpha": 0.06, "eps": 0.98, "I": 4200},
26
-
27
  }
28
 
29
  material_categories = {
@@ -35,27 +34,25 @@ material_categories = {
35
  "wood_elements": {"members": ["wood"], "candidates": ["wood"]},
36
  "vegetation": {"members": ["foliage"], "candidates": ["foliage"]},
37
  "water_bodies": {"members": ["water"], "candidates": ["water"]},
38
-
39
  }
40
 
41
  replacement_text = {
42
- "facade": {"brick": "آجر روشن یا نمای سرامیکی/تایل روشن با پوشش بازتابی (cool coating)",
43
  "stone": "سنگ روشن یا سنگ با پوشش بازتابی",
44
  "polishedstone": "سنگ مات روشن یا سرامیک نما روشن",
45
- "concrete": "بتن روشن با پوشش بازتابی یا موزاییک نما روشن",
46
  "tile": "کاشی/سرامیک روشن یا متخلخل",
47
  "ceramic": "سرامیک روشن با نمای بازتابی",
48
  "painted": "رنگ بازتابی (cool paint) یا پوشش نانو بازتابی"},
49
- "glazing": {"glass": "شیشه دو جداره با پوشش Low-E یا شیشه بازتابی کنترل‌شده",
50
  "mirror": "شیشه مات یا شیشه Low-E با فریم عایق"},
51
  "metallic": {"metal": "آلومینیوم رنگ روشن یا پوشش پودری با بازتاب بالا"},
52
- "coverings": {"plastic": "سنگ سبک یا چوب روکش‌دار روشن (بسته به کاربرد)",
53
- "paper": "در نما کاربرد معمول ندارد - بررسی بهینه‌سازی طراحی",
54
- "fabric": "پارچه با روکش بازتابی یا سایه‌انداز طبیعی"},
55
- "wood_elements": {"wood": "چوب رنگ روشن یا چوب با روکش بازتابی/محافظ"},
56
- "vegetation": {"foliage": None},
57
- "water_bodies": {"water": None},
58
-
59
  }
60
 
61
  # ============================== (توابع کمکی)
@@ -112,7 +109,7 @@ def analyze_image(image, T_air=32.0, RH=40, u=2.0, S=700):
112
  counter = Counter(all_predictions)
113
  total_patches = len(patches)
114
  MIN_COUNT = 3
115
- ignore_classes = ["food", "sky","skin", "other", "wallpaper", "carpet"]
116
  materials_found = {label for label, count in counter.items() if count >= MIN_COUNT and label not in ignore_classes}
117
 
118
  if len(materials_found) == 0:
@@ -124,63 +121,93 @@ def analyze_image(image, T_air=32.0, RH=40, u=2.0, S=700):
124
  share = count / total_patches
125
  dT = calc_deltaT(label, T_air, RH, u, S)
126
  material_info[label] = {"count": count, "share": share, "deltaT": dT}
127
- # ============================== (مقایسه درون‌دسته‌ای و توصیه)
128
- IMPROVEMENT_THRESHOLD = 0.02
129
- SHARE_IMPORTANCE_THRESHOLD = 0.03
130
- recommendations = []
131
- candidate_delta_cache = {}
132
-
133
- # محاسبه ΔT برای تمام candidate های هر دسته
134
- for cat, info in material_categories.items():
135
- # نادیده گرفتن دسته‌های با کمتر از 2 عضو
136
- if len(info["candidates"]) < 2:
137
- continue
138
- for candidate in info["candidates"]:
139
- if candidate not in candidate_delta_cache:
140
- candidate_delta_cache[candidate] = calc_deltaT(candidate, T_air, RH, u, S)
141
-
142
- # برای هر دسته، بهترین ΔT (خنک‌ترین) را پیدا می‌کنیم
143
- for cat, info in material_categories.items():
144
- # دسته‌های با کمتر از 2 عضو را نادیده می‌گیریم
145
- if len(info["candidates"]) < 2:
146
- continue
147
-
148
- # ΔT هر candidate
149
- cand_list = [(c, candidate_delta_cache[c]) for c in info["candidates"]]
150
- cand_list.sort(key=lambda x: x[1]) # کمترین ΔT اول
151
-
152
- best_candidate, best_dT = cand_list[0] # خنک‌ترین عضو
153
- for label in info["members"]:
154
- if label not in material_info:
 
 
 
 
 
 
 
 
 
 
155
  continue
156
- current_dT = material_info[label]["deltaT"]
 
 
 
 
 
 
157
  improvement = current_dT - best_dT
158
- share_pct = material_info[label]["share"] * 100
159
-
160
- if improvement >= IMPROVEMENT_THRESHOLD and label != best_candidate:
161
- importance = "High" if material_info[label]["share"] >= SHARE_IMPORTANCE_THRESHOLD else "Optional"
162
- suggestion_text = replacement_text.get(cat, {}).get(best_candidate, f"Consider replacing with {best_candidate}")
 
163
  recommendations.append(
164
- f"{label} ({cat}): ΔT={current_dT:+.2f}°C → جایگزین: {best_candidate} (ΔT={best_dT:+.2f}°C) | بهبود: {improvement:+.2f}°C | اهمیت: {importance} | پیشنهاد: {suggestion_text}"
 
 
 
165
  )
166
  else:
167
- recommendations.append(f"{label}: ΔT={current_dT:+.2f}°C نیازی به جایگزینی ن��ارد.")
168
-
169
-
 
 
 
 
 
 
 
 
170
 
171
  # ============================== (راه‌اندازی رابط Gradio)
172
  iface = gr.Interface(
173
  fn=analyze_image,
174
  inputs=[
175
- gr.Image(type="pil", label="آپلود تصویر"),
176
- gr.Number(value=32.0, label="دمای هوا T_air (°C)"),
177
- gr.Number(value=40, label="رطوبت نسبی RH (%)"),
178
- gr.Number(value=2.0, label="سرعت باد u (m/s)"),
179
- gr.Number(value=700, label="تابش خورشیدی S (W/m²)")
180
  ],
181
- outputs=gr.Textbox(label="خروجی ΔT و توصیه‌ها"),
182
- title="تحلیل مصالح و ΔT سطحی",
183
- description="آپلود تصویر ساختمان/محیط نمایش ΔT مصالح و توصیه جایگزینی منطقی."
 
184
  )
185
 
186
- iface.launch()
 
 
8
 
9
  # ============================== (همان پارامترها و توابع قبلی)
10
  material_params = {
11
+ "brick": {"alpha": 0.3, "eps": 0.9, "I": 1600, "name": "آجر"},
12
+ "stone": {"alpha": 0.25, "eps": 0.92, "I": 2000, "name": "سنگ"},
13
+ "polishedstone": {"alpha": 0.2, "eps": 0.9, "I": 2100, "name": "سنگ صیقلی"},
14
+ "concrete": {"alpha": 0.35, "eps": 0.9, "I": 1800, "name": "بتن"},
15
+ "metal": {"alpha": 0.5, "eps": 0.2, "I": 4000, "name": "فلز"},
16
+ "glass": {"alpha": 0.1, "eps": 0.85, "I": 1500, "name": "شیشه"},
17
+ "wood": {"alpha": 0.35, "eps": 0.9, "I": 800, "name": "چوب"},
18
+ "tile": {"alpha": 0.4, "eps": 0.9, "I": 1200, "name": "کاشی"},
19
+ "ceramic": {"alpha": 0.45, "eps": 0.92, "I": 1300, "name": "سرامیک"},
20
+ "painted": {"alpha": 0.3, "eps": 0.9, "I": 1000, "name": "سطح رنگ‌شده"},
21
+ "plastic": {"alpha": 0.1, "eps": 0.95, "I": 800, "name": "پلاستیک"},
22
+ "paper": {"alpha": 0.6, "eps": 0.95, "I": 500, "name": "کاغذ"},
23
+ "mirror": {"alpha": 0.7, "eps": 0.1, "I": 2000, "name": "آینه"},
24
+ "foliage": {"alpha": 0.25, "eps": 0.98, "I": 900, "name": "گیاهان"},
25
+ "water": {"alpha": 0.06, "eps": 0.98, "I": 4200, "name": "آب"},
 
26
  }
27
 
28
  material_categories = {
 
34
  "wood_elements": {"members": ["wood"], "candidates": ["wood"]},
35
  "vegetation": {"members": ["foliage"], "candidates": ["foliage"]},
36
  "water_bodies": {"members": ["water"], "candidates": ["water"]},
 
37
  }
38
 
39
  replacement_text = {
40
+ "facade": {"brick": "آجر روشن یا نمای سرامیکی/تایل روشن با پوشش بازتابی",
41
  "stone": "سنگ روشن یا سنگ با پوشش بازتابی",
42
  "polishedstone": "سنگ مات روشن یا سرامیک نما روشن",
43
+ "concrete": "بتن روشن با پوشش بازتابی",
44
  "tile": "کاشی/سرامیک روشن یا متخلخل",
45
  "ceramic": "سرامیک روشن با نمای بازتابی",
46
  "painted": "رنگ بازتابی (cool paint) یا پوشش نانو بازتابی"},
47
+ "glazing": {"glass": "شیشه دو جداره با پوشش Low-E",
48
  "mirror": "شیشه مات یا شیشه Low-E با فریم عایق"},
49
  "metallic": {"metal": "آلومینیوم رنگ روشن یا پوشش پودری با بازتاب بالا"},
50
+ "coverings": {"plastic": "سنگ سبک یا چوب روکش‌دار روشن",
51
+ "paper": "مواد پوششی بازتابی",
52
+ "fabric": "پارچه با روکش بازتابی"},
53
+ "wood_elements": {"wood": "چوب رنگ روشن یا چوب با روکش بازتابی"},
54
+ "vegetation": {"foliage": "حفظ پوشش گیاهی طبیعی"},
55
+ "water_bodies": {"water": "حفظ منابع آبی"},
 
56
  }
57
 
58
  # ============================== (توابع کمکی)
 
109
  counter = Counter(all_predictions)
110
  total_patches = len(patches)
111
  MIN_COUNT = 3
112
+ ignore_classes = ["food", "skin", "other", "wallpaper", "carpet"]
113
  materials_found = {label for label, count in counter.items() if count >= MIN_COUNT and label not in ignore_classes}
114
 
115
  if len(materials_found) == 0:
 
121
  share = count / total_patches
122
  dT = calc_deltaT(label, T_air, RH, u, S)
123
  material_info[label] = {"count": count, "share": share, "deltaT": dT}
124
+
125
+ # مقایسه درون‌دسته‌ای و توصیه - بخش اصلاح شده
126
+ IMPROVEMENT_THRESHOLD = 0.02
127
+ SHARE_IMPORTANCE_THRESHOLD = 0.03
128
+ recommendations = []
129
+
130
+ # سرتیتر نتایج
131
+ recommendations.append("📋 نتایج تحلیل مصالح:\n")
132
+
133
+ for label, info in material_info.items():
134
+ material_name = material_params[label]["name"]
135
+ share_pct = info["share"] * 100
136
+ current_dT = info["deltaT"]
137
+
138
+ recommendations.append(f"• {material_name}: سهم={share_pct:.1f}% | ΔT={current_dT:+.2f}°C")
139
+
140
+ recommendations.append("\n💡 توصیه‌های بهینه‌سازی:\n")
141
+
142
+ candidate_delta_cache = {}
143
+ for cat, info in material_categories.items():
144
+ for candidate in info["candidates"]:
145
+ if candidate not in candidate_delta_cache:
146
+ candidate_delta_cache[candidate] = calc_deltaT(candidate, T_air, RH, u, S)
147
+
148
+ for label, info in material_info.items():
149
+ material_name = material_params[label]["name"]
150
+ current_dT = info["deltaT"]
151
+ share = info["share"]
152
+
153
+ # پیدا کردن دسته
154
+ found_category = None
155
+ for cat, cinfo in material_categories.items():
156
+ if label in cinfo["members"]:
157
+ found_category = cat
158
+ break
159
+
160
+ if found_category is None:
161
+ recommendations.append(f"• {material_name}: در دسته‌های پیش‌تعریف قرار ندارد")
162
  continue
163
+
164
+ # پیدا کردن بهترین جایگزین
165
+ candidates = material_categories[found_category]["candidates"]
166
+ cand_list = [(c, candidate_delta_cache.get(c, calc_deltaT(c, T_air, RH, u, S))) for c in candidates]
167
+ cand_list.sort(key=lambda x: x[1])
168
+
169
+ best_candidate, best_dT = cand_list[0]
170
  improvement = current_dT - best_dT
171
+
172
+ if improvement >= IMPROVEMENT_THRESHOLD and best_candidate != label:
173
+ best_candidate_name = material_params[best_candidate]["name"]
174
+ importance = "بالا" if share >= SHARE_IMPORTANCE_THRESHOLD else "اختیاری"
175
+ suggestion = replacement_text.get(found_category, {}).get(best_candidate, "جایگزین بهینه")
176
+
177
  recommendations.append(
178
+ f" برای {material_name}:\n"
179
+ f" → پیشنهاد: {best_candidate_name} (ΔT={best_dT:+.2f}°C)\n"
180
+ f" → بهبود: {improvement:.2f}°C | اهمیت: {importance}\n"
181
+ f" → توصیه: {suggestion}"
182
  )
183
  else:
184
+ recommendations.append(f"{material_name}: از نظر حرارتی بهینه است")
185
+
186
+ # خلاصه نتایج
187
+ scene_deltaT = sum([info["share"] * info["deltaT"] for info in material_info.values()])
188
+
189
+ recommendations.append("\n📊 خلاصه نتایج:")
190
+ recommendations.append(f"• ΔT میانگین وزنی: {scene_deltaT:+.2f}°C")
191
+ recommendations.append(f"• دمای مؤثر سطح: {T_air + scene_deltaT:.2f}°C")
192
+ recommendations.append(f"• تعداد پچ‌های تحلیل شده: {total_patches}")
193
+
194
+ return "\n".join(recommendations)
195
 
196
  # ============================== (راه‌اندازی رابط Gradio)
197
  iface = gr.Interface(
198
  fn=analyze_image,
199
  inputs=[
200
+ gr.Image(type="pil", label="📷 تصویر نمای ساختمان"),
201
+ gr.Number(value=32.0, label="🌡️ دمای هوا (°C)"),
202
+ gr.Number(value=40, label="💧 رطوبت نسبی (%)"),
203
+ gr.Number(value=2.0, label="💨 سرعت باد (m/s)"),
204
+ gr.Number(value=700, label="☀️ تابش خورشیدی (W/m²)")
205
  ],
206
+ outputs=gr.Textbox(label="نتایج تحلیل", lines=20),
207
+ title="🏗️ تحلیل مصالح و توصیه اقلیمی",
208
+ description="این اپلیکیشن مصالح را از تصویر شناسایی کرده و ΔT سطح و پیشنهادهای جایگزینی را نمایش می‌دهد.",
209
+ allow_flagging="never"
210
  )
211
 
212
+ if __name__ == "__main__":
213
+ iface.launch(share=True, server_name="0.0.0.0", server_port=7860)