BG63: OpenCV的Python調用簡介

愛好圖像處理或者從事計算機視覺方面研究的朋友大概無人不知OpenCV的大名。OpenCV的核心是C/C++程序,因此有比較好的執行效率,不過C/C++的開發效率確實不敢恭維。

幸運的是,OpenCV提供了python接口,可以使用開發效率更高的python方式調用OpenCV的強大功能,這種優勢互補確實令人鼓舞。對於研究人員和原型產品開發者,使用OpenCV的python調用能夠更快地驗證idea的可行性和粗略的性能。

1. OpenCV的安裝

想要在python中調用OpenCV需要準備兩個組件,一是OpenCV的核心程序庫,二是OpenCV的python接口模塊。核心程序為C/C++程序,在不同的操作系統下安裝方式稍有差異。

(1) Windows平臺

OpenCV的官網發佈了Windows平臺下的二進制核心開發程序庫,直接下載二進制的安裝包即可安裝到本地計算機中。只是在核心開發程序庫部署完成之後,需要將對應的bin目錄添加到PATH環境變量中。OpenCV是完全開源的,但是在Windows平臺下不建議使用源碼的方式安裝。喜歡折騰的朋友可以選擇對應的Visual Studio編譯試試,這裡就不細說。

(2) Mac平臺

在MacOS下安裝OpenCV是非常容易的,直接運行以下指令即可

<code>brew install opencv/<code>

安裝成功後可以到“/usr/local/Cellar”目錄下查看是否存在“opencv”的目錄。

(3) Linux平臺

在Linux操作系統中,建議使用源碼安裝。由於安裝涉及到依賴項和cmake指令參數的指定,具體安裝步驟可以在本文的notebook版中查看。

(4) 安裝python接口

OpenCV的核心程序庫安裝完成之後,就可以安裝其python調用接口,只需運行以下命令

<code>pip3 install opencv-python/<code>

如果提示權限不足,需要在開頭加上“sudo”。到此OpenCV的核心程序庫和python調用模塊就安裝完畢。

2. 兩個需注意的坑

OpenCV是為圖像處理和計算機視覺開發的,因此對於圖像大小的描述採用了專業的“寬x高”的方式,而不是numpy數據的“行x列”的方式;OpenCV的默認顏色通道是“BGR”而不是matplotlib中的“RGB”。這兩個坑常常導致一些詭異的現象。

下面就詳細說說這兩點。

(1) 圖像顏色通道

我們從圖片文件讀取圖像數據,然後使用matplotlib可視化。

<code>import cv2
import matplotlib
%matplotlib notebook
import matplotlib.pyplot as plt
# 讀取圖像文件
img = cv2.imread('../data/bg63/image_0008.png')
# 創建畫布,並設置畫布大小
plt.figure(figsize=(9.6, 9.6))
# 使用matplotlib顯示BGR通道圖像
plt.subplot(2,1,1)
plt.imshow(img)
plt.title("OpenCV's BGR")
# 使用matplotlib顯示RGB通道圖像
plt.subplot(2,1,2)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('RGB Channels')
# 保存圖像到文件
plt.savefig('../output/bg63/color.png', dpi=300, bbox_inches='tight')/<code>

Output:

BG63: OpenCV的Python調用簡介

從顯示的圖像來看,BGR通道直接可視化的結果是整個畫面偏藍色,而使用cvtColor函數將圖像通道調整為RGB後可視化的結果就是正常的。事實上,在OpenCV的所有處理程序中,對這三色通道的默認排列順序都是BGR。所以,使用其他方式讀入的圖像通道直接是RGB,如果需要傳給OpenCV的程序處理,那麼就需要使用cvtColor函數將RGB轉換成BGR才能正確運行。這一點對於很多剛開始使用OpenCV的python調用的朋友都是一個巨大的坑。在實際開發中,如果實在不清楚當前圖像數據的通道,可以使用matplotlib可視化檢查,也可以使用OpenCV內置的imshow檢查,不過需要謹記,OpenCV的imshow顯示正常的圖像表明通道為BGR。

(2) 圖像大小

我們可以使用resize這個函數來實驗一下OpenCV中對於圖像大小的表示方式。

<code># 創建圖像並指定畫布大小
plt.figure(figsize=(9.6, 9.6))
# 繪製原始圖像
plt.subplot(2,1,1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('Origin')
# 繪製錯誤的size格式結果
plt.subplot(2,2,3)
resize_1 = cv2.resize(img, (img.shape[0]//2, img.shape[1]//2))
plt.imshow(cv2.cvtColor(resize_1, cv2.COLOR_BGR2RGB))

plt.title('height-width')
# 繪製正確的size格式結果
plt.subplot(2,2,4)
resize_2 = cv2.resize(img, (img.shape[1]//2, img.shape[0]//2))
plt.imshow(cv2.cvtColor(resize_2, cv2.COLOR_BGR2RGB))
plt.title('width-height')
# 保存圖像到文件
plt.savefig('../output/bg63/resize.png', dpi=300, bbox_inches='tight')/<code>

Output:

BG63: OpenCV的Python調用簡介

從以上的結果可以看出,在給resize傳遞目標圖像大小的時候,必須遵守(寬,高)的格式,否則處理結果就不符合預期。事實上,在OpenCV中其他的圖像處理操作的默認設置也是這樣的。因此在調用OpenCV中的函數時需要記住這一點。

3. 簡單例程

或許對OpenCV不太熟悉的朋友還不知道能夠使用OpenCV做什麼有意思的事情,這裡就是用OpenCV的python接口完成一個人臉檢測的任務。在OpenCV的安裝目錄下的“share/opencv4/haarcascades”目錄中存儲了一些檢測器的模型,其中由一個模型“haarcascade_frontalface_default.xml”就是用來完成人臉檢測任務的。

<code># 創建檢測器對象
model_path = '/usr/local/Cellar/opencv/4.0.1/share/opencv4/haarcascades/haarcascade_frontalface_default.xml'
face_detector = cv2.CascadeClassifier(model_path)
# 檢測人臉
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray_img, 1.3, 5)
# 繪製人臉矩形框
paint_img = img.copy()
for (x,y,w,h) in faces:
paint_img = cv2.rectangle(paint_img, (x,y), (x+w, y+h), (0,0,255), 3)
# 使用matplotlib可視化
plt.figure(figsize=(9.6,9.6))
plt.imshow(cv2.cvtColor(paint_img, cv2.COLOR_BGR2RGB))
plt.title('face detection')
# 保存圖像到文件
plt.savefig('../output/bg63/face.png', dpi=300, bbox_inches='tight')/<code>

Output:


BG63: OpenCV的Python調用簡介

就這樣簡單的幾行代碼就能完成一個人臉檢測任務,而且OpenCV自帶人臉檢測的精度還不錯。這對於快速驗證原型產品可行性而言是一個不錯的工具。

OpenCV所提供的功能集合是非常龐大的,這裡只是簡要介紹了幾個小的功能點。如果你是圖像處理愛好者,或者計算機視覺的研究者,或者正在學習相機模型和視覺幾何問題的朋友,那麼使用OpenCV的python調用就是一個很好的選擇。更多關於OpenCV的python調用相關的詳細教程,可以閱讀《OpenCV-Python Tutorial》這本書。


分享到:


相關文章: