獨家 | 手把手教你使用OpenCV庫(附實例、Python代碼解析)

2021-02-13 數據派THU

作者:Anirudh Rao

翻譯:吳金笛

校對:李潔

本文約4000字,建議閱讀10+分鐘

本文將通過幾個簡單的實例帶你上手OpenCV庫,新手必備!

 

OpenCV Python 教程

 

在這個OpenCV Python 的教程中, 我們將使用Python中的OpenCV庫來介紹計算機視覺的各個方面。OpenCV 長期以來一直是軟體開發的重要部分。對開發人員來說學習OpenCV是提高編程能力並幫助他們發展軟體開發職業生涯的好方法。

 

什麼是計算機視覺?

 

為了簡化這個問題的答案, 讓我們來試想一個場景。

 

假設你和你的朋友去度假,然後你上傳了很多照片到Facebook上。但是現在在每張照片中找到你朋友的臉並標記它們要花費很多時間。實際上,Facebook已經足夠智能,它可以幫你標記人物。

 

那麼,你認為自動的特徵標記是如何工作的呢? 簡單來說,它通過計算機視覺來實現。

 

計算機視覺是一個跨學科領域,它解決如何使計算機從數字圖像或視頻中獲得高層次的理解的問題。

 

這裡的想法是將人類視覺系統可以完成的任務自動化。因此,計算機應該能夠識別諸如人臉或者燈柱甚至雕像之類的物體。

 

計算機如何讀取圖像?


思考以下圖片:

我們可以認出它是紐約天際線的圖片。 但是計算機可以自己發現這一切嗎?答案是不!

 

計算機將任何圖片都讀取為一組0到255之間的值。

 

對於任何一張彩色圖片,有三個主通道——紅色(R),綠色(G)和藍色(B)。它的工作原理非常簡單。

 

對每個原色創建一個矩陣,然後,組合這些矩陣以提供R, G和B各個顏色的像素值。

 

每一個矩陣的元素提供與像素的亮度強度有關的數據。

 

思考下圖:

如圖所示,圖像的大小被計算為B x A x 3。

 

注意:對於黑白圖片,只有一個單一通道。

 

現在讓我們來看看OpenCV究竟是什麼。

 

什麼是OpenCV?


OpenCV是一個旨在解決計算機視覺問題的Python庫。OpenCV最初由Intel在1999年開發,但是後來由Willow Garage資助。它支持很多程式語言,如C++,Python,Java等等。它也支持多種平臺,包括Windows,Linux和MacOS。

 

OpenCV Python只是一個與Python一起使用的原始C++庫的包裝類。通過使用它,所有OpenCV數組結構都能被轉化為NumPy數組或從NumPy數組轉化而來。這樣就可以輕鬆地將其與其他使用NumPy的庫集成。例如,SciPy和Matplotlib等庫。

 

OpenCV的基礎操作?


Opencv能完成以下從加載圖像到調整大小等基本操作:

使用OpenCV加載圖片

查看圖片形狀/解析度

顯示圖片

調整圖像大小


1. 使用OpenCV加載圖片

Import cv2  

 

 # colored Image  

Img = cv2.imread ("Penguins.jpg",1)  

 

 # Black and White (gray scale)  

Img_1 = cv2.imread ("Penguins.jpg",0)  

如以上代碼所示,第一個要求是導入OpenCV模塊。

 

之後,我們可以用imread模塊讀取圖片。參數中的1代表這是一個彩色圖片。如果這個參數的值是0,就意味著這個將被導入的圖片是黑白圖片。這裡的圖片名稱是「Penguins」。很簡單吧?

 

2. 查看圖片形狀/解析度

我們可以使用shape子函數來輸出圖片的形狀。看看以下代碼:

Import cv2  

 

# Black and White (gray scale)  

Img = cv2.imread ("Penguins.jpg",0)  

 

Print(img.shape)  

對於圖片的形狀,我們指的是NumPy數組的形狀。執行代碼之後你將會看到這個矩陣由768行和1024列組成。

 

3. 顯示圖片

使用OpenCV顯示圖片非常簡單和直接。思考以下圖片:

import cv2  

 

# Black and White (gray scale)  

Img = cv2.imread ("Penguins.jpg",0)  

cv2.imshow("Penguins", img)  

 

cv2.waitKey(0)  

# cv2.waitKey(2000)  

cv2.destroyAllWindows()  

正如你所見,我們首先使用imread導入圖片。我們需要一個輸出窗口來顯示這個圖片,對吧?

 

然後,我們等待用戶事件。waitKey使窗口保持靜態直到用戶按下一個鍵。傳入的參數是以毫秒為單位的時間。

 

最後,我們根據waitForKey的參數使用destroyAllWindows關閉窗口。

 

4. 調整圖像大小


類似地,調整圖像大小非常簡單。 這裡有另一個代碼段:

import cv2  

# Black and White (gray scale)  

img = cv2.imread ("Penguins.jpg",0)  

resized_image = cv2.resize(img, (650,500))  

cv2.imshow("Penguins", resized_image)  

cv2.waitKey(0)  

cv2.destroyAllWindows()  

這裡,resize函數用於將圖像大小調整為所需的形狀。這裡的參數是新調整大小後的圖像的形狀。

 

與之前的代碼相比,剩下的代碼非常簡單,對嗎?

 

我相信你們對企鵝很好奇,這是我們想要輸出的圖片!

這是另一個向resize函數傳遞參數的方法。看看下面的表示方法:

Resized_image = cv2.resize(img, int(img.shape[1]/2), int(img.shape[0]/2)))  

這裡,我們得到的新圖像大小是原始圖像的一半。

 

使用OpenCV進行人臉檢測

這看起來很複雜,但實際上很容易。 讓我帶你了解整個過程,然後你也會有同樣的感受。

 

第一步:想一想我們的先決條件。我們首先需要一個圖像。然後,我們需要創建一個級聯分類器,它最後會給我們提供面部特徵。

 

第二步:這一步要使用到OpenCV讀取圖像和特徵文件。所以這個時候,原始數據點是NumPy數組的形式。

我們要做的就是搜索麵部 NumPy n維數組的行和列的值。這是具有面部矩形坐標的數組。

 

第三步:最後一步是使用矩形面框顯示圖像。

 

看看下面的圖片,這裡我以圖片的形式總結了上述的三個步驟以便於閱讀:

 

非常直接明了,對吧?

首先,如之前所述,我們創建CascadeClassifier對象來提取面部特徵。包含面部特徵的XML文件路徑是此處的參數。

 

下一步是讀取一個包含面部的圖片,並且使用COLOR_BGR2GREY將其轉化為黑白圖片。接下來,我們搜索圖像的坐標。這是使用detectMultiScale來實現的。

 

你問什麼坐標?它是面部矩形的坐標。scaleFactor被用來減小5%的形狀值,直到找到面部。因此,總的來說,值越小,準確度越高。

 

最後,這張臉被顯示到窗口。

 

這個邏輯很簡單——就像使用for循環語句一樣簡單。看看下面的圖片:

我們通過傳遞參數(比如圖片對象,輪廓框的RGB值和矩形的寬度),使用cv2.rectangle來定義方法以創建一個矩形。

 

讓我們來看看面部檢測的完整代碼:

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庫。接下來,我們有一個叫做VideoCapture的方法,用來創建VideoCapture對象。這個方法用於觸發用戶計算機上的攝像頭。這個函數的參數表示程序應該使用內置攝像頭還是附加攝像頭。「0」表示在這個例子中使用內置攝像頭。

 

最後,release方法用於在幾毫秒內釋放攝像頭。

 

當你繼續並嘗試執行上述代碼時,你會注意到攝像頭指示燈會在一瞬間開啟並稍後關閉。為什麼會這樣?

 

這是因為沒有持續時間來保持相機功能。

看看以上代碼,我們有新的一行time.sleep(3)。這使腳本停止3秒。請注意,傳遞的參數是以秒為單位的時間。因此,當代碼執行時,網絡攝像頭將開啟3秒鐘。

 

添加一個窗口來顯示視頻的輸出非常簡單,與用於圖像的相同方法差不多。 但是,還是有一點變化。 請看以下代碼:

 

我很確定除了一兩行外,你能很大程度地理解以上的代碼。

 

在這裡,我們定義了一個NumPy數組,用於表示視頻捕獲的第一個圖像。它被保存在frame數組中。

 

我們還有check。這是一個布爾數據類型。如果Python能夠訪問和讀取VideoCapture對象則返回True。

 

看看下面的輸出:

如你所見,我們得到的輸出為True,並列印了frame數組的一部分。

 

但是我們需要讀取視頻的第一個幀/圖才能開始,是吧?

 

要做到這一點,首先我們需要創建一個frame對象,它將讀取VideoCapture對象的圖像。

 

如上所示,imshow方法用於捕獲視頻的第一幀。

 

在此期間,我們已經嘗試了捕獲視頻的第一圖像/幀。

 

那麼我們如何在OpenCV中捕獲視頻而不是第一張圖像呢?

 

為了捕獲視頻,我們將使用while循環。while的條件是這樣的:除非「check」值為True,否則Python將顯示幀。

 

這是代碼段的圖片:

我們利用cvtColor函數將每個幀轉換為灰度圖像,如前所述。

 

waitKey(1)將確保在每毫秒的間隙後生成一個新幀。

 

重要的是要注意while循環是完全有效的,以幫助完全迭代幀並在最終顯示視頻。

 

這裡還有一個用戶事件觸發器。一旦用戶按下「q」鍵,程序窗口就會關閉。

 

OpenCV很容易掌握,對吧? 我個人喜歡它的良好的可讀性以及初學者開始使用OpenCV時極快的上手速度。

 

使用案例:使用OpenCV的運動檢測器


1. 問題描述

你正在接觸一家研究人類行為的公司。你的任務是為他們提供可以檢測前方運動的網絡攝像頭。它應該返回一個圖,並且這個圖應該包含人/物體在攝像頭前面的時間。

那麼現在我們已經定義了我們的問題陳述,我們需要構建一個解決方案邏輯以結構化的方式來解決問題。

 

看看下面的圖表:

最開始,我們將圖像保存在特定的frame當中。

 

下一步是將圖像轉化為高斯模糊圖像。這樣做是為了保證我們能計算模糊圖像和真實圖像之間的明顯的差異。

 

此時,圖像仍然不是對象。我們定義一個閾值來去除瑕疵,比如圖像中的陰影和其他噪聲。

 

對象的邊框稍後定義。我們在對象周圍添加一個矩形框,正如我們在本教程前面所討論的那樣。

 

最後,我們計算對象出現在畫面和退出畫面的時間。

 

很簡單吧?

 

這是代碼段:

這裡也遵循同樣的原則。我們首先導入包並創建VideoCapture對象,以確保我們使用網絡攝像頭捕獲視頻。

 

While循環遍歷視頻的各個幀。我們將彩色幀轉換為灰度圖像,然後將此灰度圖像轉化為高斯模糊圖。

 

我們需要存儲視頻的第一個圖像/幀,對吧?出於這個目的,我們使用if語句。

 

現在,讓我們深入了解一下代碼:

 

我們使用absdiff函數計算第一個幀和其他所有幀之間的差異。

 

threshold函數提供閾值,它將差異值小於30的像素轉換為黑。如果像素的差異值大於30,則轉換為白色。THRESH_BINARY就適用於此目的。

 

然後,我們使用findContours函數給圖像定義輪廓區域。我們也在這個階段加入邊界。

 

就像之前解釋過的,contourArea函數可消除陰影和噪聲。為了簡化,它將只保留白色部分,正如我們定義的,白色部分面積大於1000像素。

 

然後,在我們的工作幀中在對象的周圍創建一個矩形框。

 

接下來是這個簡單的代碼:

如前所述,幀每毫秒改變一次,並且當用戶輸入「q」時,跳出循環並關閉窗口。

 

在我們的用例中還有一件事就是我們要計算對象在攝像頭前的時間。

 

2. 計算時間

我們用DataFrame存儲對象出現在幀中被檢測到的時間和運動的時間。

 

接下來是我們之前解釋過的VideoCapture函數。但是在這裡,我們有一個標誌位,稱之為status。我們在記錄開始時設置status為0,因為對象在最初是不可見的。

如上圖所示,當檢測到對象時,我們將status標誌更改為1。很簡單吧?

我們將創建一個status的列表存儲每一個掃描到的幀的狀態,然後如果某處發生改變則使用datetime在列表中記錄日期和時間。

如以上的解釋圖所示,我們將時間值存儲在 DataFrame中。我們以把DataFrame寫入CSV文件中結束,如圖所示。

 

3. 繪製運動檢測圖

我們實例的最後一步是顯示結果。我們將要顯示的是表示兩軸上的運動的圖形。看看以下代碼:

首先,我們從motion_detector.py文件中導入DataFrame。

 

下一步是將時間轉換為可讀的並且可以解析的字符串形式。

 

最後,使用Bokeh plots在瀏覽器上繪製時間值的DataFrame。

 

輸出:


結論:

 

我希望這個OpenCV Python的教程能幫助你學習所有由Python開始使用OpenCV所需的基礎。

 

當你嘗試開發需要圖像識別和類似原理的軟體時就會非常方便了。現在你還能夠在Python OpenCV的幫助下輕鬆地使用這些概念來開發應用程式。

 

原文標題:

Computer Vision Using OpenCV

原文連結:

https://dzone.com/articles/opencv-python-tutorial-computer-vision-using-openc

 

吳金笛,雪城大學計算機科學碩士一年級在讀。迎難而上是我最舒服的狀態,動心忍性,曾益我所不能。我的目標是做個早睡早起的Cool Girl。

工作內容:需要一顆細緻的心,將選取好的外文文章翻譯成流暢的中文。如果你是數據科學/統計學/計算機類的留學生,或在海外從事相關工作,或對自己外語水平有信心的朋友歡迎加入翻譯小組。

你能得到:定期的翻譯培訓提高志願者的翻譯水平,提高對於數據科學前沿的認知,海外的朋友可以和國內技術應用發展保持聯繫,THU數據派產學研的背景為志願者帶來好的發展機遇。

其他福利:來自於名企的數據科學工作者,北大清華以及海外等名校學生他們都將成為你在翻譯小組的夥伴。

點擊文末「閱讀原文」加入數據派團隊~

點擊「閱讀原文」擁抱組織

相關焦點

  • 「Python+cv2」Python安裝opencv及圖像的基本操作
    Python環境opencv的安裝1、檢查是否安裝python環境如果對Python安裝有疑問的可以參考我的文章:手把手教你搭建Python3開發環境手把手教你安裝python編輯器pycharm2、檢查pip3是否安裝
  • 如何快速簡單的安裝opencv-python
    :可以在使用pip的時候,加上參數-i和鏡像地址(如https://pypi.tuna.tsinghua.edu.cn/simple),例如:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python這樣就會從清華鏡像安裝opencv-contrib-python
  • Python不超過10行代碼就可實現人臉識別,教你辨別真假
    人臉檢測不一定會使用深度學習技術,因為這裡的技術要求相對低一些,只需要知道有沒有人臉以及人臉在照片中的大致位置即可。一般我們考慮使用OpenCV、dlib等開源庫的人臉檢測功能(基於專家經驗的傳統特徵值方法計算量少從而速度更快),也可以使用基於深度學習實現的技術如MTCNN(在神經網絡較深較寬時運算量大從而慢一些)。下面環境搭建:1.
  • 手把手教你使用圖像處理利器OpenCV
    概要在本文中,將學習如何使用Python語言進行圖像處理,我們不會局限於一個單獨的庫或框架,然而,有一個庫的使用率將會是最高的,那就是OpenCV。下面依次說明在不同作業系統中OpenCV的安裝方法:$ pip install opencv-python$ brew install opencv3 --with-contrib --with-python3
  • 目標檢測必須要OpenCV?10行Python代碼也能實現,親測好用!
    大數據文摘出品編譯:朱一輝、雪清、小魚短短10行代碼就可以實現目標檢測?!本文作者和他的團隊構建了一個名為ImageAI 的Python庫,集成了現今流行的深度學習框架和計算機視覺庫。本文將手把手教你構建自己的第一個目標檢測應用,而且文摘菌已經幫你踩過坑了,親測有效!
  • 「python opencv 計算機視覺零基礎實戰」第一節
    前置條件說明:本系列opencv實戰教程將從基礎到實戰,若只是簡單學習完python也可以通過該教程完成一般的機器學習編程;文中將會對很多python的基礎內容進行講解,但由於文章定位的原因將不會贅述過多的基礎內容,基礎內容進行第一次講解後第二次將不會過多贅述,本文主要講解的是opencv相關知識。
  • 手把手教你用python搶票回家過年 !(附代碼)
    本文教大家用Python寫出搶火車票代碼以及實戰。首先看看如何快速查看剩餘火車票?當你想查詢一下火車票信息的時候,你還在上12306官網嗎?或是打開你手機裡的APP?下面讓我們來用Python寫一個命令行版的火車票查看器, 只要在命令行敲一行命令就能獲得你想要的火車票信息!如果你剛掌握了Python基礎,這將是個不錯的小練習。接口設計一個應用寫出來最終是要給人使用的,哪怕只是給你自己使用。所以,首先應該想想你希望怎麼使用它?
  • 使用Python+OpenCV實現圖像數據採集
    在本文中,將提供代碼並指導你如何通過構建與模型交互的拍照接口來真正完成項目。安裝cv2(OpenCV)我們將使用的圖像庫是cv2。因為cv2不能在Kaggle這樣的在線平臺上工作,所以它必須在你的計算機上本地完成。然而,模型的權重仍然可以在Kaggle上進行訓練,以.h5文件的形式下載(基於Keras/TensorFlow)並加載。
  • python利用opencv實現證件照換底
    網上交證件照的時候不同單位對底色的要求不一樣,當你手裡只有一張藍底照片,卻要求交紅底或者白底的證件照時,不免就尷尬了些。此時的你為了避免重拍的麻煩,不得不打開ps一點一點地去摳圖換背景,費時費力。opencv今天就給大家介紹一下python利用opencv庫進行藍底換紅底或者白底照片的操作。1.強大的opencv庫說到圖像處理,不得不提opencv庫。
  • 慢步python,說說import,引用功能代碼(功能庫、py文件代碼)
    就差手把手教了。今天想說說importimport是python語言的保留字,它能實現引用當前程序之外已有的功能代碼。python語言像積木,你可以根據你想要的功能,編寫一系列的代碼。比如筆者之前編寫的《word文檔標題置換》。
  • OpenCV入門及應用案例:手把手教你做DNN圖像分類
    本書的代碼分析、示例程序及環境搭建基於OpenCV 4.1版本,原始碼位於GitHub的OpenCV倉庫。01 OpenCV庫OpenCV由各種不同組件組成。OpenCV原始碼主要由OpenCV core(核心庫)、opencv_contrib和opencv_extra等子倉庫組成。
  • OpenCV 強大的開源計算機視覺庫
    如何使用最初的OpenCV使用C語言實現,後來C++逐步加入並成為了OpenCV開發的核心語言。因此你可以通過C++來使用OpenCV庫。另外OpenCV也提供了類似的Python、JavaScript等接口,可以讓您避免C++難度過大的問題。
  • 使用一行Python代碼從圖像讀取文本
    雖然圖像分類和涉及到一定程度計算機視覺的任務可能需要大量的代碼和紮實的理解,但是從格式良好的圖像中讀取文本在Python中卻是簡單的,並且可以應用於許多現實生活中的問題。在今天的帖子中,我想證明這一點。雖然會安裝一些庫,但不會花很多時間。
  • 推薦一些相見恨晚的 Python 庫 「二」
    Python 庫,那麼這篇文章繼續安利一些相見恨晚的庫,旨在讓你在需要的時候能夠派上用場。因此對於開發者來講,從環境到使用會有各種坑需要踩。不過還好有 stackoverflow ,大部分問題都能查到。同時,借著這篇文章問下大家,若有對 RN 感興趣或者正在使用 RN 開發的同學,可以在公眾號後臺回復 RN 獲取到 微信群二維碼,我們一起交流前進。
  • 推薦 :手把手教你用Python進行Web抓取(附代碼)
    本教程以在Fast Track上收集百強公司的數據為例,教你抓取網頁信息。作為一名數據科學家,我在工作中所做的第一件事就是網絡數據採集。使用代碼從網站收集數據,當時對我來說是一個完全陌生的概念,但它是最合理、最容易獲取的數據來源之一。經過幾次嘗試,網絡抓取已經成為我的第二天性,也是我幾乎每天使用的技能之一。
  • Python 圖像處理 OpenCV (1):入門
    /官方 Demo :https://github.com/opencv/opencv/blob/master/samples/python圖書推薦圖書的話我就推薦一本吧,如果要看書學習絕對不能錯過的「Learning OpenCV 3」,當然,是英文原版的,中文版的話翻譯有點慘不忍睹,對英文閱讀壓力大的同學可以中英文對照著看:
  • 乾貨 | 人臉識別的簡要介紹(附實例、Python代碼)
    本文將介紹人臉識別的基本思路和對代碼進行簡要分析。介紹你是否意識到,每當你上傳照片到Facebook上,平臺都會用人臉識別算法來識別圖片中的人物?目前還有一些政府在用人臉識別技術來識別和抓捕罪犯。此外,最常見的應用就是通過自己的臉部解鎖手機。
  • Python下opencv使用筆記(一:簡單操作與幾何變換)
    上次分享了一個關於python下opencv的所有相關資料,詳細可參考下載:珍藏資料-學習OpenCV與計算機視覺-有這些就夠了1.圖像簡單讀取、顯示與儲存首先關於python想說的是,單純的官網下載的python並不大,是一個最初的python,進行一些簡單的操作時可以的,但是當你進行複雜一點的時候,就需要許多第三方的安裝包,比如numpy等等,這些庫安裝進去說起來也不是很複雜,網上有很多教程,但是當許多的包安裝的時候,有的庫包並沒有你的電腦的版本,等等還有許多因素導致你的庫包安裝不進去,想想還是挺麻煩的
  • Python爬蟲之基本庫的使用
    可能你對這些根本不了解,也沒辦法下手。但是沒關係,python為我們提供了功能齊全的類庫來幫助我們完成這些請求。最基礎的HTTP庫有urllib、requests、treq等。以urllib為例,有了它,我們只需要關心請求的連接是什麼。需要傳的參數是什麼,以及如何設置可選的請求頭就好了,不用深入到底層去了解它到底是怎樣傳輸和通信的。
  • 使用Python+OpenCV實現神經網絡預處理人臉圖像的快速指南
    對於本文,我們使用OpenCV:一個高度優化的計算機視覺開源庫,在C++、java和Python中都可用。這是一篇簡短的文章,包含了一些基本的指導原則、示例和代碼,你可以根據需求將它們應用到人臉分類或識別問題上。