Spaces:
Sleeping
Sleeping
File size: 9,280 Bytes
7c8b3aa 68acfb6 a419469 8ae9faf 68acfb6 cf2b6fd 68acfb6 245f5a7 cf2b6fd fe926b7 4a65ba6 8ae9faf 96ad7d9 cf2b6fd 68acfb6 8ae9faf 245f5a7 96ad7d9 245f5a7 96ad7d9 245f5a7 96ad7d9 245f5a7 cf2b6fd 63782d6 cf2b6fd 8ae9faf 68acfb6 96ad7d9 8ae9faf 68acfb6 8ae9faf cf2b6fd 96ad7d9 5be1df3 e0a018b 5f66e0b 96ad7d9 5f66e0b 68acfb6 8ae9faf cf2b6fd 96ad7d9 cf2b6fd 96ad7d9 f728bc5 cf2b6fd f728bc5 cf2b6fd 96ad7d9 cf2b6fd f728bc5 245f5a7 f728bc5 e0a018b cf2b6fd 7c8b3aa | 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 |
import gradio as gr
from collections import Counter
from transformers import AutoImageProcessor, AutoModelForImageClassification
from PIL import Image
import torch
import math
# ============================== (همان پارامترها و توابع قبلی)
material_params = {
"brick": {"alpha": 0.3, "eps": 0.9, "I": 1600},
"stone": {"alpha": 0.25, "eps": 0.92, "I": 2000},
"polishedstone": {"alpha": 0.2, "eps": 0.9, "I": 2100},
"concrete": {"alpha": 0.35, "eps": 0.9, "I": 1800},
"metal": {"alpha": 0.5, "eps": 0.2, "I": 4000},
"glass": {"alpha": 0.1, "eps": 0.85, "I": 1500},
"wood": {"alpha": 0.35, "eps": 0.9, "I": 800},
"tile": {"alpha": 0.4, "eps": 0.9, "I": 1200},
"ceramic": {"alpha": 0.45, "eps": 0.92, "I": 1300},
"painted": {"alpha": 0.3, "eps": 0.9, "I": 1000},
"plastic": {"alpha": 0.1, "eps": 0.95, "I": 800},
"paper": {"alpha": 0.6, "eps": 0.95, "I": 500},
"mirror": {"alpha": 0.7, "eps": 0.1, "I": 2000},
"foliage": {"alpha": 0.25, "eps": 0.98, "I": 900},
"water": {"alpha": 0.06, "eps": 0.98, "I": 4200},
}
material_categories = {
"facade": {"members": ["brick", "stone", "polishedstone", "concrete", "tile", "ceramic", "painted"],
"candidates": ["brick", "stone", "polishedstone", "concrete", "tile", "ceramic", "painted"]},
"glazing": {"members": ["glass", "mirror"], "candidates": ["glass", "mirror"]},
"metallic": {"members": ["metal"], "candidates": ["metal"]},
"coverings": {"members": ["plastic", "paper", "fabric"], "candidates": ["plastic", "paper", "fabric"]},
"wood_elements": {"members": ["wood"], "candidates": ["wood"]},
"vegetation": {"members": ["foliage"], "candidates": ["foliage"]},
"water_bodies": {"members": ["water"], "candidates": ["water"]},
}
replacement_text = {
"facade": {"brick": "آجر روشن یا نمای سرامیکی/تایل روشن با پوشش بازتابی (cool coating)",
"stone": "سنگ روشن یا سنگ با پوشش بازتابی",
"polishedstone": "سنگ مات روشن یا سرامیک نما روشن",
"concrete": "بتن روشن با پوشش بازتابی یا موزاییک نما روشن",
"tile": "کاشی/سرامیک روشن یا متخلخل",
"ceramic": "سرامیک روشن با نمای بازتابی",
"painted": "رنگ بازتابی (cool paint) یا پوشش نانو بازتابی"},
"glazing": {"glass": "شیشه دو جداره با پوشش Low-E یا شیشه بازتابی کنترلشده",
"mirror": "شیشه مات یا شیشه Low-E با فریم عایق"},
"metallic": {"metal": "آلومینیوم رنگ روشن یا پوشش پودری با بازتاب بالا"},
"coverings": {"plastic": "سنگ سبک یا چوب روکشدار روشن (بسته به کاربرد)",
"paper": "در نما کاربرد معمول ندارد - بررسی بهینهسازی طراحی",
"fabric": "پارچه با روکش بازتابی یا سایهانداز طبیعی"},
"wood_elements": {"wood": "چوب رنگ روشن یا چوب با روکش بازتابی/محافظ"},
"vegetation": {"foliage": None},
"water_bodies": {"water": None},
}
# ============================== (توابع کمکی)
def ET_proxy(T, RH):
es = 0.6108 * math.exp((17.27 * T) / (T + 237.3))
return es * (1 - RH / 100.0)
def calc_deltaT(material, T_air, RH=40, u=2, S=700):
if material not in material_params: return 0.0
alpha, eps, I = material_params[material]["alpha"], material_params[material]["eps"], material_params[material]["I"]
A, B, C, D = 1.0, 0.4, 0.8, 0.015
h_c = 5.8 + 4.1 * u
if material == "foliage":
C_m = A * (1 - alpha) - D * ET_proxy(T_air, RH)
else:
C_m = A * (1 - alpha) + B * (1 - eps) + (C / math.sqrt(max(I, 1)))
gamma = S / max(h_c, 1e-6)
return gamma * C_m / 1000.0
# ============================== (بارگذاری مدل)
model_id = "prithivMLmods/Minc-Materials-23"
processor = AutoImageProcessor.from_pretrained(model_id)
model = AutoModelForImageClassification.from_pretrained(model_id)
patch_size = 224
def get_patches(image, size=224, stride=100):
patches = []
w, h = image.size
for scale in [1.0, 0.75, 0.5]:
scaled_w, scaled_h = int(w * scale), int(h * scale)
if min(scaled_w, scaled_h) < size: continue
scaled_img = image.resize((scaled_w, scaled_h), Image.Resampling.LANCZOS)
for i in range(0, scaled_w, stride):
for j in range(0, scaled_h, stride):
box = (i, j, min(i+size, scaled_w), min(j+size, scaled_h))
patch = scaled_img.crop(box)
if patch.size[0] >= size and patch.size[1] >= size:
patches.append(patch)
return patches
# ============================== (تابع اصلی Gradio)
def analyze_image(image, T_air=32.0, RH=40, u=2.0, S=700):
patches = get_patches(image, size=patch_size)
all_predictions = []
for patch in patches:
inputs = processor(images=patch, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
top1 = torch.argmax(probs[0]).item()
label = model.config.id2label[top1]
all_predictions.append(label)
counter = Counter(all_predictions)
total_patches = len(patches)
MIN_COUNT = 3
ignore_classes = ["food", "skin", "other", "wallpaper", "carpet","sky"]
materials_found = {label for label, count in counter.items() if count >= MIN_COUNT and label not in ignore_classes}
if len(materials_found) == 0:
return "هیچ مصالح معتبرِ کافی در تصویر شناسایی نشد (حداقل تکرار MIN_COUNT رعایت نمیشود)."
material_info = {}
for label in sorted(materials_found):
count = counter[label]
share = count / total_patches
dT = calc_deltaT(label, T_air, RH, u, S)
material_info[label] = {"count": count, "share": share, "deltaT": dT}
# مقایسه دروندستهای و توصیه
IMPROVEMENT_THRESHOLD = 0.02
SHARE_IMPORTANCE_THRESHOLD = 0.03
recommendations = []
candidate_delta_cache = {}
for cat, info in material_categories.items():
for candidate in info["candidates"]:
if candidate not in candidate_delta_cache:
candidate_delta_cache[candidate] = calc_deltaT(candidate, T_air, RH, u, S)
for label, info in material_info.items():
found_category = None
for cat, cinfo in material_categories.items():
if label in cinfo["members"]:
found_category = cat
break
if found_category is None:
recommendations.append(f"{label}: در دستههای پیشتعریف قرار ندارد.")
continue
candidates = material_categories[found_category]["candidates"]
cand_list = [(c, candidate_delta_cache.get(c, calc_deltaT(c, T_air, RH, u, S))) for c in candidates]
cand_list.sort(key=lambda x: x[1])
current_dT = info["deltaT"]
best_candidate, best_dT = cand_list[0]
improvement = current_dT - best_dT
share_pct = info["share"] * 100
if improvement >= IMPROVEMENT_THRESHOLD and best_candidate != label:
importance = "High" if info["share"] >= SHARE_IMPORTANCE_THRESHOLD else "Optional"
suggestion_text = replacement_text.get(found_category, {}).get(best_candidate, f"Consider replacing with {best_candidate}")
recommendations.append(
f"{label} ({found_category}): ΔT={current_dT:+.2f}°C → جایگزین: {best_candidate} (ΔT={best_dT:+.2f}°C) | بهبود: {improvement:+.2f}°C | اهمیت: {importance} | پیشنهاد: {suggestion_text}"
)
else:
recommendations.append(f"{label}: ΔT={current_dT:+.2f}°C → نیازی به جایگزینی ندارد.")
scene_deltaT = sum([info["share"] * info["deltaT"] for info in material_info.values()])
recommendations.append(f"ΔT میانگین وزنی کل صحنه: {scene_deltaT:+.2f}°C")
recommendations.append(f"دمای مؤثر سطح: {T_air + scene_deltaT:.2f}°C")
return "\n".join(recommendations)
# ============================== (راهاندازی رابط Gradio)
iface = gr.Interface(
fn=analyze_image,
inputs=[
gr.Image(type="pil", label="آپلود تصویر"),
gr.Number(value=32.0, label="دمای هوا T_air (°C)"),
gr.Number(value=40, label="رطوبت نسبی RH (%)"),
gr.Number(value=2.0, label="سرعت باد u (m/s)"),
gr.Number(value=700, label="تابش خورشیدی S (W/m²)")
],
outputs=gr.Textbox(label="خروجی ΔT و توصیهها"),
title="تحلیل مصالح و ΔT سطحی",
description="آپلود تصویر ساختمان/محیط → نمایش ΔT مصالح و توصیه جایگزینی منطقی."
)
iface.launch() |