【CV】OpenCV 入门之旅
OpenCV 是一個強大的圖片處理工具,尤其是隨著人工智能、圖片識別等行業的興起,這個第三方庫也越來越受到重視,今天我們就一起來開啟 OpenCV 之旅
計算機視覺
我們先來看下到底什么是計算機視覺
其實這個是一個比較大的問題了,我們先來簡化下問題,思考如下場景
相信很多朋友都會使用微博來曬出自己的旅游照片,當然照片中會包含自己和家人朋友等等。那么該怎么快速的識別出照片中不同的人并標注出來呢,這個時候就可以用到計算機視覺的知識了
計算機視覺是一個跨學科領域,涉及如何使計算機從數字圖像或視頻中獲得高級別的理解,并使得計算機能夠識別諸如人臉、燈柱甚至雕像之類的物體
計算機如何讀取圖像
比如說下面這張圖片,計算機是怎么展示的呢
計算機會將任何圖像讀取為 0 到 255 之間的范圍值
對于任何彩色圖像,都有 3 個主要通道——紅色、綠色和藍色,它的工作原理非常簡單:
“
為每種原色形成一個矩陣,然后這些矩陣組合起來為各個 R、G、B 顏色提供像素值,然后矩陣的每個元素提供與像素亮度強度有關的數據
”
文字有些抽象,我們來看下面這張圖片
如圖所示,此處圖像的大小可以計算為 B x A x 3
注意:對于黑白圖像,只有一個通道
了解了前置基礎知識后,接下來讓我們看看 OpenCV 到底是什么
OpenCV 是什么
OpenCV 是一個 Python 庫,用于解決計算機視覺問題。OpenCV 最初由 Intel 于 1999 年開發,后來得到 Willow Garage 的支持,從而發展的更加迅速
OpenCV 支持多種編程語言,如 C++、Python、Java 等,同時也支持多種平臺,包括 Windows、Linux 和 MacOS
OpenCV Python 只不過是與 Python 一起使用的原始 C++ 庫的包裝類,所有 OpenCV 數組結構都會被轉換為 NumPy 數組
這使得 OpenCV 更容易與其他使用 NumPy 的庫集成,例如,SciPy 和 Matplotlib 等
接下來讓我們看看使用 OpenCV 執行的一些基本操作
OpenCV 基本操作
載入圖像
Import?cv2#?彩色圖片Img?=?cv2.imread?(Penguins.jpg,1)#?黑白圖片Img_1?=?cv2.imread?(Penguins.jpg,0)如上一段代碼所示,首先我們需要導入 OpenCV 模塊
然后我們可以使用 imread 模塊讀取圖像,參數中的1表示是彩色圖像。如果該參數為 0 而不是 1,則表示導入的圖像是黑白圖像
圖像形狀/分別率
我們可以利用 shape 子函數來打印出圖像的形狀
Import?cv2Img?=?cv2.imread?(Penguins.jpg,0)Print(img.shape)圖像的形狀是指 NumPy 數組的形狀,從執行代碼可以看出,矩陣由 768 行和 1024 列組成
展示圖像
import?cv2Img?=?cv2.imread(Penguins.jpg,0)cv2.imshow(Penguins,?Img)cv2.waitKey(0)#?cv2.waitKey(2000)cv2.destroyAllWindows()我們首先使用 imread 導入圖像
接下來使用 imshow 函數通過打開一個窗口來顯示圖像,imshow 函數有兩個參數,分別是窗口的名稱和要顯示的圖像對象
然后我們等待用戶事件,waitKey 使窗口保持靜態,直到用戶按下某個鍵,傳遞的參數是以毫秒為單位的時間
最后,我們使用 destroyAllWindows 根據 waitForKey 參數關閉窗口
調整圖像大小
調整圖像大小也很容易
import?cv2img?=?cv2.imread(Penguins.jpg,0)resized_image?=?cv2.resize(img,?(650,500))cv2.imshow(Penguins,?resized_image)cv2.waitKey(0)cv2.destroyAllWindows()在這里,resize 函數用于將圖像調整為所需的形狀,這里的參數是新調整大小的圖像的形狀
我們注意到,圖像對象從 img 變為 resized_image,因為現在圖像對象發生了變化
還有另一種方法可以將參數傳遞給 resize 函數
Resized_image?=?cv2.resize(img,?int(img.shape[1]/2),?int(img.shape[0]/2)))這樣,我們得到的新圖像形狀會是原始圖像形狀的一半
接下來讓我們進入實戰部分,使用 OpenCV 執行人臉檢測
人臉檢測
人臉檢測?乍一看似乎很復雜,但是通過 OpenCV 就非常容易了,只需要三步走即可!
第 1 步:我們首先拿到一個圖像,然后創建一個級聯分類器,它最終會給出我們人臉的特征
第 2 步:這一步涉及使用 OpenCV,它將讀取圖像和特征文件,主要就是操作 NumPy 數組
我們需要做的就是搜索人臉 NumPy ndarray 的行和列值,這是帶有人臉矩形坐標的數組
第 3 步:使用矩形人臉框顯示圖像
首先,我們創建一個 CascadeClassifier 對象來提取人臉的特征,參數就是包含面部特征的 XML 文件的路徑
下一步是讀取帶有人臉的圖像,并使用 COLOR_BGR2GREY 將其轉換為黑白圖像,接著,我們搜索圖像的坐標,這是使用 detectMultiScale 來完成的
什么是坐標呢?就是面部矩形的坐標。scaleFactor 用于將形狀值減少 5%,直到找到人臉。因此,總的來說 -- 值越小,準確性越高
最后展示圖像
添加人臉框
一個比較簡單的邏輯處理
我們定義了使用 cv2.rectangle 通過傳遞圖像對象、框輪廓的 RGB 值和矩形的寬度等參數來創建矩形的方法。
讓我們看看人臉檢測的完整代碼:
import?cv2#?Create?a?CascadeClassifier?Object face_cascade?=?cv2.CascadeClassifier("haarcascade_frontalface_default.xml")#?Reading?the?image?as?it?is img?=?cv2.imread("photo.jpg")#?Reading?the?image?as?gray?scale?image gray_img?=?cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#?Search?the?co-ordintes?of?the?image faces?=?face_cascade.detectMultiScale(gray_img,?scaleFactor?=?1.05,minNeighbors=5) for?x,y,w,h?in?faces:img?=?cv2.rectangle(img,?(x,y),?(x+w,y+h),(0,255,0),3)resized?=?cv2.resize(img,(int(img.shape[1]/7),int(img.shape[0]/7)))cv2.imshow("Gray",?resized)cv2.waitKey(0)cv2.destroyAllWindows()接下來看看如何使用 OpenCV 捕獲帶有計算機網絡攝像頭的視頻
使用 OpenCV 捕獲視頻
使用 OpenCV 捕獲視頻也非常簡單
一張一張地讀取圖像,由于幀的快速處理已經我們眼睛的機制(生物學范疇?)使單個圖像移動起來,就生成了視頻
首先,我們先導入 OpenCV 庫,接下來我們使用一個名為 VideoCapture 的方法,用于創建 VideoCapture 對象,該方法用于觸發用戶機器上的攝像頭。此函數的參數表示程序應使用內置攝像頭還是附加攝像頭,“0”表示內置攝像頭
最后的釋放方法用于在幾毫秒內釋放系統相機
但是當我們嘗試執行上面的代碼時,會注意到相機燈亮起一秒鐘然后關閉這是因為沒有時間延遲來保持相機功能
我們來增加延遲
我們增加了3秒鐘的延遲,網絡攝像頭將開啟 3 秒鐘
添加一個窗口來顯示視頻輸出
在這里,我們定義了一個 NumPy 數組,我們用它來表示視頻捕獲的第一張圖像——存儲在幀數組中
我們還有一個 check 變量——這是一個布爾數據類型,如果 Python 能夠訪問和讀取 VideoCapture 對象,那么它返回 True
下面是代碼的輸出情況
我們得到的輸出為 True,并打印了幀數組的一部分
但是我們需要從讀取視頻的第一幀開始,以此,我們需要首先創建一個幀對象,它將讀取 VideoCapture 對象的圖像
如上所示, imshow 方法用于捕獲視頻的第一幀
直接捕獲視頻
為了捕獲視頻,我們將使用 while 循環
我們使用 cvtColor 函數將每一幀轉換為灰度圖像
waitKey(1) 將確保在每毫秒間隔后生成一個新幀
這里還有一個用戶事件觸發器,一旦用戶按下“q”鍵,程序窗口就會關閉
下面我們看看如何使用 OpenCV 做一個非常有趣的運動檢測器
基于 OpenCV 的運動檢測器
問題場景:通過一個網絡攝像頭,可以檢測到攝像頭前任何運動物體,并且返回一個圖表,這個圖表包含人/物體在相機前面的時間
問題場景示意圖如下:
下面我們來思考下解決方案
首先我們將圖像保存在特定幀中
接下來將圖像轉換為高斯模糊圖像,這樣做是為了確保我們計算出模糊圖像和實際圖像之間的明顯差異
此時,圖像仍然不是對象,我們定義了一個閾值來去除圖像中的瑕疵,例如陰影和其他噪聲等等
再接下來定義對象的邊框,我們在對象周圍添加一個矩形框
最后,我們計算對象出現和退出幀的時間
思路還是蠻清晰的
我們首先導入包并創建 VideoCapture 對象以確保我們使用網絡攝像頭捕獲視頻。
while 循環遍歷視頻的各個幀,我們將彩色幀轉換為灰度圖像,然后將此灰度圖像轉換為高斯模糊模型
我們使用 if 語句來存儲視頻的第一個圖像
接下來我們繼續深入
我們使用 absdiff 函數來計算第一個出現的幀與所有其他幀之間的差異
閾值函數提供閾值,將小于30的差值轉換為黑色。如果差異大于 30,它會將這些像素轉換為白色
之后我們使用 findContours 函數來定義圖像的輪廓區域
就像前面說的,contourArea 函數可去除噪聲和陰影。為簡單起見,將只保留那部分為白色,其面積大于我們為此定義的 1000 像素
幀每 1 毫秒更改一次,當用戶輸入“q”時,循環中斷并關閉窗口
最后計算對象在相機前的時間
我們使用 DataFrame 來存儲對象檢測和移動出現在幀中的時間值
在這里我們定義了一個狀態標志位,我們在錄制開始時使用此狀態為零,因為對象最初不可見
當檢測到對象時,我們將狀態標志更改為 1
我們將列出每個掃描幀的狀態,如果發生更改以及發生更改的位置,則在列表中使用 datetime 記錄日期和時間
我們將時間值存儲在 DataFrame 中并寫入 CSV 文件
繪制運動檢測圖
最后一步是顯示結果
首先,我們從 motion_detector.py 文件中導入DataFrame
接下來將時間轉換為可以解析的可讀字符串格式
最后,使用散景圖在瀏覽器上繪制時間值的圖表
好了,這就是今天的 OpenCV 入門實戰,怎么樣,看過之后是不是有一種動手的沖動呢,一起玩起來吧!
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載黃海廣老師《機器學習課程》視頻課黃海廣老師《機器學習課程》711頁完整版課件本站qq群955171419,加入微信群請掃碼:
總結
以上是生活随笔為你收集整理的【CV】OpenCV 入门之旅的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机搜狗浏览器怎么样
- 下一篇: WeX5 Model 里data ,ba