Opencv系列之一:簡介與基本使用

2023-10-17 12:01:00

1 Opencv簡介

Opencv是計算機視覺中經典的專用庫,其支援多語言,跨平臺,功能強大。Opencv-Python為Opencv提供了Python介面,使得使用者在Python中能夠呼叫C/C++,在保證易讀性和執行效率的前提下,實現所需的功能。

Opencv是由Gray Bradsky於1999年在英特爾創立,第一版於2000年問世。Vadim Pisarevsky加入Gary Bradsky,一起管理因特爾的俄羅斯軟體Opencv團隊。

2005年,Opencv用於Stanley,該車贏得了2005年DARPA挑戰賽的冠軍。後來,在Willow Garage的支援下,它的積極發展得以繼續,由Gary Bradsky和Vadim Pisarevsky領導了該專案。Opencv現在支援與計算機視覺和機器學習有關的多種演演算法,並且正在日益擴充套件。

Opencv支援多種程式語言,例如C++, Python, Java等,並且可以再Windows , Linux , OS X , Android和IOS等不同平臺上使用。基於CUDA和OpenCL的高速GPU操作的介面也在積極開發中。

Opencv-Python是用於Opencv的Python API,結合了Opencv C++ API和Python語言的最佳特性。

1.1 Opencv-Python

Opencv-Python是旨在解決計算機視覺問題的專用庫
Python是由Guidovan Rossum發起的通用程式語言,很快就非常流行,主要是因為他的簡單性和程式碼可讀性。它使得程式設計師可以用較少的程式碼行表達想法,而不會降低可讀性。

與C/C++之類的語言,Python速度較慢。也就是說,可以使用C/C++輕鬆擴充套件Python,這使得我們能夠用C/C++編寫計算機密集型程式碼並建立可用作Python模組的Python包裝器。它給我們帶來了兩個好處: 首先,程式碼與原始C/C++程式碼一樣快(因為它是在後臺執行的實際C++程式碼), 其次,在Python中比C/C++編寫程式碼更容易。Opencv-Python是原始Opencv C++實現的Python包裝器。

Opencv-Python利用了Numpy,這是一個高度優化的庫,用於使用MATLAB樣式的語言進行數值運算。所有Opencv陣列結構都與Numpy陣列相互轉換。這也使與使用Numpy的其他庫(例如Scipy和Matplotlib)的整合變得更加容易。

1.2 應用領域

  • 人機互動
  • 物體識別
  • 影象分割
  • 臉部辨識
  • 動作識別
  • 運動跟蹤
  • 機器人
  • 運動分析
  • 機器視覺
  • 結構分析
  • 汽車安全駕駛

如上所述,opencv的功能十分強大,在各個領域大放異彩,由淺入深,本次我們先介紹影象編輯,簡單的字母數位識別的相關部分,日後會繼續開始臉部辨識,影象分割,影象定位等等功能;

2 opencv-python安裝與使用

首先我們需要安裝一下環境

  1. python3:安裝python3:python教學有詳細的說明,網址安裝python
  2. numpy:安裝numpy:pip install numpy
  3. opencv-python:安裝opencv-python: pip install opencv-python

安裝完opencv-python後命令列開啟python互動式環境:import cv2 成功,便說明成功安裝了opencv-python

2.1 imread()

imread函數讀取數位影像,先看一下官網對於該函數的定義

cv2.imread(path_of_image, intflag)

函數引數一: 需要讀入影象的完整的路徑
函數引數二: 標誌以什麼形式讀入影象,可以選擇一下方式:

  • cv2.IMREAD_COLOR: 載入彩色影象。任何影象的透明度都將被忽略。它是預設標誌
  • cv2.IMREAD_GRAYSCALE:以灰度模式載入影象
  • cv2.IMREAD_UNCHANGED:保留讀取圖片原有的顏色通道
  • 1 :等同於cv2.IMREAD_COLOR
  • 0 :等同於cv2.IMREAD_GRAYSCALE
  • -1 :等同於cv2.IMREAD_UNCHANGED
color_img = cv2.imread("image_file/1.jpeg")
print(color_img.shape)

gray_img=cv2.imread("image_file/1.jpeg", cv2.IMREAD_GRAYSCALE)
print(gray_img.shape)

#把單通道影象儲存後,再讀取,仍然是3通道,相當於將單通道複製到3個通道儲存
cv2.imwrite("image_file/gray_1.jpeg",gray_img)

2.2 threshold()

這個函數作用是將圖片二值化,影象的二值化,就是將影象上的畫素點的灰度值設定為0或255,也就是將整個影象呈現出明顯的只有黑和白的視覺效果。二值化是影象分割的一種最簡單的方法。二值化可以把灰度影象轉換成二值影象。把大於某個臨界灰度值的畫素灰度設為灰度極大值,把小於這個值的畫素灰度設為灰度極小值,從而實現二值化。

畫圖舉例來說

cv.threshold()用來實現閾值分割,函數有4個引數:

  • 引數1:要處理的原圖,一般是灰度圖,這也是上一步中處理的
  • 引數2:設定的閾值
  • 引數3:最大閾值,一般為255
  • 引數4:閾值的方式,主要有5種,分別為:THRESH_BINARY,THRESH_BINARY_INV,THRESH_TRUNC,THRESH_TOZERO 和 THRESH_TOZERO_INV

範例如下:
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret, th2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
ret, th3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret, th4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret, th5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)

titles = [‘Original’, ‘BINARY’, ‘BINARY_INV’, ‘TRUNC’, ‘TOZERO’, ‘TOZERO_INV’]
images = [img, th1, th2, th3, th4, th5]

使用Matplotlib顯示
for i in range(6):
plt.subplot(2, 3, i + 1)
plt.imshow(images[i], ‘gray’)
plt.title(titles[i], fontsize=8)
plt.xticks([]), plt.yticks([]) # 隱藏座標軸
plt.show()

實際輸出:

對應的官方中說明

2.3 morphologyEx()

形態學操作是根據影象形狀進行的簡單操作。一般情況下對二值化影象進行的操作。需要輸入兩個引數,一個是原始影象,第二個被稱為結構化元素或核,它是用來決定操作的性質的。

兩個基本的形態學操作是腐蝕和膨脹。他們的變體構成了開運算,閉運算,具體概念如下:

1)腐蝕:

就像土壤侵蝕一樣,這個操作會把前景物體的邊界腐蝕掉(但是前景仍然是白色)。這是怎麼做到的呢?折積核沿著影象滑動,如果與折積核對應的原影象的所有畫素值都是1,那麼中心元素就保持原來的畫素值,否則就變為零。
這會產生什麼影響呢?根據折積核的大小靠近前景的所有畫素都會被腐蝕掉(變為0),所以前景物體會變小,整幅影象的白色區域會減少。這對於去除白噪聲很有用,也可以用來斷開兩個連在一塊的物體等。

2)膨脹:

與腐蝕相反,與折積核對應的原影象的畫素值中只要有一個是1,中心元素的畫素值就是1。
所以這個操作會增加影象中的白色區域(前景)。一般在去噪聲時先用腐蝕再用膨脹。因為腐蝕在去掉白噪聲的同時,也會使前景物件變小。所以我們再對他進行膨脹。這時噪聲已經被去除了,不會再回來了,但是前景還在並會增加。膨脹也可以用來連線兩個分開的物體。

3)開運算:

先腐蝕,後膨脹。去除影象中小的亮點(CV_MOP_OPEN);

4)閉運算

先膨脹,後腐蝕。去除影象中小的暗點(CV_MOP_CLOSE);

kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8))
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv.imshow("MORPH_OPEN_1", opening)
cv2.waitKey(0)

kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8))
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv.imshow("MORPH_OPEN_1", closing)
cv2.waitKey(0)

3 應用案例

以上是opencv的簡單使用,現在舉一個實際應用的案例:識別驗證碼,其實按照上面3個步驟就可以將圖片一步步處理,置灰,二值化,開運算,最後就可以識別了。那麼首先原圖如下:

1)首次處理效果,將圖片灰度化,二值化,為提取輪廓做準備,二值化後,圖片非黑即白兩種,更有利於開閉運算處理

src = cv2.imread('image_file/before.png')
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("Binarization", binary)
cv2.waitKey(0)

2)基礎上面二值化圖片,對結果圖進行開運算處理,去除噪音部分

kernel = cv.getStructuringElement(cv.MORPH_RECT, (8, 1))
open_out = cv.morphologyEx(binl, cv.MORPH_OPEN, kernel)
cv.imshow("MORPH_OPEN_2", open_out)
cv2.waitKey(0)

3)最後一次處理,將背景置為白色,並且識別圖片識別碼

cv.bitwise_not(open_out, open_out)  
cv.imshow("Transform", open_out)
textImage = Image.fromarray(open_out)
text = pytesseract.image_to_string(textImage)  
cv2.waitKey(0)

4)最後列印出驗證碼

4 總結

相信認真一起看完上述知識點,opencv-python已經對於影象的基本操作可以熟練掌握了,接下來會對數位影像的一些其他概念進行介紹,敬請期待~

作者:京東物流 張偉男

來源:京東雲開發者社群 自猿其說Tech 轉載請註明來源