Spaces:
Sleeping
Sleeping
File size: 6,199 Bytes
33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 33f1e89 6ace570 d40bc97 6ace570 33f1e89 6ace570 33f1e89 |
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 |
import os
import gradio as gr
from google import genai
from google.genai import types
from PIL import Image
import io
import base64
# 載入環境變數(本機開發時需要)
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass
# 配置Google AI
def configure_google_ai():
"""配置Google AI API"""
api_key = os.getenv("GOOGLE_API_KEY")
if not api_key:
raise ValueError("請設定GOOGLE_API_KEY環境變數")
# 使用新的 Gen AI 客戶端
client = genai.Client(api_key=api_key)
return client
# 初始化模型
try:
client = configure_google_ai()
model_name = "gemini-1.5-flash"
except Exception as e:
print(f"警告:無法初始化Google AI模型 - {e}")
client = None
def analyze_food_calories(image):
"""
分析圖片中的食物並估算卡路里
Args:
image: PIL Image 物件
Returns:
str: 分析結果
"""
if client is None:
return "錯誤:Google AI模型未正確初始化,請檢查API KEY設定"
try:
# 將圖片轉換為 base64
img_byte_arr = io.BytesIO()
image.save(img_byte_arr, format='PNG')
img_byte_arr = img_byte_arr.getvalue()
img_base64 = base64.b64encode(img_byte_arr).decode('utf-8')
# 準備提示詞
prompt = """
請分析這張圖片中的內容:
1. 首先判斷圖片中是否包含食物
2. 如果不是食物,請回答:「這個不是食物」
3. 如果是食物,請:
- 識別食物種類
- 估算大概的份量
- 計算大概的卡路里含量
- 以繁體中文回答
請以以下格式回答:
- 食物名稱:[食物名稱]
- 估算份量:[份量描述]
- 預估卡路里:[卡路里數值] 大卡
- 營養說明:[簡短的營養價值說明]
如果不是食物,就直接回答「這個不是食物」。
"""
# 建立內容,包含文字和圖片
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text=prompt),
types.Part.from_bytes(
data=img_byte_arr,
mime_type="image/png"
)
]
)
]
# 生成回應
response = client.models.generate_content(
model=model_name,
contents=contents,
config=types.GenerateContentConfig(
temperature=0.4,
max_output_tokens=1024,
)
)
if response.text:
return response.text
else:
return "無法生成回應"
except Exception as e:
return f"分析時發生錯誤:{str(e)}"
def process_image(image):
"""
處理上傳的圖片
Args:
image: Gradio上傳的圖片
Returns:
str: 分析結果
"""
if image is None:
return "請上傳一張圖片"
try:
# 確保圖片是PIL Image格式
if isinstance(image, str):
# 如果是路徑字串,載入圖片
pil_image = Image.open(image)
else:
pil_image = image
# 分析圖片
result = analyze_food_calories(pil_image)
return result
except Exception as e:
return f"處理圖片時發生錯誤:{str(e)}"
# 建立Gradio介面
def create_interface():
"""建立Gradio使用者介面"""
# 自訂CSS樣式
css = """
.gradio-container {
font-family: 'Microsoft JhengHei', sans-serif;
}
.title {
text-align: center;
color: #2E7D32;
margin-bottom: 20px;
}
.description {
text-align: center;
color: #666;
margin-bottom: 30px;
}
"""
with gr.Blocks(css=css, title="食物卡路里檢測器") as demo:
gr.HTML("<h1 class='title'>🍎 食物卡路里檢測器</h1>")
gr.HTML("<p class='description'>上傳食物照片,AI會幫你識別食物種類並估算卡路里含量</p>")
with gr.Row():
with gr.Column():
# 圖片上傳元件
image_input = gr.Image(
label="上傳食物照片",
type="pil",
height=400
)
# 分析按鈕
analyze_btn = gr.Button(
"🔍 分析卡路里",
variant="primary",
size="lg"
)
with gr.Column():
# 結果顯示
result_output = gr.Textbox(
label="分析結果",
lines=10,
placeholder="上傳圖片後點擊分析按鈕...",
interactive=False
)
# 使用說明
gr.HTML("""
<div style="margin-top: 30px; padding: 20px; background-color: #f5f5f5; border-radius: 10px;">
<h3>📋 使用說明:</h3>
<ul>
<li>📸 上傳一張包含食物的清晰照片</li>
<li>🤖 AI會自動識別食物種類</li>
<li>📊 獲得卡路里估算和營養資訊</li>
<li>⚠️ 如果不是食物,系統會提醒您</li>
</ul>
<p><strong>注意:</strong>卡路里估算僅供參考,實際數值可能因烹飪方式和份量而有所差異。</p>
</div>
""")
# 設定事件處理
analyze_btn.click(
fn=process_image,
inputs=[image_input],
outputs=[result_output]
)
# 也可以在上傳圖片後自動分析
image_input.change(
fn=process_image,
inputs=[image_input],
outputs=[result_output]
)
return demo
# 主程式
if __name__ == "__main__":
# 建立介面
demo = create_interface()
# 啟動應用
# HuggingFace Spaces 使用預設設定
demo.launch() |