1. 程式人生 > >OpenCV3入門教程(一)基礎知識

OpenCV3入門教程(一)基礎知識

------韋訪 20181011

1、概述

想學習影象處理,不管是機器學習也好,深度學習也好,不會點OpenCV好像有點說不過去吧?所以,現在開始OpenCV的學習。

2、讀寫圖片

先從圖片的讀寫開始,opencv讀取圖片的函式是imread,預設情況下,imread函式返回BGR格式的影象,可以用imwrite函式將資料寫到本地。下面的程式碼會將JPG圖片轉成PNG。

import cv2
image = cv2.imread('dog.jpeg')
cv2.imwrite('dog.png', image)

執行結果:

如果想將圖片通過OpenCV的視窗顯示,則呼叫imshow函式,注意在程式碼末尾加上waitkey函式,否則視窗就直接關閉了,不知道的還以為imshow函式沒起作用。程式碼如下,

import cv2
image = cv2.imread('dog.jpeg')
cv2.imwrite('dog.png', image)
cv2.imshow('dog', image)
cv2.waitKey(0)

執行結果:

上面提到,imread預設返回的是BGR圖片,我們也可以通過設定引數,讓其返回一個灰度圖片,程式碼如下,

import cv2
image = cv2.imread('dog.jpeg', flags=cv2.IMREAD_GRAYSCALE)
cv2.imshow('dog', image)
cv2.waitKey(0)

執行結果:

3、高通濾波器

高通濾波器(HPF)是檢測影象的某個區域,根據該畫素與周圍畫素的亮度差值來提升該畫素的亮度的濾波器。下面來舉個例子,程式碼如下,

import cv2
import numpy as np
from scipy import ndimage

kernel_3x3 = np.array([
    [-1, -1, -1],
    [-1, 8, -1],
    [-1, -1, -1],
])

kernel_5x5 = np.array([
    [-1, -1, -1, -1, -1],
    [-1, -1,  2, -1, -1],
    [-1,  2,  4,  2, -1],
    [-1, -1,  2, -1, -1],
    [-1, -1, -1, -1, -1],
])

img = cv2.imread('sea.jpg', flags=cv2.IMREAD_GRAYSCALE)
k3 = ndimage.convolve(img, kernel_3x3)
k5 = ndimage.convolve(img, kernel_5x5)

GBlur = cv2.GaussianBlur(img, (11, 11), 0)
g_hpf = img - GBlur

cv2.imshow('img', img)
cv2.imshow('3x3', k3)
cv2.imshow('5x5', k5)
cv2.imshow('g_hpf', g_hpf)
cv2.waitKey()
cv2.destroyAllWindows()

4、低通濾波器

低通濾波器則在畫素與周圍畫素的亮度差值小於一個特定值時,平滑該畫素的亮度,主要用於去噪和模糊化。

5、邊緣檢測

邊緣檢測不管是在人類視覺還是計算機視覺中都是非常重要的,我們能識別物體,就是靠邊緣。這個很容易理解,夜晚很黑什麼都看不到,不就是因為沒看到物體的邊緣嗎?

OpenCV提供了很多邊緣檢測的濾波函式,比如,Laplacian, Sobel, Scharr, Canny等。這些函式會將非邊緣區域轉為黑色,將邊緣區域轉為白色或其他顏色。但是,這些函式容易將噪聲錯誤的失敗為邊緣,所以,在邊緣檢測之前,應該對影象進行模糊處理。

OpenCV提供了很多模糊濾波器,比如blur, medianBlur, GausianBlur等,邊緣檢測濾波器和模糊濾波器總有一個ksize引數,這個引數表示濾波核的寬高,是一個奇數。還是來個程式碼吧,

import cv2

img = cv2.imread('car.jpg', flags=cv2.IMREAD_GRAYSCALE)
GBlur = cv2.GaussianBlur(img, (3, 3), 0)
canny = cv2.Canny(GBlur, 50, 150)
cv2.imshow('img', img)
cv2.imshow('canny', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()

執行結果,

6、邊界框、最小矩形區域、最小閉圓的輪廓

實際應用中經常會對目標的邊界框、最小矩形區域、最小閉圓特別感興趣。用cv2.findContours函式很容易實現上述功能。上程式碼,

#encoding:utf-8
import cv2
import numpy as np

#讀取圖片
img = cv2.imread('Picture1.png', cv2.IMREAD_UNCHANGED)
#降低解析度,也可以不降低
# img = cv2.pyrDown(img)

#對影象進行二值化操作
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)

#檢測輪廓,
#輸入的三個引數分別為:輸入影象、層次型別、輪廓逼近方法
#因為這個函式會修改輸入影象,所以上面的步驟使用copy函式將原影象做一份拷貝,再處理
#返回的三個返回值分別為:修改後的影象、圖輪廓、層次
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    #邊界框
    x, y, w, h = cv2.boundingRect(c)
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

    #最小矩形區域
    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(img, [box], 0, (0, 0, 255), 3)
    
    #最小閉圓
    (x, y), radius = cv2.minEnclosingCircle(c)
    center = (int(x), int(y))
    radius = int(radius)
    img = cv2.circle(img, center, radius, (255, 0, 0), 2)

cv2.imshow('image', image)
cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
cv2.imshow("contours", img)
cv2.waitKey(0)

執行結果:

總結:

基礎知識先學這麼多,後續再通過例項慢慢學,本來想加上攝像頭的操作,無奈電腦沒有攝像頭,已經在淘寶了,後續例項中再補了。