# 電腦視覺簡介 [電腦視覺](https://wikipedia.org/wiki/Computer_vision)是一個旨在讓電腦能夠高層次理解數位影像的學科。這是一個相當廣泛的定義,因為*理解*可以有許多不同的含義,包括在圖片中找到物件(**物件偵測**)、理解正在發生的事情(**事件偵測**)、用文字描述圖片,或是以3D重建場景。此外,還有一些與人類影像相關的特殊任務,例如年齡和情緒估算、臉部偵測與識別,以及3D姿態估算等。 ## [課前測驗](https://red-field-0a6ddfd03.1.azurestaticapps.net/quiz/106) 電腦視覺最簡單的任務之一是**影像分類**。 電腦視覺通常被認為是人工智慧的一個分支。如今,大多數的電腦視覺任務都是使用神經網路來解決的。我們將在本章節中深入了解用於電腦視覺的特殊神經網路類型,[卷積神經網路](../07-ConvNets/README.md)。 然而,在將影像傳遞給神經網路之前,許多情況下使用一些演算法技術來增強影像是有意義的。 以下是幾個可用於影像處理的 Python 函式庫: * **[imageio](https://imageio.readthedocs.io/en/stable/)** 可用於讀取/寫入不同的影像格式。它還支援 ffmpeg,一個將影片幀轉換為影像的有用工具。 * **[Pillow](https://pillow.readthedocs.io/en/stable/index.html)**(也稱為 PIL)功能更強大,並支援一些影像操作,例如形態變化、調整調色板等。 * **[OpenCV](https://opencv.org/)** 是一個用 C++ 編寫的強大影像處理函式庫,已成為影像處理的*事實標準*。它有一個方便的 Python 介面。 * **[dlib](http://dlib.net/)** 是一個 C++ 函式庫,實現了許多機器學習演算法,包括一些電腦視覺演算法。它也有 Python 介面,可用於挑戰性任務,例如臉部和臉部特徵點偵測。 ## OpenCV [OpenCV](https://opencv.org/) 被認為是影像處理的*事實標準*。它包含許多有用的演算法,並以 C++ 實現。你也可以從 Python 調用 OpenCV。 學習 OpenCV 的好地方是[這門 Learn OpenCV 課程](https://learnopencv.com/getting-started-with-opencv/)。在我們的課程中,我們的目標不是學習 OpenCV,而是展示一些它的使用範例以及如何使用它。 ### 加載影像 在 Python 中,影像可以方便地表示為 NumPy 陣列。例如,大小為 320x200 像素的灰度影像將存儲在一個 200x320 的陣列中,而相同尺寸的彩色影像則具有 200x320x3 的形狀(代表三個色彩通道)。要加載影像,可以使用以下程式碼: ```python import cv2 import matplotlib.pyplot as plt im = cv2.imread('image.jpeg') plt.imshow(im) ``` 傳統上,OpenCV 使用 BGR(藍-綠-紅)編碼來表示彩色影像,而其他 Python 工具則使用更傳統的 RGB(紅-綠-藍)。為了使影像顯示正確,你需要將其轉換為 RGB 色彩空間,可以通過在 NumPy 陣列中交換維度,或者調用 OpenCV 函數來完成: ```python im = cv2.cvtColor(im,cv2.COLOR_BGR2RGB) ``` 同樣的 `cvtColor` 函數也可以用於執行其他色彩空間轉換,例如將影像轉換為灰度或 HSV(色相-飽和度-亮度)色彩空間。 你還可以使用 OpenCV 逐幀加載影片——範例可在練習[OpenCV Notebook](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb)中找到。 ### 影像處理 在將影像傳遞給神經網路之前,你可能需要應用幾個預處理步驟。OpenCV 可以執行許多操作,包括: * 使用 `im = cv2.resize(im, (320,200),interpolation=cv2.INTER_LANCZOS)` **調整影像大小** * 使用 `im = cv2.medianBlur(im,3)` 或 `im = cv2.GaussianBlur(im, (3,3), 0)` **模糊影像** * 改變影像的**亮度和對比度**可以通過 NumPy 陣列操作完成,詳情請參考[這篇 Stackoverflow 筆記](https://stackoverflow.com/questions/39308030/how-do-i-increase-the-contrast-of-an-image-in-python-opencv)。 * 使用[閾值處理](https://docs.opencv.org/4.x/d7/d4d/tutorial_py_thresholding.html),通過調用 `cv2.threshold` 或 `cv2.adaptiveThreshold` 函數,這通常比調整亮度或對比度更可取。 * 對影像應用不同的[變換](https://docs.opencv.org/4.5.5/da/d6e/tutorial_py_geometric_transformations.html): - **[仿射變換](https://docs.opencv.org/4.5.5/d4/d61/tutorial_warp_affine.html)** 如果你需要結合旋轉、調整大小和傾斜影像,並且知道影像中三個點的來源和目標位置,仿射變換會保持平行線平行。 - **[透視變換](https://medium.com/analytics-vidhya/opencv-perspective-transformation-9edffefb2143)** 如果你知道影像中四個點的來源和目標位置,透視變換會很有用。例如,如果你用智能手機相機從某個角度拍攝矩形文件,並希望生成該文件本身的矩形影像。 * 使用**[光流](https://docs.opencv.org/4.5.5/d4/dee/tutorial_optical_flow.html)**來理解影像內的運動。 ## 使用電腦視覺的範例 在我們的[OpenCV Notebook](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb)中,我們提供了一些範例,展示了電腦視覺如何用於執行特定任務: * **預處理盲文書籍的照片**。我們專注於如何使用閾值處理、特徵偵測、透視變換和 NumPy 操作來分離單個盲文符號,以便進一步由神經網路進行分類。 ![盲文影像](../../../../../translated_images/braille.341962ff76b1bd7044409371d3de09ced5028132aef97344ea4b7468c1208126.mo.jpeg) | ![盲文影像預處理結果](../../../../../translated_images/braille-result.46530fea020b03c76aac532d7d6eeef7f6fb35b55b1001cd21627907dabef3ed.mo.png) | ![盲文符號](../../../../../translated_images/braille-symbols.0159185ab69d533909dc4d7d26a1971b51401c6a80eb3a5584f250ea880af88b.mo.png) ----|-----|----- > 圖片來源:[OpenCV.ipynb](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb) * **使用幀差分偵測影片中的運動**。如果相機固定,則相機畫面中的幀應該彼此非常相似。由於幀以陣列表示,只需減去兩個連續幀的陣列即可獲得像素差異,靜態幀的差異應該很低,而當影像中有顯著運動時,差異會變高。 ![影片幀和幀差分的影像](../../../../../translated_images/frame-difference.706f805491a0883c938e16447bf5eb2f7d69e812c7f743cbe7d7c7645168f81f.mo.png) > 圖片來源:[OpenCV.ipynb](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb) * **使用光流偵測運動**。[光流](https://docs.opencv.org/3.4/d4/dee/tutorial_optical_flow.html)使我們能夠理解影片幀中每個像素的移動方式。光流有兩種類型: - **密集光流**計算顯示每個像素移動方向的向量場 - **稀疏光流**基於影像中的一些顯著特徵(例如邊緣),並從幀到幀建立它們的軌跡。 ![光流影像](../../../../../translated_images/optical.1f4a94464579a83a10784f3c07fe7228514714b96782edf50e70ccd59d2d8c4f.mo.png) > 圖片來源:[OpenCV.ipynb](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb) ## ✍️ 範例筆記本:OpenCV [嘗試 OpenCV 實作](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb) 讓我們通過探索[OpenCV Notebook](../../../../../lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb)來進行一些 OpenCV 的實驗。 ## 結論 有時,像運動偵測或指尖偵測這樣相對複雜的任務可以純粹通過電腦視覺來解決。因此,了解電腦視覺的基本技術以及像 OpenCV 這樣的函式庫能做什麼是非常有幫助的。 ## 🚀 挑戰 觀看[這段影片](https://docs.microsoft.com/shows/ai-show/ai-show--2021-opencv-ai-competition--grand-prize-winners--cortic-tigers--episode-32?WT.mc_id=academic-77998-cacaste),了解 Cortic Tigers 項目以及他們如何構建基於模塊的解決方案來通過機器人普及電腦視覺任務。研究其他類似項目,了解它們如何幫助新學習者進入這個領域。 ## [課後測驗](https://red-field-0a6ddfd03.1.azurestaticapps.net/quiz/206) ## 回顧與自學 閱讀更多關於光流的內容,[這篇精彩的教程](https://learnopencv.com/optical-flow-in-opencv/)是個好地方。 ## [作業](lab/README.md) 在這次實驗中,你將拍攝一段包含簡單手勢的影片,你的目標是使用光流提取上下左右的移動。 手掌移動幀 **免責聲明**: 本文件使用 AI 翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。應以原始語言的文件作為權威來源。對於關鍵資訊,建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或誤釋不承擔責任。