昨天我們讓 AI 看懂一張圖並描述內容。
今天更進一步 —— 做一個 Image Captioning 小工具,能為多張圖片自動產生標題/說明,適合相簿、商品圖片、知識庫圖像標註等情境。
.jpg/.jpeg/.png
圖片captions.csv
,日後可匯入 CMS/相簿import os, base64, mimetypes
import pandas as pd
from glob import glob
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
MODEL = "gpt-4o-mini"
IMAGE_DIR = "images" # 放圖片的資料夾
OUTPUT_CSV = "captions.csv" # 產出結果
PROMPT_TITLE = "請用最精煉的一句繁體中文,為這張圖片產生一個吸睛標題(不超過20字)。"
PROMPT_DESC = "再用 2-3 句繁體中文描述圖片重點與氛圍,避免主觀臆測與不確定資訊。"
def to_data_uri(path: str) -> str:
mime, _ = mimetypes.guess_type(path)
if mime is None:
# 依副檔名猜測,fallback
if path.lower().endswith(".png"):
mime = "image/png"
else:
mime = "image/jpeg"
with open(path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("utf-8")
return f"data:{mime};base64,{b64}"
def caption_one(image_path: str) -> dict:
data_uri = to_data_uri(image_path)
# 一次送兩個子任務:標題 + 說明
resp = client.chat.completions.create(
model=MODEL,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": f"{PROMPT_TITLE}\n{PROMPT_DESC}"},
{"type": "image_url", "image_url": {"url": data_uri}},
],
}],
temperature=0.5,
max_tokens=220
)
text = resp.choices[0].message.content.strip()
# 簡單切兩段(你也可改成 JSON 格式更穩)
# 期待模型回覆格式:
# 標題:xxx
# 說明:yyy
title, desc = "", ""
for line in text.splitlines():
s = line.strip()
if s.startswith("標題:"):
title = s.replace("標題:", "").strip()
elif s.startswith("說明:"):
desc = s.replace("說明:", "").strip()
# 若模型未嚴格遵守格式,退回全文為說明,並抓首句當標題
if not title:
title = text.split("。")[0].replace("\n", " ").strip()[:20]
if not desc:
desc = text
return {"file": os.path.basename(image_path), "title": title, "desc": desc}
def main():
os.makedirs(IMAGE_DIR, exist_ok=True)
paths = []
for ext in ("*.jpg", "*.jpeg", "*.png"):
paths.extend(glob(os.path.join(IMAGE_DIR, ext)))
if not paths:
print(f"請把圖片放到資料夾:{IMAGE_DIR}/ 再執行")
return
rows = []
for i, p in enumerate(paths, 1):
print(f"[{i}/{len(paths)}] 處理:{p}")
try:
rows.append(caption_one(p))
except Exception as e:
rows.append({"file": os.path.basename(p), "title": "", "desc": f"ERROR: {e}"})
df = pd.DataFrame(rows, columns=["file", "title", "desc"])
df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig")
print(f"完成!已輸出 {OUTPUT_CSV}(共 {len(df)} 筆)")
if __name__ == "__main__":
main()
像我們昨天給出了一張正在打球的圖片,看他會輸出什麼給我們:
我們可調整的小技巧像是:
控制語氣:把 PROMPT_TITLE/PROMPT_DESC 改得更生活一點
輸出結構化:讓模型回傳 JSON,解析更穩
去除主觀:在系統指令加上避免猜測品牌或地點
成本最佳化:多張圖可以用 批次處理,也可調低 max_tokens
今天完成了可以批次為圖片生成標題與說明的工具:
Vision 讀圖之後讓Caption 產生最後存成 CSV
可用於知識庫、商品圖、旅遊相簿等情境
明天我們要把這些文字變成簡報大綱,直接讓 GPT 幫你把一篇文章或多張圖片的描述,整理成PPT 架構!