更新於 2024/11/17閱讀時間約 12 分鐘

用 OpenCV 開啟電腦視覺的世界:基礎介紹與應用(使用Python)

所謂電腦視覺

電腦視覺算不算是一種AI?答案是對,電腦視覺就是AI的其中一項應用。我們可以把「電腦視覺」想像成「讓電腦學會用眼睛看懂世界」。就像人類用眼睛看東西並理解這些東西的樣子,電腦視覺是讓電腦學會「看」影像或影片,並從中「理解」裡面有哪些內容。然而,讓電腦跟人腦一樣得理解圖片內容,就是其最大的困難點。

以底下這張照片中,電腦能夠讀懂圖片中的物件並準確分類。

舉個例子,當一個人看到以下這兩張圖片時,會很直覺的認為左邊的是玩具車,而右邊的是普通的汽車,原因就在於他的大小以及跟周邊物體的對比。電腦視覺所要模擬的,就是這種思考方式,因此能準確的判斷圖片中一個物體。

玩具車 vs 真實汽車

雖然聽起來挺容易理解電腦視覺在做的事,但其中也與深度學習有著強烈的關聯,有相當多要研究的地方,若往下研究會發現這是一個很深的坑啊~,所以隨著現在人工智慧、深度學習等技術的興起,影像辨識的強度、準確度以及速度都大幅提升,應用的領域也越來越廣。雖然這是一個聽起來很困難的事,但是網路上提供了五花八門的學習影像辨識函式庫,可以利用引用別人已經寫好的函式來做專案,這樣就可以大大降低入門的門檻,這次就來介紹其中最著名的函式庫OpenCV。


什麼是OpenCV?

在要開始認識OpenCV之前,要先知道CV指的是電腦視覺(Computer Vision),因此他的全名便是Open Source Computer Vision Library,開源的電腦視覺,由 Intel 發起並開源,它在學術研究和商業應用中都非常流行。OpenCV 支援多種程式語言,包括 Python、C++、Java 等,並且可以在多個作業系統上運行,如 Windows、Linux 和 macOS。

OpenCV的功能十分強大,提供了基本的影像操作(濾波、邊緣檢測、直方圖均衡化)、物件檢測、影像分割、特徵提取,甚至內建了一些基本的機器學習演算法,例如支援向量機(SVM)、K-means 分群等,以及深度學習模型加載,可以直接使用訓練好的模型進行推理。

這些都還需要很多時間的學習,先看看就好~ 不過有興趣的話也歡迎繼續閱讀下去,下一段中會介紹他的基礎的操作方式


OpenCV的運作方式

OpenCV的使用方式可以大致分為三個步驟

  1. 讀取影像或影片(讓電腦「看到」東西)
    首先,OpenCV 需要從某個來源(例如相機或影像檔案)「看到」影像。電腦本身不是真的有眼睛,它看到的是一堆數字,但這些數字代表影像中的顏色和亮度。OpenCV 將影像或影片讀入程式,這樣影像內容就能進一步進行處理。
  2. 處理影像(讓電腦「理解」影像)
    接著,OpenCV 會對影像進行一些處理,這一步就是讓電腦「理解」影像內容。例如:
    • 轉換顏色:可以把彩色影像轉成黑白,這樣可以幫助簡化資料,讓處理速度變快。
    • 去除雜訊:影像可能有雜訊或模糊點,OpenCV 可以用一些技術把影像弄得更清晰。
    • 找邊緣:電腦可以找出物體的輪廓,就像我們在畫畫時會先畫出物體的外形。這對於辨識物體很有幫助。
    • 物體辨識:利用一些訓練好的資料庫,OpenCV 可以「判斷」影像中有哪些東西,比如人臉、車輛、文字等。
  3. 顯示或輸出結果(讓電腦“展示”結果)
    處理完影像後,OpenCV 可以把結果「顯示」出來。這可能是顯示一張標註過的影像,或者儲存成新的檔案。比如,我們可以把檢測到的臉部用方框框起來,然後顯示在畫面上

自己寫寫看簡單的影像辨識!

我們將會使用OpenCV裡的 Haar Cascades 人臉辨識分類器

首先要先在終端機打下以下指令,下載所需的opencv函式庫

pip install opencv-python

接著就可以開始寫程式了~

import cv2 
# Step 1 img = cv2.imread('Nicolas.jpeg')
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

Step 1.

import cv2 引入opencv後便可以開始撰寫其他內容。

img = cv2.imread(圖片名稱) 這裡是要將一張自己所下載好的圖片給cv2讀取(提醒:圖片中要有人的「正臉」之後才能看出效果)

💡補充:
cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') :
cv2.CascadeClassifier: 這是OpenCV中用來做物體檢測的分類器。它可以用來檢測像是人臉、眼睛等特徵。
cv2.data.haarcascades: 這是OpenCV中存放預訓練的Haar分類器模型的位置。Haar特徵分類器是一種常用的物體檢測方法。
'haarcascade_frontalface_default.xml':這是Haar分類器模型的名稱,它專門用來檢測正面人臉。這個XML檔案包含了識別人臉所需的特徵數據。

定義一個名為face_cascade的變數,用來當成是cv2.CascadeClassifier偵測正面人臉的工具。

face_casade = .... 

#接著上面的程式碼繼續寫

#Step 2.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gray, 1.1, 4)

for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

Step 2.

我們要先透過cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)把影像轉換成灰階,並用gray變數存起來。

原始圖片 vs 灰階圖片

之所以在做影像辨識時要將圖片轉成灰階,是由於將圖片轉換成灰階可以簡化影像處理的過程,提高運算效率,並在某些情況下提高辨識的準確度。舉個例子,在人臉辨識中,我們通常會將彩色人臉圖像轉換為灰階圖,因為人臉的主要特徵,如眼睛、鼻子、嘴巴等,在灰階圖中仍然清晰可見。而彩色資訊,如膚色等,對於人臉辨識來說並不重要,反而可能引入不必要的雜訊。

💡💡補充:
face_cascade.detectMultiScale(灰階圖片, 縮放比例, 檢測次數)

1.1 這是 scaleFactor 參數,用來設定每次圖像尺寸縮放的比例(這個參數是用來處理圖片中不同大小的人臉):
值越接近 1,檢測會越精確,但運算時間會增加
。例如 1.1 表示每次將圖片縮小 10%
。如果設為 1.2 則每次縮小 20%

4 這是 minNeighbors 參數,表示每個候選區域至少要檢測到幾次才算是真的人臉:
。值越大,誤判率越低,但可能會漏掉一些人臉
。值越小,可以檢測到更多人臉,但可能會有更多誤判
。一般建議值在 3-6 之間

我們可以透過這行簡單的程式,套用「正臉」臉部辨識的函式,faces = face_cascade.detectMultiScale(gray, 1.1, 4),而face所會得到的資料是一個多維矩陣的格式,每個矩陣中包含(x, y, w, h),分別代表每個所判定到的人臉的在圖片中的位子以及大小。


有了資料之後,便可以開始把辨識到的人臉框起來(將資料視覺化),可以透過一個for迴圈讀取faces中的每個矩陣,並用其中的(x, y, w, h)資料透過cv2.rectengle函式在圖片中畫出一個矩形的框框,
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)


for (x, y, w, h) in faces: 
... #接著上面的程式碼繼續寫

#Step 3.
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()


Step 3.

💡 補充:cv2.imshow(窗口名稱, 圖片)

最後,我們只需要透過cv2.imshow()指令上畫面顯示出來即可。

恭喜你完成了第一個OpenCV的程式!這就是一個最簡單使用OpenCV中內建的函式的其中一種方式,寫完後也可以嘗試更改看看face_cascade.detectMultiScale(gray, 1.1, 4) 中的參數,或是更換成其他圖片,並看看差異在哪裡~


完整程式碼

import cv2 

# 讀取圖片
img = cv2.imread('Nicolas.jpeg')

cv2.imshow('orig img',img)

# 使用「正臉」的人臉辨識系統
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

#將圖片轉換成灰階
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#讀取圖片中的所有人臉
faces = face_cascade.detectMultiScale(gray, 1.1, 4)

#在畫面中畫出框框
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

# 顯示最後結果(圖片)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()


結論

OpenCV 是一個厲害且普遍的開源電腦視覺函式庫,特別適合想要入門影像處理的程式開發者。它最常用於 Python 程式語言,提供了豐富的工具和函式來處理圖片與視訊。初學者可以從基本的圖片操作開始,例如讀取、顯示和儲存圖片,這些都只需要幾行簡單的程式碼就能完成。進階一點的功能包括調整圖片大小、裁剪、旋轉、模糊化等基本影像處理,這些都是建立更複雜應用的基礎,在往下研究的話,也能透過tensorflow等套件自己訓練模型。若對於此OpenCV影像辨識的領域有興趣,上網自學也是一個很好的方式,由於它是很熱門的套件,所以網路上的資源是相當多,相信你可以玩出一些新花樣!。

進階思考

除了OpenCV這種影像辨識的套件還有其他類似的套件嗎?有的,而且也不少,以下我整理了一不同難度的套件,之後有感興趣的話也歡迎研究看看!

  • 入門學習:
    • OpenCV + Pillow:基礎影像處理
    • TensorFlow/Keras:深度學習入門
  • 專案開發:
    • 網頁應用:MediaPipe
    • 行動應用:TensorFlow Lite
    • 研究專案:PyTorch
    • 即時處理:Dlib
  • 特定應用:
    • 人臉辨識:Dlib + OpenCV
    • 物件偵測:Detectron2
    • 姿態估計:MediaPipe
    • 圖片處理:Pillow + Scikit-image
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.