當我們嘗試在雲端環境執行電腦視覺專案時,最常遇到的不是程式碼錯誤,而是**「底層系統依賴」與「記憶體管理」**的挑戰。
Streamlit 網頁app
核心問題與解決方案
1. 解決「依賴地獄」 (Apt & OpenCV)
Streamlit Cloud 的 Debian 環境通常缺少 OpenCV 所需的圖形庫(如 libGL.so.1 和 libgthread-2.0.so.0)。
- 錯誤戰術: 在
packages.txt指定舊版套件,這會導致系統版本衝突(如libffi7缺失)。 - 正確戰術: * 清空 packages.txt,避免觸發系統層級的安裝失敗。
- 在 requirements.txt 中使用 opencv-python-headless,它不依賴系統圖形庫。
2. PyTorch 2.6+ 的安全性攔截
新版 PyTorch 預設禁止載入未經許可的自定義類別(如 YOLO 的模型結構)。- 解決方法: 使用
torch.serialization.add_safe_globals將DetectionModel加入白名單。
🛠️ 最終推薦的檔案結構
📄 requirements.txt (關鍵清單)
Plaintext
# 務必將 headless 版本置頂 opencv-python-headless==4.8.0.74 ultralytics==8.1.1 streamlit numpy==1.26.4 torch>=1.8.0 pillow scikit-image matplotlib
📄 8_🛸_辨識_yoloV8辨識_🐱.py (核心代碼)
Python
import streamlit as st
from skimage import io
import numpy as np
from ultralytics import YOLO
import matplotlib.pyplot as plt # 新增這一行
from ultralytics.utils.plotting import Annotator
from PIL import Image #1024
#新增20260310
import os
import sys
# 自動安裝缺失的系統庫 (針對 Streamlit Cloud 環境)
def install_packages():
try:
# 嘗試檢查是否有 libGL,若無則嘗試用 pip 補救或提醒
import cv2
except ImportError:
# 強制重新安裝 headless 版本確保路徑正確
subprocess.check_call([sys.executable, "-m", "pip", "install", "opencv-python-headless", "--force-reinstall"])
# 執行安裝
install_packages()
# 強制告訴環境我們不需要 GUI
os.environ["QT_QPA_PLATFORM"] = "offscreen"
# 【核心修正】告訴 PyTorch 許可 Ultralytics 的自定義類別
try:
from ultralytics.nn.tasks import DetectionModel
torch.serialization.add_safe_globals([DetectionModel])
except Exception:
pass
# 2. 如果系統找不到 libgthread,嘗試動態加載一個通用的 glib
# 這是一個小撇步,有時能讓 Python 內部機制跳過檢查
try:
import ctypes
ctypes.CDLL('libgthread-2.0.so.0', mode=os.RTLD_GLOBAL)
except Exception:
pass
import streamlit as st
st.title("上傳圖片辨識")
st.info("YOLO_V8), 80 個類別的物體檢測,這些類別包括人,動物,交通工具,家具等")
uploaded_file = st.file_uploader("上傳圖片", type=['jpg', 'jpeg', 'png', 'gif'])
colors_rgb = {str(i): ((i * 30) % 256, (i * 50) % 256, (i * 70) % 256) for i in range(30)}
if uploaded_file is not None:
image = io.imread(uploaded_file)
if image.shape[-1] == 4:
image = image[:, :, :3]
# 【關鍵修正 1】確保記憶體連續,否則 Annotator 會報錯
image = np.ascontiguousarray(image)
# 載入模型
pretrained_weights_path = './model/yolov8n.pt'
yolo = YOLO(pretrained_weights_path) # 建議直接載入,更簡潔
try:
results = yolo.predict(image)
st.subheader("檢測結果")
# 【關鍵修正 2】Annotator 應該放在迴圈外面,不然每一框都會蓋掉前一框
annotator = Annotator(image)
result_str = []
colors_count = 0
for result in results:
boxes = result.boxes
for box in boxes:
cls = int(box.cls[0])
xyxy = box.xyxy[0]
label = yolo.names[cls]
result_str.append(label)
# 繪製標籤
annotator.box_label(xyxy, label, colors_rgb.get(str(colors_count), (255, 0, 0)))
colors_count += 1
# 取得標註後的圖片 (BGR 轉 RGB)
img_result = annotator.result()
# 顯示圖片
st.image(img_result, caption="檢測結果", use_container_width=True)
st.write(f"偵測到物品: {', '.join(result_str)}")
except Exception as e:
st.error(f"預測過程中發生錯誤: {e}")
💡 部署小秘帖
- 記憶體節省: 如果 App 出現
Connection Reset,請嘗試移除requirements.txt中不必要的套件(如tensorflow),因為 Streamlit Cloud 免費版只有 1GB RAM。 - 快取機制: 務必使用
@st.cache_resource載入模型,否則每次上傳圖片都會重新載入一次模型,非常吃效能。 - 色彩管理: YOLO 預設使用 BGR 格式,而
skimage或PIL使用 RGB。若顏色看起來怪怪的,記得檢查顏色通道轉換。





















