使用 OpenCV DNN 與 DenseNet-121 模型進行圖片分類
使用 OpenCV DNN 與 DenseNet-121 模型進行圖片分類教學
在這篇教學中,我將帶你一步步使用 OpenCV 的 DNN 模組,搭配 DenseNet-121 預訓練模型,對圖片進行物件分類。無論你是初學者還是有些基礎,這份教學都能幫助你快速上手。
一、準備工作
1. 安裝環境
請先確定你已安裝以下套件:
pip install opencv-python numpy
注意:建議使用 OpenCV 4.5 以上版本,因為較新版改善了 DNN 模組的穩定性和功能。
2. 下載模型與資料
- DenseNet_121.caffemodel:模型權重檔
- DenseNet_121.prototxt:網路結構描述檔
- classification_classes_ILSVRC2012.txt:分類名稱清單(ImageNet 1000 類)
請將以上檔案放到你的專案資料夾,例如:
ch03/
├─ models/
│ ├─ DenseNet_121.caffemodel
│ ├─ DenseNet_121.prototxt
│ └─ classification_classes_ILSVRC2012.txt
└─ images/
└─ cat3.jpg
重要提醒:
確認檔案副檔名正確,特別是 prototxt 檔不要誤加.txt,這會造成讀取失敗。
二、程式碼詳解
以下是完整範例程式碼,我會逐步說明每個部分的功能與用法。
import cv2
import numpy as np
# 模型與分類標籤路徑
model_path = r"ch03/models/DenseNet_121.caffemodel"
config_path = r"ch03/models/DenseNet_121.prototxt"
classifier_path = r"ch03/models/classification_classes_ILSVRC2012.txt"
# 讀取分類名稱
class_names = []
with open(classifier_path, 'r') as f:
for line in f.readlines():
# 分割逗號前的類別名稱並去除空白
class_names.append(line.split(',')[0].strip())
print(f"類別名稱數量:{len(class_names)}")
# 載入模型
model = cv2.dnn.readNet(model=model_path, config=config_path, framework="Caffe")
# 載入測試圖片
img = cv2.imread("ch03/images/cat3.jpg")
# 定義前處理函式與推論
def blobFromImage(img):
# 將圖片轉成標準輸入格式 blob
blob = cv2.dnn.blobFromImage(img, scalefactor=0.01, size=(224,224), mean=(104.0, 177.0, 123))
model.setInput(blob)
outputs = model.forward()
# 將輸出結果調成1000x1符合類別數
final_outputs = outputs[0].reshape(1000, 1)
return final_outputs
# 執行推論
final_outputs = blobFromImage(img)
# 定義 softmax 轉機率函式
def softmax(x):
e_x = np.exp(x - np.max(x)) # 減去最大值避免溢位
return e_x / e_x.sum()
probs = softmax(final_outputs)
final_probs = np.round(np.max(probs)*100, 2) # 最高機率(%)
label_id = np.argmax(probs) # 找出最高機率索引
out_name = class_names[label_id]
print(f"預測結果:{out_name},機率:{final_probs}%")
# 在圖片上顯示結果
cv2.putText(img, out_name, (25, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.putText(img, f"{final_probs}%", (25, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 顯示圖片
cv2.imshow("Prediction", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
程式碼重點說明
- 路徑設定:
model_path、config_path與classifier_path指向你的模型檔與分類檔案。 - 分類名稱讀取:將文字檔中每一行的類別名稱載入清單。
- 模型載入:利用 OpenCV 的
readNet載入 Caffe 格式模型。 - 圖片讀取:使用
cv2.imread載入欲分類圖片。 - 前處理與推論:將圖片轉成模型輸入 blob,執行前向推論得到輸出。
- softmax 機率計算:將模型輸出 logits 轉換成機率分佈。
- 結果顯示:在圖片上標記分類名稱與機率,並以視窗顯示。
三、注意事項
- 確定路徑與檔案名稱無誤,包括副檔名。
- 模型輸入尺寸必須與訓練時一致,DenseNet-121 通常是 224x224。
- 均值參數
(104.0, 177.0, 123)需與模型訓練時使用的設定相符。 - 若模型載入失敗,請檢查 OpenCV 版本與檔案完整性。
- 可以嘗試不同圖片測試,驗證模型效果。
四、結語
現在你已經完成了從讀取模型、處理圖片到輸出分類結果的完整流程。OpenCV DNN 模組讓部署深度學習模型變得簡單快速,不需要安裝 TensorFlow 或 PyTorch 等重量級框架。
如果你喜歡這篇教學,歡迎分享給更多朋友,或在留言區告訴我你的使用心得,也歡迎提出問題讓我協助解決!
祝你專案順利,玩得愉快!

留言
張貼留言