顯示具有 電腦視覺 標籤的文章。 顯示所有文章
顯示具有 電腦視覺 標籤的文章。 顯示所有文章

OpenCV 5.0 深拆——當 LLM 與 VLM 走進電腦視覺函式庫

三個引擎合流到單一 API 的視覺隱喻

2026 年 6 月,OpenCV 5.0 正式釋出。社群在 Hacker News 上熱烈討論了好幾天,距離 4.0(2018 年 11 月)整整八年——這個間距本身就說明這次改版的份量。

我花了幾天時間把 官方 release page 、GitHub OpenCV 5 wiki 、heise online 的解析 、Satya Mallick 在 Embedded Vision Summit 的簡報 全部過了一遍,這篇就把所有重點整合在一起,每個變更都附上技術意義與遷移建議。

如果你是現在還在維護 OpenCV 4.x 專案、或正在評估要不要升級的工程師,這篇就是寫給你的。

三個最反直覺的結論

我把所有更新讀過一輪後,三個變化讓我停下來重讀好幾次:

第一,OpenCV 自己內建了一套可以跑 VLM 的最小 runtime。Qwen 2.5、Gemma 3、PaliGemma 這些多模態模型現在能透過 cv::dnn::Net API 直接餵圖跟 prompt——不再需要 Hugging Face Transformers。第二,DNN 引擎 ONNX 操作覆蓋率從 ~22% 衝到 80%+,這數字背後意味著「PyTorch 模型 export ONNX 後在 OpenCV 跑得起來」這件事,終於從碰運氣變成預設可行。第三,C API 整個被連根拔起——任何還在用 IplImage、CvMat 的舊專案,5.0 連編都編不過。

其餘的改動(C++17 基線、HAL 重構、Features 模組翻新、bfloat16、N 維陣列)一樣有份量,但要看你做的場景。下面一項一項拆。

一、DNN 引擎重寫:從「將就用」變成「真的能用」

OpenCV 的 DNN 模組自 3.1 引入、3.3 升上主 repo 後,一直有個尷尬問題——它支援的 ONNX operator 太少。實務上你拿一個新的 PyTorch 模型 export 成 ONNX,用 cv2.dnn.readNetFromONNX 載入,大概率會吐 unsupported operator 錯誤。

5.0 怎麼解?官方把整個 DNN 引擎重寫,並引入「三引擎並存於同一個 Net API 之後」的設計:

cv::dnn::Net 統一 API
  └── engine = ENGINE_AUTO 自動選擇
        ├── 預設    → New Engine(重新設計,ONNX 80%+)
        ├── 向後相容 → Classic Engine(4.x 的舊引擎)
        └── 外部    → ORT Engine(ONNX Runtime backend)
  • New engine:原生重寫,ONNX 覆蓋率從 ~22% 提升到 80%+(數字來自 opencv.org 官方 5.0 頁面 )。
  • Classic engine:保留 4.x 的引擎做向後相容。
  • ORT engine:直接呼叫 ONNX Runtime 作為 backend,要 GPU 加速時走這條。

實務上你只要寫:

auto net = cv::dnn::readNet("yolo11.onnx");
// 想強制走特定引擎時:
net.setPreferableEngine(cv::dnn::ENGINE_NEW);  // 或 ENGINE_CLASSIC / ENGINE_ORT

一個小坑

New engine 目前只支援 CPU。要 GPU 加速,必須走 Classic engine + CUDA backend,或者 ORT engine + NVIDIA execution provider。官方表示後續版本會補上 New engine 的 GPU。

另外,Darknet 與 Caffe 解析器被完全移除——多數模型現在都已轉 ONNX,OpenCV 不再養這兩個古董。TFLite 仍可用,但只在 Classic engine 裡。

二、LLM / VLM 進場:OpenCV 第一次能說人話

這是 5.0 最讓我意外的設計。引述 OpenCV 5 官方 wiki 的描述:

The new engine includes the tokenizers and all necessary components: attention layers, decoding blocks, post-processing, KV-cache, to run VLMs end-to-end.

換句話說——OpenCV 5 自己內建了一套可以跑自迴歸解碼的最小 LLM runtime。heise online 整理 提到目前已驗證跑過的模型家族:

模型類型來源
Qwen 2.5LLM / VLM阿里巴巴
Gemma 3LLMGoogle
PaliGemma(部分支援)VLMGoogle

實務上你可以這樣寫:

import cv2

net = cv2.dnn.readNet("paligemma.onnx")
net.setInput(image_blob, "image")
net.setInput(prompt_tokens, "text")
output = net.forward()  # 回傳生成的描述 tokens

關鍵差別在於 「no separate runtime」——OpenCV 自帶 tokenizer 與 KV-cache,你不必再裝 Hugging Face Transformers,也不必額外起 vLLM / TGI 服務。一個 OpenCV 就解決從影像前處理到 VLM 描述輸出的整條 pipeline。這也是 opencv.org 對 VLM 模組 強調的設計目標。

視覺與語言融合的概念視覺化

這對工程意義是什麼?

對「邊緣裝置上做即時 VLM」這類場景影響最大。以前你要在 Jetson Orin Nano 上做「鏡頭即時描述場景」,得:

  1. OpenCV 抓幀
  2. 轉成 PIL Image
  3. 餵給 Hugging Face 的 processor
  4. 跑 transformer
  5. 把結果轉回 OpenCV 畫面

現在這 5 步合成 1 個 Net::forward()。記憶體佔用、跨程式呼叫成本、安裝依賴的負擔——全部砍掉。

不過必須誠實提醒:目前 New engine 仍是 CPU only,所以 LLM/VLM 推論在邊緣裝置上的速度會被 CPU 算力限制。要真正即時還是得走 ORT + GPU,或者等後續版本補上原生 GPU。

三、徹底移除 legacy C API

從 4.0 開始 OpenCV 就在棄用 C API,5.0 直接把它連根拔起。以下這些東西在 5.0 都消失:

移除項目替代方案
IplImage / CvMat 結構cv::Mat(2.0 起就存在)
cvCreateMat() / cvFindContours() C 函式cv::Mat 建構子 / cv::findContours()
CV_* 巨集(大量)名稱化 enum
include/opencv/ 標頭資料夾全部走 include/opencv2/
OpenVX 整合移除(業界使用率太低)
G-API 與經典 ML 模組移到 opencv_contrib(仍可裝)

升級時最常見的 4 種編譯錯

錯誤訊息原因解法
error: 'IplImage' was not declared舊 C API改 cv::Mat
error: 'cvWaitKey' was not declaredC 函式改 cv::waitKey()
'_aligned_malloc' was not declared缺 C++17加 -std=c++17
import error: cv2 has no attribute 'gapi'G-API 搬家裝 opencv-contrib-python 並改 import

我自己升 4 → 5 時最痛的是 macro 全面改名。以前 CV_8U、CV_32F 這些還留著,但 CV_RGB(r,g,b)、CV_FILLED 之類的 macro 都被改成 cv::Scalar(...) / cv::FILLED,要全文搜尋替換。

不要害怕,如果你想看完整的不相容清單,OpenCV 5 release page 的 migration guide 寫得很詳細。

四、新 HAL 與 Universal Intrinsics 2.0

Satya Mallick 在 Embedded Vision Summit 的簡報 裡,把 HAL(Hardware Acceleration Layer)列為「7 件 5.0 在解的事」之一。我們先看為什麼這層存在。

OpenCV 要在這些架構上跑:

  • Intel x86(SSE / AVX / AVX2 / AVX-512)
  • Arm(NEON、FP16、BF16、SVE)
  • Qualcomm(Hexagon DSP、FastCV)
  • RISC-V(RVV 1.0)
  • NVIDIA / AMD GPU

過去每加一種新指令集,要在演算法層手動寫多個版本。新 HAL 抽象化這層,加上 Universal Intrinsics 2.0——一段 C++ 程式碼,編譯時自動展開成對應平台的 SIMD 指令。

實務影響:

平台受益功能
RISC-V(如 LicheePi、StarFive)4.12 起就有 RVV 1.0 backend
Arm v8(Apple Silicon、Raspberry Pi 5)NEON FP16、BF16 加速
IntelOpenVINO 整合更深
QualcommFastCV 整合

對於想把 OpenCV 應用部署到邊緣裝置的人,這次的 HAL 重構等於把「為了 Pi 4 / Pi 5 / Jetson / RISC-V 各跑一套效能測試」這種地獄變成「寫一次到處跑」。

五、資料型別擴充與真正的 N 維陣列

4.x 的 cv::Mat 名義上支援多維,但實作上有很多限制——Mat::dims 與 Mat::rows、Mat::cols 的關係很尷尬,做 transformer 那種 N-D tensor 操作會撞牆。

5.0 新增的型別:

新型別對應 C++用途
CV_16BFcv::bfloatbfloat16,深度學習主流推論型別
CV_32Uuint32_t無號 32 位元
CV_64Uuint64_t無號 64 位元
CV_64Sint64_t有號 64 位元(大張量索引)
CV_Boolbool真正的布林矩陣

以前 4.x 用 CV_8U 來假裝 bool,現在有真的 CV_Bool,邏輯運算與遮罩可以清乾淨。

更重要的是 真正的 N 維陣列支援。cv::Mat::dims 可以是任意整數,配合新的 InputArray/OutputArray API,OpenCV 5 第一次能自然處理 transformer 的 [batch, seq, hidden] 這種張量。

六、Features 模組——傳統與深度學習特徵的世代交替

Features2D 模組從 OpenCV 2.x 就存在,裡面是 SIFT、SURF、ORB、AKAZE 這些經典算法。5.0 把它改名為 Features,並加入深度學習時代的特徵匹配:

演算法類型何時用
SIFT / ORB經典手刻特徵計算便宜、可解釋
ALIKEDDL 特徵比 SIFT 更穩
DISKDL 特徵室外場景、變化光線
LightGlueMatcherDL matcherattention-based,比 BFMatcher 強很多

heise online 寫得很傳神:「LightGlue uses attention mechanisms to match image features more robustly than classic methods.」

實務上 panorama 拼接、Visual SLAM、3D 重建這類需要 robust feature matching 的場景,現在可以從 SIFT 直接升級成 LightGlue,幾乎不用改 API。

升級策略:什麼時候升、什麼時候別升

升級不是越早越好。這張表是我自己的決策框架:

情境建議理由
新專案、用 Python直接 5.0沒有歷史包袱,享受新引擎與 LLM 整合
既有 4.x 純 C++ 專案、無 C API可升改 macro 就好,效能會提升
重度依賴 G-API暫緩G-API 搬到 contrib,需要重新 import
用 cv2 + CUDA GPU暫緩New engine CPU only,等 5.1
程式碼還有 IplImage / CvMat不能升C API 全砍,停在 4.x 維護分支
嵌入式裝置 / RISC-V可升HAL 重構大幅受益

OpenCV 同時維護 4.x 與 5.x 兩條 stable 分支,4.x 仍會收到 SIMD/HAL/codec 的 backport,給「不能立刻升級」的專案緩衝期。

我自己的判斷流程是這樣的:先在現有 codebase 跑一次 grep -rE 'IplImage|CvMat|cvCreateMat'——只要這個 grep 命中任何一行,5.0 就先別升,那些檔案先標起來慢慢翻。再跑 grep -rE 'setPreferableTarget.*CUDA'——如果命中、又是即時 30fps 以上的場景,等 5.1 GPU 完整補上比較穩。剩下的情境,新專案就直接 5.0 起步,沒什麼好猶豫的。

一些第一次接觸 5.0 會踩的坑

Q1:pip install opencv-python 還是裝到 4.x,怎麼辦?

截至 2026-06-23,PyPI 上的 opencv-python 預設仍可能解到 4.13.x(4.x 仍是維護線),要顯式指定:

pip install "opencv-python>=5.0"

不確定當下狀態時,先跑 pip index versions opencv-python 看一眼可用版本。或裝 opencv-python-headless(無 GUI 版,伺服器用)。

Q2:Python 端 cv2.findContours 回傳變了嗎?

沒有。4.0 已經改回 (contours, hierarchy) 兩元素,5.0 維持不變。

Q3:CUDA 加速怎麼設?

net = cv2.dnn.readNet("model.onnx")
net.setPreferableEngine(cv2.dnn.ENGINE_CLASSIC)  # 走舊引擎才能 CUDA
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

等 5.1 之後 New engine 的 GPU 補上,這段會簡化。

Q4:VLM 推論延遲大概多少?

官方還沒公布完整 benchmark。社群初步測試(Macbook M2、PaliGemma 3B FP16)大約是「一次推論幾秒」等級,遠不到即時。對「離線批次描述影像」尚可,對「即時直播導覽」還太慢。等 GPU 補上後會大不同。

Q5:升上去後編譯時間爆增

5.0 引入了較多 C++17 template,整體編譯時間比 4.x 約增加 15–25%。可以開 ccache 或限制 WITH_OPENVINO=OFF 之類的選項減負擔。

舊程式碼蛻變為現代架構

結語:OpenCV 重新證明了自己的戰略位置

寫這篇之前我其實對 5.0 持保留態度——畢竟業界已經有 ONNX Runtime、TensorRT、vLLM、Hugging Face Transformers 這些更專業的工具,OpenCV 要把 DNN 重做、把 LLM 塞進來,會不會太貪心?

但深入讀完官方文件、看完 Satya Mallick 的簡報、跑過幾個 demo 之後,我改變了想法。OpenCV 5 並不是想取代 ONNX Runtime——它是把「從相機到 LLM 描述輸出的端到端 pipeline」做成一個函式庫。對嵌入式工程師、邊緣 AI 開發者、機器人公司來說,少裝一套依賴、少維護一個程序、少一次跨進程通訊的成本,遠比「再多一個 VLM 框架」更重要。

更深一層的訊號是——一個 26 歲的開源函式庫,敢在 4.x 已經很穩定的情況下重寫核心引擎、改變最低 C++ 標準、把 LLM 納進來,本身就證明這個社群還有活力。很多老專案最後死於「不敢改」,OpenCV 用 5.0 證明它不在那個名單裡。

接下來幾個值得追的方向:

  • 5.1 的 GPU backend 完整補上後,VLM 邊緣推論才會真正可用
  • OpenCV Enterprise(路線圖提到的商業版)會不會改變開源節奏
  • OpenCV 5 + RISC-V 在中國本土晶片上的實測效能
  • Diffusion model 支援(5.0 已預告)對 generative CV 應用的影響

具體建議是這樣:純研究或新專案用 Python,今天就跑 pip install "opencv-python>=5.0";既有 4.x C++ 專案,先把 grep 跑過再決定升不升;嵌入式或 RISC-V 開發者,5.0 的 HAL 重構對你來說是免費效能升級,能跳就跳;重度 CUDA 推論場景,5.1 補上 New engine GPU 之前先別動。

延伸閱讀

2026 新手指南——用 30 行 Python + OpenCV 做完你的第一個電腦視覺專案

筆電 Webcam 即時 Canny 邊緣偵測

跟身邊很多想入門電腦視覺的朋友聊過,最常聽到的卡關點是這句:

「我看了一堆教學,但好像每個都要我先讀完線性代數、再讀完 CNN、再讀完 transformer,那我什麼時候才能跑出一張有結果的圖?」

懂,我也經歷過這個階段。所以這篇我直接反過來——先讓你看到結果,再回頭講原理。三個範例由淺到深:

  1. 第一天:Webcam 即時 Canny 邊緣偵測(約 14 行 Python)
  2. 第一週:拍一張紙、自動轉成 A4 PDF 的文件掃描器(約 35 行 Python)
  3. 第一個月:拿 YOLO11 接上 Webcam 做即時物件偵測(約 15 行 Python)

整篇文章我不會碰太重的數學,只在你需要踩坑時提醒一下。Code 全部可以直接複製貼上跑。

環境與前置條件

不囉嗦,先給你一個能用的環境:

項目建議版本說明
Python3.11 或 3.123.13 也行,但部分套件 wheel 可能還沒到位
OpenCVopencv-python==4.13.x寫這篇時最新;想嚐鮮 5.0 可改 opencv-python>=5.0
NumPy2.xOpenCV 從 4.11.0 起正式支援 NumPy 2.x,本文用 4.13
Ultralyticsultralytics>=8.3第三個範例用到 YOLO11
攝影機內建 Webcam 或 USB cammacOS 第一次跑要授權 Terminal/IDE 攝影機權限

裝環境一行解決:

python -m venv .venv && source .venv/bin/activate
pip install "opencv-python>=4.13" "numpy>=2.0" "ultralytics>=8.3"

如果你不確定 Webcam 跑不跑得起來,先存這個 5 行的「相機測試」:

import cv2
cap = cv2.VideoCapture(0)  # macOS 上有時要試 1、2
ok, frame = cap.read()
print("frame shape =", frame.shape if ok else "FAILED")
cap.release()

跑得出 shape 就代表 OK。跑不出來最常見原因是權限——macOS 去「系統設定 → 隱私權與安全性 → 攝影機」把你的 Terminal 打勾。

範例 1:Webcam 即時 Canny(第一天就能跑)

Canny 邊緣偵測 是電腦視覺的「Hello World」。它是 1986 年 John Canny 提出來的演算法,用兩個閾值找出影像中「梯度夠陡」的位置,這些位置就是邊緣。

import cv2

cap = cv2.VideoCapture(0)

while True:
    ok, frame = cap.read()
    if not ok:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 1.4)
    edges = cv2.Canny(blurred, 80, 160)
    cv2.imshow("Canny", edges)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

這 14 行東西就是一個即時邊緣偵測程式。按 q 退出。手動把鏡頭對著房間裡任何東西——書本、馬克杯、貓——你會看到輪廓被白色線條精準畫出來。

三個重點記下來

  • cvtColor(BGR2GRAY):OpenCV 讀進來的圖預設是 BGR(不是 RGB),這是 1999 年留下來的歷史包袱,別問為什麼,習慣就好。
  • GaussianBlur 是 Canny 前必做的去噪:不模糊一下,邊緣會一堆雜訊。
  • Canny(img, low, high) 的兩個閾值用「low ≈ high / 2」這個經驗法則調起,效果不好再 fine-tune。

邊緣偵測的視覺示範

範例 2:自動文件掃描器(第一週的成就感)

這是 PyImageSearch 入門系列 裡的經典題目。你拍一張歪歪的紙本文件,程式自動找到文件邊框、把它矯正成正面、輸出乾淨的掃描結果。要用到三個技巧的組合:Canny → findContours → warpPerspective。

import cv2
import numpy as np

def order_points(pts):
    rect = np.zeros((4, 2), dtype="float32")
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]      # 左上
    rect[2] = pts[np.argmax(s)]      # 右下
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]   # 右上
    rect[3] = pts[np.argmax(diff)]   # 左下
    return rect

img = cv2.imread("paper.jpg")
ratio = img.shape[0] / 800.0
small = cv2.resize(img, (int(img.shape[1] / ratio), 800))

gray = cv2.cvtColor(small, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 75, 200)

contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5]

doc_cnt = None
for c in contours:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    if len(approx) == 4:
        doc_cnt = approx
        break

if doc_cnt is None:
    raise RuntimeError("找不到文件四邊形——請拍張對比度高一點的照片再試")

pts = order_points(doc_cnt.reshape(4, 2) * ratio)
(tl, tr, br, bl) = pts
maxW = int(max(np.linalg.norm(br - bl), np.linalg.norm(tr - tl)))
maxH = int(max(np.linalg.norm(tr - br), np.linalg.norm(tl - bl)))

dst = np.array([[0, 0], [maxW - 1, 0], [maxW - 1, maxH - 1], [0, maxH - 1]], dtype="float32")
M = cv2.getPerspectiveTransform(pts, dst)
warped = cv2.warpPerspective(img, M, (maxW, maxH))

cv2.imwrite("scanned.jpg", warped)

把任何一張包含 A4 紙的照片存成 paper.jpg,跑一次,會吐出 scanned.jpg——一張矯正後的乾淨文件圖。

流程拆解

原始照片
  → 縮小 + 灰階
  → GaussianBlur
  → Canny 邊緣
  → findContours 找最大輪廓
  → approxPolyDP 拿四個角
  → order_points 排序角點
  → getPerspectiveTransform + warpPerspective 矯正
  → 輸出 scanned.jpg

常見踩坑

症狀原因解法
找不到四邊形邊緣斷裂 / 文件邊框不完整拍照時讓紙本與背景對比大;可改用 cv2.morphologyEx 補邊
矯正結果上下顛倒order_points 排序錯檢查 s 和 diff 的方向;OpenCV 座標 y 軸向下
顏色發黃沒做白平衡對 warped 再做 cv2.adaptiveThreshold 變黑白文件

文件掃描的透視變換概念

範例 3:YOLO11 + OpenCV,第一個月就能玩現代物件偵測

範例 2 教你用幾何方法處理靜態文件,但你應該已經想到下一個問題——「畫面裡到底有什麼東西」這個問題傳統 CV 沒辦法回答,因為它需要語意理解。這就是深度學習接手的地方。

到了 2026 年,光會傳統 CV 不夠——你要會把 OpenCV 跟現代深度學習模型接起來。最簡單的接法就是 Ultralytics YOLO,這套工具把訓練、推論、export 整個包成幾行 Python。

import cv2
from ultralytics import YOLO

model = YOLO("yolo11n.pt")  # 第一次跑會自動下載 nano 模型
cap = cv2.VideoCapture(0)

while True:
    ok, frame = cap.read()
    if not ok:
        break
    results = model(frame, verbose=False)
    annotated = results[0].plot()
    cv2.imshow("YOLO11 + OpenCV", annotated)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

15 行 Python,你的 Webcam 已經能即時辨識 80 類常見物件(人、貓、筆電、手機、椅子⋯⋯)。

為什麼這樣搭最聰明?

OpenCV 與 YOLO 是分工關係,不是替代關係:

  • OpenCV 負責:相機 I/O、影像前處理(resize、色彩空間)、後處理(畫框、寫字、輸出影片)
  • YOLO 負責:推論、給出 bounding box

如果你想做進階一點的「物件追蹤 + 計數 + 視覺化」,加上 Roboflow Supervision 這個套件會更省事——它是 model-agnostic 的,YOLO、SAM、Hugging Face Transformers 接哪個都一致。

Python vs C++:新手怎麼選?

這是入門最常糾結的問題。直接給你結論:

比較項PythonC++
學習曲線平緩陡到爆
開發速度快(Jupyter 互動式視覺化)慢
純 OpenCV 呼叫的執行速度跟 C++ 接近(底層仍是 C++)最快
自寫 for-loop 逐像素處理非常慢(必須改 NumPy 向量化)快
部署目標桌面、伺服器、Mac、PC嵌入式、即時、IoT

新手的話無腦選 Python。LearnOpenCV 在這篇對比文 也建議:「If you are a python programmer, use OpenCV with Python.」原因很簡單——Python 加 Jupyter Notebook 可以做到「改一行、馬上看到結果」,這對學 CV 是無可取代的優勢。

什麼時候才需要 C++?等你以後要把模型部署到 Jetson Nano、做即時 30fps 以上的工業檢測、或者自己寫像素級新演算法,再轉就好。多數應用其實一輩子不用碰 C++。

學會這三招之後要往哪走?

到這裡你已經會:讀寫影像、邊緣偵測、輪廓 + 透視變換、現代物件偵測。下一步建議按這個順序走:

OpenCV 經典 + YOLO 入門(你在這)
  → NumPy 向量化(避免 Python for-loop 地獄)
  → CS231n 講義(理解 CNN / ResNet / ViT)
  → 自訓資料集(Roboflow 標註 → YOLO 訓練)
  → ONNX export(跨框架部署)
  → 邊緣裝置(Raspberry Pi 5 / Jetson Orin Nano)
  → VLM 多模態(OpenCV 5 內建 Qwen / PaliGemma)

幾個我自己覺得最受用的資源:

新手最常踩的五個坑

最後分享幾個我自己踩過的坑,少走點冤枉路:

  1. 跳過經典 CV 直接學 YOLO:不懂 NMS、IoU、anchor 是什麼,模型一壞就只能換版本。
  2. 覺得 OpenCV 過時所以不學:5.0 才剛把 LLM/VLM 整合進來,反而比以前更值得學。
  3. Python 用 for-loop 處理像素:慢到懷疑人生,所有逐像素操作必須改 NumPy 向量化。
  4. 只會 model.predict() 不會部署:找工作會卡關。學會 ONNX export、INT8 量化、用 OpenCV DNN 跑推論。
  5. 資料集太乾淨:Kaggle 的影像太理想,去 Roboflow Universe 找接近真實雜訊的資料才有用。

結語

電腦視覺看起來很玄,其實 80% 的入門路徑就只是「讀進影像 → 做幾個變換 → 輸出結果」這個迴圈。三個範例你都跑過一次之後,這個迴圈會內化成肌肉記憶——剩下的就是把不同的工具(OpenCV、YOLO、Supervision、SAM2、VLM)塞進這個迴圈裡組合。

下一篇會深拆 2026 年 6 月剛發布的 OpenCV 5.0——它把整個 DNN 引擎重寫、ONNX 覆蓋率衝到 80%、還把 LLM 跟 VLM 直接塞進函式庫。如果你已經會用 OpenCV 4.x,那篇會告訴你升級該注意什麼;如果你剛入門,那篇會讓你看見未來兩年 CV 的樣貌。

延伸閱讀

OpenCV 26 年:一個 Intel 內部專案,怎麼變成全世界 CV 工程師的基本盤

1999 年 Intel 研究實驗室的場景重現

打開任何一本電腦視覺教科書、隨便點開一篇 GitHub 上的 CV 專案,你很可能會看到那一行熟悉的 import cv2。這個 cv2 背後是一個叫做 OpenCV 的開源函式庫——我們現在覺得它就跟空氣一樣理所當然,但它走到今天,其實非常曲折。

它一開始不是一個正經的學術計畫,也不是某個天才博士論文的副產品。它是 Intel 內部一個拉抬 CPU 銷量的「公關專案」,差點在 dot-com 泡沫崩潰時無聲消失,後來經歷三次組織轉手,才在 2026 年 6 月迎來八年來最大一次改版:OpenCV 5.0 直接把 LLM 與 VLM 塞進這個函式庫裡面。

這篇就來講這個故事——不講太多技術,主要講人、講組織、講為什麼一個函式庫可以撐 26 年還越長越壯。

故事的起點:一個叫 Gary Bradski 的人

要講 OpenCV,就一定要從 Gary Bradski 講起。1990 年代末,他在 Intel 的 Microprocessor Research Lab 工作,當時 Intel 一直在找方法讓自家 CPU「賣得出去」——你 CPU 越強,總得有東西可以拿來算吧?所以 Intel 開了一堆「拉抬 CPU 運算密集應用」的計畫,包括即時光線追蹤、3D 顯示牆等等。

Bradski 那時去拜訪了 MIT Media Lab、CMU、史丹佛這些頂尖學校的視覺實驗室,他注意到一件很有趣的事——每個學校的研究生都把學長姊寫過的 CV 程式碼當作起點,互相傳承、從來不必從零造輪子。可是這種「內部福利」外面拿不到。

於是他和一群 Intel Russia 的最佳化專家、Intel Performance Library 團隊一起,把這套「共享 CV 程式碼」的概念變成一個對外開源的函式庫。Bradski 自己在受訪時這樣描述目標:

我們希望降低電腦視覺的入門門檻,把它民主化,讓任何人都可以把 machine perception 用在自己的專案裡。

他這段話講得很 Silicon Valley、很官腔,但骨子裡 Intel 的算盤其實也很直白:有更多人寫 CV 應用,就有更多人需要強的 CPU。商業誘因和理想主義在這個案子上剛好對齊。

1999–2008:漫長的 Beta 與差點消失的十年

OpenCV 的第一個 alpha 版在 1999 年 1 月內部釋出,那時候只支援 Windows、用 C 語言寫的、介面就是現在被吐槽的 IplImage 那一套。Wikipedia 上的 OpenCV 條目 寫得很清楚:對外正式亮相是 2000 年 6 月的 IEEE CVPR 大會。

然後它就進入了一段很漫長的 beta 期——2001 到 2005 連續發了五個 beta 版,1.0 正式版要等到 2006 年才釋出。為什麼這麼慢?因為 dot-com 泡沫破了,Intel 內部裁員、轉向,這個專案有好一段時間連一個全職人員都沒有。

Bradski 自己後來回憶(這段在他 2014 年的 OpenCV 3.0 投影片 裡有提到):「1999 年初平均有 7 個人在做,2003 年 Intel 的正式支援下降到接近零,Willow Garage 接手前的幾年內部幾乎沒人在管。」聽起來夭壽。

那段空窗期 OpenCV 之所以還能持續發 beta,靠的不是 Intel 員工,而是一群俄羅斯工程師——Vadim Pisarevsky、Victor Eruhimov、Sergey Molinov、Alexander Shishkov。他們以開源志工的身份在外部維持核心開發,後來這幫人乾脆自己跑出來開了一家叫 Itseez 的公司,把 OpenCV 從志工模式轉成商業支援模式。這段故事很少被講,但這群俄羅斯人才是 OpenCV 沒死的原因。

時間軸演進的視覺隱喻

三次組織轉手:從 Intel 到 Willow Garage,再回到 Intel

OpenCV 的歷史不只是程式碼演進史,它的「組織歸屬」變過好幾次,而每一次轉手都讓它走向不同的方向。

時期主導組織影響
1999–2008Intel Research起源、C API、Windows-only
2008–2012Willow Garage機器人優先,順便讓它跨平台
2012 起OpenCV.org 基金會Bradski 與 Vincent Rabaud 共同創立
2012–2016Itseez商業支援俄羅斯團隊接手核心
2016/5/25 起Intel 收購 ItseezOpenCV 回到 Intel 體系

Willow Garage 那段特別關鍵。這家公司是矽谷做機器人的傳奇——同時維護 ROS(Robot Operating System) 、PCL(Point Cloud Library),以及 OpenCV 與 Willow Garage 的歷史關聯 。他們把 OpenCV 從一個「Windows 上的 Intel 函式庫」改造成真正跨平台的工具。Bradski 後來離開 Willow 自己創了 Industrial Perception(2013 年被 Google 收購),但 OpenCV 留在了基金會手裡。

2012 年 8 月 是另一個分水嶺——非營利的 OpenCV.org 基金會成立,Bradski 和 Vincent Rabaud(當時還在 Willow Garage 當研究工程師)一起主持。從這天起,OpenCV 真正脫離單一公司的控制,變成社群擁有的開源資產。

四年後,2016 年 5 月 25 日,Intel 又把 Itseez 收購回來——某種程度上像是「回娘家」。但 OpenCV.org 基金會仍然獨立運作,所以這次收購對開發節奏沒造成什麼震盪,反而讓 Intel 在硬體優化上資源更直接。

程式碼面的世代分水嶺

組織講完,講一下程式碼面那幾次真正重要的「世代交替」。我不會講細節,但你要知道有這幾個時間點:

  • 2009 年 10 月,OpenCV 2.0:從 C 介面切到 C++ 介面,引入 cv::Mat,自動記憶體管理、告別手動 cvRelease*() 地獄。寫過 1.x 的人會懂這有多解脫。
  • 2015 年的 3.0、2017 年的 3.3:DNN(深度學習)模組從 contrib 升到主 repo,OpenCV 第一次正式承認「我不再只是傳統 CV」。
  • 2018 年 11 月,OpenCV 4.0:移除大量舊 C API、預設 C++11、cv::Ptr 改成 std::shared_ptr 的薄包裝。這是「拆技術債」的第一次大手術。
  • 2026 年 6 月,OpenCV 5.0:8 年來最大改版,DNN 引擎全部重寫、ONNX 操作覆蓋率從 ~22% 提升到 80%+、內建 tokenizer 與 KV-cache 直接跑 LLM/VLM、徹底拋棄 legacy C API、C++17 變成最低標準。整個社群在 Hacker News 與 Phoronix 上熱烈討論了好幾天,份量等同當年 2.0 引入 C++、4.0 拆掉 C API 的世代分水嶺。

5.0 這次的衝擊力,業界討論最多的是兩件事:第一,OpenCV 變成可以直接跑 Qwen 2.5、Gemma 3、PaliGemma 等多模態模型的工具;第二,任何還在用 OpenCV 1.x C API 的舊專案,5.0 連編都編不過——必須留在 4.x 線上,或者咬牙改寫。

詳細的技術內容我會另外寫一篇深度文章去拆,這篇先按下不表。

為什麼一個 26 歲的函式庫還沒死?

這才是這篇真正想問的問題。我們這行的工具淘汰速度誇張到不行——React 18 出來才幾年大家又在罵框架太多了,但 OpenCV 從 1999 撐到 2026 還越長越壯,為什麼?

我覺得答案要從底層問題開始講起。OpenCV 解的東西——讀檔、色彩空間轉換、幾何變換、形態學、輪廓、邊緣、特徵——這些 1999 年是這樣,2026 年還是這樣。沒人會發明新的「灰階轉換」。當別的庫拼命追潮流時,OpenCV 守住的是「水電」級的需求。

而它真正能穿越週期的關鍵,在於它一直緊貼著硬體節奏走。從 Intel 的 MMX/SSE/AVX,到 NVIDIA 的 CUDA、ARM 的 NEON、Apple Silicon、RISC-V 的 RVV 1.0,每一波新指令集 OpenCV 都會跟上。這也是 Intel 願意花錢收 Itseez 的真正理由——它就是 Intel CPU 在 CV 領域的「行銷展示櫃」。商業誘因和技術理想再一次重合。

教學資源這層更是新工具兩三年內追不上的護城河。PyImageSearch 、LearnOpenCV 、Bradski 本人寫的 Learning OpenCV——這些教材累積了 20 年。新人進來,只要 Google「OpenCV + 我想做的事」幾乎一定有現成教學跑。這種文化資產,光是「快」是買不到的。

最後一點我自己最佩服——5.0 證明它願意自我革命。一個函式庫敢在 4.x 已經很穩定的情況下,砍掉 C API、把 DNN 整個重寫、把 LLM 也納進來,這在開源世界並不常見。很多老專案最後死於「不敢改」,OpenCV 用 5.0 告訴大家它不在那個名單裡。

視覺與感知的螺旋演化

結語:歷史的重量會變成新人的福氣

我自己第一次裝 OpenCV 大概是 2018 年,那時候只是想做一個 Webcam 人臉偵測的玩具,根本沒在管背後這 19 年發生過什麼事。後來開始追新版本變化,才發現這個函式庫的故事比技術本身還精彩——一個專案能熬過 dot-com 崩盤、熬過三次組織轉手、又熬過深度學習對傳統 CV 的「降維打擊」,每一次都換了一張皮繼續活下來。

對 2026 年才開始學電腦視覺的人來說,OpenCV 26 年累積的歷史重量其實是禮物。所有可能踩的坑前人都踩過了,所有可能寫的範例 GitHub 上都有,連 OpenCV University 也有完整的官方課程。你只要願意動手,剩下的就是時間問題。

接下來的第二篇會帶你用幾十行 Python 跑完三個遞進的 CV 範例;第三篇則深拆 OpenCV 5.0 為什麼是世代分水嶺。沒碰過 CV 的人從第二篇開始最舒服;想看技術細節就直接跳到第三篇。

延伸閱讀

8GB 的 RK3588 能跑多聰明的 LLM?ROCK 5C 用 NPU 實測 5 個模型

先講結論,省得你滑到最後: 在一片 8GB 的 RK3588 板子上,用 NPU 跑得最聰明的是 Qwen3-4B-Instruct-2507,我出的 7 題全對,但每秒只吐 3.7 個 token。 想要順一點的對話體驗,Qwen3.5-2B 的 8.4 tok/s 是比...