農林漁牧網

您現在的位置是:首頁 > 農業

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

2021-12-30由 AI科技大本營 發表于 農業

圖片如何調負片

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

作者 | 王天慶,長期從事分散式系統、資料科學與工程、人工智慧等方面的研究與開發,在人臉識別方面有豐富的實踐經驗。現就職某世界100強企業的資料實驗室,從事資料科學相關技術領域的預研工作。

【導讀】OpenCV是一個以BSD許可證開源的、跨平臺的計算機視覺庫。它提供了Python、C++、Java、Matlab等多種程式語言介面。它集成了很多計算機視覺演算法,具有非常強大的功能,是計算機視覺中最為著名的一個庫。在本文中,我們將要介紹OpenCV的一些基本用法。

01 OpenCV介紹

OpenCV是使用C++進行編寫的、以BSD許可證開放原始碼的、跨平臺的計算機視覺庫。它提供了上百種計算機視覺、機器學習、影象處理等相關演算法,新版本的OpenCV支援Tensorflow、Caffe等深度學習框架。

OpenCV的底層最佳化處理得很好,能夠支援多核處理,能夠利用硬體實現加速。由於該庫是以BSD許可證進行開源的,因此可以被免費應用在科學研究與商業應用中。

OpenCV庫是由英特爾公司下屬的俄羅斯技術團隊發起的,由於優異的效能、免費、開源、演算法豐富、使用簡單等優點,自從專案被髮起後便得到迅猛發展,越來越多的組織和個人加入到原始碼的貢獻隊伍中,這也在客觀進一步促進了OpenCV庫的發展。

OpenCV在諸多領域得到了廣泛的應用,例如物體檢測、影象識別、運動跟蹤、增強現實(AR)、機器人等場景。我們在本書中需要對影象進行處理時,需要用到OpenCV庫。

OpenCV的安裝也比較簡單,在Python中,透過pip包管理工具就可以實現安裝:

pip install opencv-python

如果在anaconda環境中安裝OpenCV,則透過下面的方法進行安裝:

conda install opencv

安裝完畢OpenCV後,可以透過下述方法來檢視是否安裝成功:

# 檢視引入OpenCV庫時是否報錯import cv2# 檢視安裝的版本cv2。__version__# 我這裡顯示的版本資訊是 ‘3。4。1’

以下介紹OpenCV基本操作。

02 存取資料

OpenCV中的圖片以RGB的形式儲存,只不過再OpenCV中的顏色通道順序不是RGB而是BGR。這可以歸結為一個歷史遺留原因。因為OpenCV庫的研發歷史比較“悠久”,在那個時代,BGR是數碼相機裝置的主流表示形式。這一點伴隨著OpenCV的發展一直沒有被改變,我們在後面編寫程式碼的時候應該注意到通道順序的問題。

我們看一下OpenCV中儲存圖片的形式,圖4-2是按照BGR順序儲存的RGB顏色模型的圖片,對於相同的資料,我們也可以將其分別拆分為藍色、綠色、紅色的顏色矩陣,如圖4-3所示。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-2 OpenCV中以BGR形式儲存的彩色圖片

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-3 將彩色圖片拆分成三個顏色通道儲存的形式

透過圖4-2和圖4-3,我們知道了OpenCV儲存圖片的形式。那麼在Python環境中的OpenCV庫底層儲存這顏色的資料結構就是array型別。OpenCV將圖片讀取進來,經過解碼後以array形式儲存。透過下面的例子,我們看一下OpenCV中圖片的讀取和儲存方法。

程式碼清單① OpenCV中圖片的讀取和儲存

import cv2import numpy as np

# 使用imread方法讀入一個圖片image = cv2。imread(“lena。jpg”)

# 看一下資料的儲存維度image。shape# 返回:(121, 121, 3)

# 將讀入的資料image打印出來print(image)

‘’‘如果讀入資料失敗,返回值將不是一個array型別,而是None我們可以看到圖片資料的儲存形式:

[[[113 152 227] [109 153 230] [104 152 230] 。。。, [ 58 93 166] [119 156 212] [149 182 232]]

[[107 149 224] [103 149 226] [ 97 149 225] 。。。, [ 79 112 175] [ 77 108 159] [ 65 91 137]]

[[101 148 222] [ 96 146 222] [ 91 146 221] 。。。, [ 56 80 132] [ 3 22 65] [ 0 3 40]]

。。。, [[ 21 40 45] [ 24 37 45] [ 34 41 50] 。。。, [ 20 34 57] [ 7 24 50] [ 8 27 54]]

[[ 17 35 36] [ 20 32 38] [ 22 29 38] 。。。, [ 13 29 52] [ 28 45 72] [ 41 59 90]]

[[ 15 31 30] [ 19 31 35] [ 21 28 37] 。。。, [ 13 29 52] [ 48 64 93] [ 71 90 123]]]’‘’

# 將儲存圖片資料的image變數寫到磁碟中,寫出的檔名為lena。bak。jpg# 其返回值結果為True代表寫入成功,反之代表失敗cv2。imwrite(“lena。bak。jpg”,image)

這裡面有一個問題需要注意:OpenCV判斷圖片的格式是透過副檔名來實現的,如果我們寫出的檔名為 lena。jpg。bak 那麼可能會報錯:

could not find a writer for the specified extension in function cv::imwrite_

所以,我們在使用OpenCV時候要注意圖片檔案的副檔名。

OpenCV相比於其他的庫,最大的特點是對影象的處理功能非常完備。OpenCV能夠實現對圖片顏色和形狀的變換。

03 顏色變換

圖片的顏色變換可以有很多種類,譬如可以對彩色圖片進行灰度化處理,調節圖片的亮度和對比度,將圖片轉換成負片的形式等。這些操作都是表現在對圖片的顏色處理上,下面我們介紹幾種圖片的常用顏色變換。

1. 灰度化

我們在平時接觸到的圖片大多都是彩色圖片,儲存的顏色模型一般也都是RGB模型。對於彩色圖片我們前面提到過它的儲存形式,相當於三個顏色通道分別用各自的顏色矩陣來記錄資料。對於灰度影象來講,它自然沒有三個通道的說法,它的表現形式是一張矩陣,沒有RGB三個不同的顏色通道。

彩色圖片是可以轉換為灰度影象的,雖然在轉換為灰度影象的過程中丟失了顏色資訊,但是卻保留了圖片的紋理、線條、輪廓等特徵,這些特徵往往比顏色特徵更重要。

將彩色圖片轉換為灰度圖片後,儲存的資料量自然而然也隨之減少,這樣就會帶來一個明顯的好處:對圖片進行處理時的計算量也將會減少很多,這一點在工程實踐中非常重要,大家會在後面的內容中進一步體會。下面我們簡述一下在OpenCV中將彩色圖片轉換為灰度圖片的過程。

程式碼清單②使用OpenCV將圖片灰度化處理

import numpy as npimport cv2

img = cv2。imread(“lena。jpg”)

print(img。shape)# (121, 121, 3)# 使用cv2。cvtColor 方法將彩色圖片轉換為灰度圖片gray_img = cv2。cvtColor(img,cv2。COLOR_BGR2GRAY)

print(gray_img。shape)# (121, 121)

# 將轉換後的灰度圖片回覆成BGR形式img2 = cv2。cvtColor(gray_img,cv2。COLOR_GRAY2BGR)

print(img2。shape)# (121, 121, 3)

# 輸出彩色圖片img的內容print(img)‘’‘[[[113 152 227] [109 153 230] [104 152 230] 。。。, [ 58 93 166] [119 156 212] [149 182 232]]

[[107 149 224] [103 149 226] [ 97 149 225] 。。。, [ 79 112 175] [ 77 108 159] [ 65 91 137]]

[[101 148 222] [ 96 146 222] [ 91 146 221] 。。。, [ 56 80 132] [ 3 22 65] [ 0 3 40]]

。。。, [[ 21 40 45] [ 24 37 45] [ 34 41 50] 。。。, [ 20 34 57] [ 7 24 50] [ 8 27 54]]

[[ 17 35 36] [ 20 32 38] [ 22 29 38] 。。。, [ 13 29 52] [ 28 45 72] [ 41 59 90]]

[[ 15 31 30] [ 19 31 35] [ 21 28 37] 。。。, [ 13 29 52] [ 48 64 93] [ 71 90 123]]]’‘’

# 輸出將灰度圖片重新轉換為BGR形式圖片後的內容print(img2)‘’‘[[[170 170 170] [171 171 171] [170 170 170] 。。。, [111 111 111] [169 169 169] [193 193 193]]

[[167 167 167] [167 167 167] [166 166 166] 。。。, [127 127 127] [120 120 120] [102 102 102]]

[[165 165 165] [163 163 163] [162 162 162] 。。。, [ 93 93 93] [ 33 33 33] [ 14 14 14]]

。。。, [[ 39 39 39] [ 38 38 38] [ 43 43 43] 。。。, [ 39 39 39] [ 303030] [ 33 33 33]]

[[ 33 33 33] [ 32 32 32] [ 31 31 31] 。。。, [ 34 34 34] [ 51 51 51] [ 66 66 66]]

[[ 29 29 29] [ 31 31 31] [ 303030] 。。。, [ 34 34 34] [ 71 71 71] [ 98 98 98]]]’‘’

在上面的例子中,我們看到使用cvtColor 函式可以將彩色圖片轉換為灰度圖片,經過轉換後的圖片shape屬性減少了一個維度,所以這個過程也可以看作是一個降維的過程。

在cvtColor 函式取convert color 之意,第二個引數表示的是轉換操作的類別。這裡我們是將BGR形式的圖片轉換為灰度圖片,所以使用 cv2。COLOR_BGR2GRAY 常量來表示,當然如果將灰度圖片轉換為BGR形式的圖片,也可以傳入cv2。COLOR_GRAY2BGR 常量。

在程式碼清單②中做了一個實驗:嘗試將灰度圖片gray_img 再次轉換為BGR形式的彩色圖片,發現轉換後的圖片無法恢復原先不同顏色通道的數值,OpenCV所採用的方法是將所有的顏色通道全都置成相同的數值,這個數值就是該點的灰度值。

這也說明了從彩色圖片轉換到灰度圖片的計算是單向的,使用簡單的演算法將灰度圖片恢復為彩色圖片是很難的,OpenCV中所採用的轉換過程只是形式上的轉換,並不是真正將灰度圖片轉換為彩色形式。目前有效果比較好的將灰度圖片轉換為彩色圖片的演算法多是結合機器學習的方法來實現的。

2. 負片轉換

負片是攝影中會經常接觸到的一個詞語,在最早的膠捲照片沖印中是指經曝光和顯影加工後得到的影像。負片操作在很多影象處理軟體中也叫反色,其明暗與原影象相反,其色彩則為原影象的補色。

例如顏色值A與顏色值B互為補色,則其數值的和為255。即RGB影象中的某點顏色為(0,0,255) 則其補色為 (255,255,0)。

由於負片的操作過程比較簡單,OpenCV並沒有單獨封裝負片函式,這裡我們需要將一張圖片拆分為各個顏色通道矩陣,然後分別對每一個顏色通道矩陣進行處理,最後再將其重新組合為一張圖片,示例程式碼如下。

程式碼清單③負片功能實現

import numpy as npimport cv2

# 讀入圖片img = cv2。imread(“lena。jpg”)

# 獲取高度和寬度,注意索引是高度在前,寬度在後height = img。shape[0]width = img。shape[1]

# 生成一個空的三維張量,用於存放後續三個通道的資料negative_file = np。zeros((height,width,3))

# 將BGR形式儲存的彩色圖片拆分成三個顏色通道,注意顏色通道的順序是藍、綠、紅b,g,r = cv2。split(img)

# 進行負片化處理,求每個通道顏色的補色r = 255 - rb = 255 - bg = 255 - g

# 將處理後的結果賦值到前面生成的三維張量中negative_file[:,:,0] = bnegative_file[:,:,1] = gnegative_file[:,:,2] = r

# 看一下生成圖片的資料negative_file‘’‘array([[[ 142。, 103。, 28。], [ 146。, 102。, 25。], [ 151。, 103。, 25。], 。。。, [ 197。, 162。, 89。], [ 136。, 99。, 43。], [ 106。, 73。, 23。]],

[[ 148。, 106。, 31。], [ 152。, 106。, 29。], [ 158。, 106。, 30。], 。。。, [ 176。, 143。, 80。], [ 178。, 147。, 96。], [ 190。, 164。, 118。]],

[[ 154。, 107。, 33。], [ 159。, 109。, 33。], [ 164。, 109。, 34。], 。。。, [ 199。, 175。, 123。], [ 252。, 233。, 190。], [ 255。, 252。, 215。]],

。。。, [[ 234。, 215。, 210。], [ 231。, 218。, 210。], [ 221。, 214。, 205。], 。。。, [ 235。, 221。, 198。], [ 248。, 231。, 205。], [ 247。, 228。, 201。]],

[[ 238。, 220。, 219。], [ 235。, 223。, 217。], [ 233。, 226。, 217。], 。。。, [ 242。, 226。, 203。], [ 227。, 210。, 183。], [ 214。, 196。, 165。]],

[[ 240。, 224。, 225。], [ 236。, 224。, 220。], [ 234。, 227。, 218。], 。。。, [ 242。, 226。, 203。], [ 207。, 191。, 162。], [ 184。, 165。, 132。]]])’‘’

# 將生成的圖片儲存起來,注意儲存圖片檔名中的副檔名cv2。imwrite(“negative_lena。jpg”,negative_file)

經過上述程式碼的對影象的處理,我們可以看到經過處理的影象如圖4-4b所示,原始影象如圖4-4a所示。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-4 原始影象與經過負片處理後的影象

使用負片對影象進行處理,就是將圖片的顏色進行反轉的過程,這是一個線性變換過程。在影象處理中可以增強暗色區域中的白色或灰色細節。在這個例子中,我們應該同時熟悉對彩色圖片中三個不同顏色通道的拆分以及重新構建影象的方法。

3. 亮度與對比度轉換

一般來說,影象處理運算元是將一幅或多幅影象作為輸入資料,產生一幅輸出影象的函式。影象變換可分為以下兩種。

點運算元:基於畫素變換,在這一類影象變換中,僅僅根據輸入畫素值(有時可加上某些額外資訊)計算相應的輸出畫素值。

鄰域運算元:基於影象區域進行變換。

兩種常用的點運算元,是用常數對點的畫素值進行乘法或加法運算,可以表示為:

g(i, j)=α·f(i, j)+β

其中,影象中點的位置為(i, j), α值代表增益,β值代表偏置。對影象進行亮度和對比度的變換就是一種點運算元,這兩個引數分別可以用來控制對比度與亮度。

熟悉這個原理之後,我們就可以透過調節這兩個引數的值,來對圖片進行對比度或亮度的調節。即將原影象中的每一個畫素點都加上一個偏置常數,則可以使圖片的亮度變大,類似地,可以將原圖片中的畫素點乘上一個增益係數,來調整圖片的對比度。

但是要注意,圖片畫素點的畫素值取值範圍是[0,255],一定不應該讓其溢位,否則圖片將不是我們想要的效果。

程式碼清單④分別演示了實現對圖片的畫素點進行計算的兩種方法。

程式碼清單④ 對圖片亮度與對比度轉換演示

import cv2import numpy as np

# 方法1:透過addWeighted函式來實現def convert_img1(img, alpha, beta): blank = np。zeros(img。shape, img。dtype) # dtpye is uint8 return cv2。addWeighted(img, alpha, blank, 0, beta)

# 方法2: 透過for迴圈手動實現,與addWeighted函式內部實現原理一樣def convert_img2(img, alpha, beta): rows, cols, channel = img。shape new_img = np。zeros(img。shape, img。dtype) for i in range(0,rows): for j in range(0,cols): for k in range(0,channel): # np。clip 將數值限制在[0,255]區間,防止數字溢位 new_img[i,j,k] = np。clip( alpha * img[i,j,k] + beta,0,255) return new_img

img = cv2。imread(‘lena。jpg’)cv2。imwrite(‘converted_lena_1。jpg’, convert_img1(img,2。2,50))cv2。imwrite(‘converted_lena_2。jpg’, convert_img2(img,2。2,50))

在上述程式碼中,convert_img1 函式的addWeighted 函式的引數列表分別為:

[img1, alpha, img2, beta, gamma]

代表將兩個圖片進行如下計算:

new_img=alpha·img1+beta·img2+gamma

因此,函式convert_img2 實現的過程,就是透過for迴圈修改原始圖片的畫素值,與convert_img1 函式的過程是一樣的,只不過convert_img1 函式呼叫addWeighted 函式的img2引數中圖片的畫素值都是0罷了。

可以得到變換前的圖片如圖4-5a所示,變換後的圖片如圖4-5b所示。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-5 圖片亮度與對比度轉換示例

04 幾何變換

影象的幾何變換是指對影象中的影象畫素點的位置進行變換的一種操作,它將一幅影象中的座標位置對映到新的座標位置,也就是是改變畫素點的空間位置,同時也要估算新空間位置上的畫素值。

經過幾何變換的圖片,直觀來看就是其影象的形態發生了變化,例如常見的影象縮放、平移、旋轉等都屬於幾何變換。

1. 影象裁剪

影象的裁剪實現起來相對容易,即在影象資料的矩陣中裁剪出部分矩陣作為新的影象資料,從而實現對影象的裁剪。例如下面的程式碼段落實現了對圖片的裁剪。

程式碼清單⑤ 影象裁剪演示

import cv2import numpy as npimg = cv2。imread(‘lena。jpg’)print(img。shape)# (121, 121, 3)new_img = img[20:120,20:120]cv2。imwrite(‘new_img。jpg’,new_img)

上述程式碼實現的過程是將原始的影象從第(20,20) 個畫素點的位置,裁剪到(120,120) 處,裁剪的形狀是矩形的。原始影象如圖4-6a所示,裁剪後的影象如圖4-6b所示,影象尺寸明顯變小了。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-6 影象裁剪示例

2. 影象尺寸變換

修改影象的尺寸也就是修改影象的大小,OpenCV的resize 函式可以實現這樣的功能。對影象進行尺寸變換時,必然會丟失或者增加一些畫素點,這些畫素點怎麼丟棄或者增加呢?

這就需要插值演算法了,resize 函式提供了指定插值演算法的引數。在縮放時建議使用區域插值cv2。INTER_AREA, 可以避免波紋出現;在放大時建議使用三次樣條插值cv2。INTER_CUBIC, 但是其計算速度相對較,或者線性插值cv2。INTER_LINEAR, 預設情況下所有改變影象尺寸大小的操作使用的是插值法都是線性插值。

我們可以透過設定縮放因子或者直接給出變換後圖像的尺寸,則resize 函式就可以為我們自動生成變換後的影象了。

程式碼清單⑥ 使用OpenCV變換影象尺寸

import cv2import numpy as npimg = cv2。imread(‘lena。jpg’)print(img。shape)# (121, 121, 3)new_img = cv2。resize(img,(40,40),interpolation=cv2。INTER_AREA)cv2。imwrite(‘new_img1。jpg’, new_img)print(new_img。shape)# (40, 40, 3)new_img2 = cv2。resize(img,None,fx=0。5, fy=0。6,interpolation=cv2。INTER_AREA)print(new_img2。shape)# 注意影象的寬對應的是列數,高對應的是行數# (73, 60, 3)cv2。imwrite(‘new_img2。jpg’,new_img2)

如圖4-7所示,原圖如圖4-7a所示,new_img1與new_img2分別如圖4-7b與圖4-7c所示。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-7 影象尺寸變換示例

3. 影象旋轉

我們在前面介紹過影象的旋轉原理,OpenCV為我們提供了影象的這種操作,旋轉透過getRotationMatrix2D 函式來實現。

程式碼清單⑦ 使用OpenCV實現影象旋轉

import cv2import numpy as npimg = cv2。imread(‘lena。jpg’)rows, cols, _ = img。shape# 第一個引數為旋轉中心,第二個為旋轉角度,第三個為旋轉後的縮放因子rotated_img = cv2。getRotationMatrix2D((cols/2,rows/2),45,0。4)cv2。imwrite(‘dst。jpg’,dst)

原圖如圖 4-7a 所示,經過旋轉後的影象如圖4-8所示。

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-8 經過旋轉後的影象

05 影象噪聲處理

我們曾在前面介紹過噪聲,與訊號相比,噪聲是我們不希望得到的,噪聲量越少則表明影象質量越高。由於影象採集裝置的效能不同,有的採集裝置獲得的噪聲少,有的則會很多,這可能會干擾到影象的處理。

因此,我們在這裡介紹一下噪聲的消減方法,可以用在影象的預處理上。與此同時,對訓練資料新增適量噪聲,可以使訓練後的模型更加魯棒,對模型的效能提升有一定幫助。因此,為影象新增噪聲可以起到資料增強的作用。

1. 新增噪聲

下面我們演示一下對影象新增兩種常用噪聲的方法,一種是椒鹽噪聲,另一種是高斯噪聲,它們的實現程式碼如程式碼清單⑧所示。

程式碼清單⑧ 為影象新增噪聲

import cv2import numpy as npimport random

# 新增椒鹽噪聲def salt_and_pepper_noise(img, percentage): rows, cols = img。shape num = int(percentage * rows * cols) for i in range(num): x = random。randint(0,rows - 1) y = random。randint(0,cols - 1) if random。randint(0,1) == 0: img[x,y] = 0 # 黑色噪點 else: img[x,y] = 255 # 白色噪點 return img

# 新增高斯隨機噪聲def gaussian_noise(img, mu, sigma, k): rows, cols = img。shape for i in range(rows): for j in range(cols): # 生成高斯分佈的隨機數,與原始資料相加後要取整 value = int(img[i,j] + k * random。gauss(mu=mu, sigma=sigma)) # 限定資料值的上下邊界value = np。clip(a_max=255,a_min=0,a=value) img[i,j] = value return imgimg = cv2。imread(‘lena。jpg’)

# 轉換為灰度影象gray_img = cv2。cvtColor(img,cv2。COLOR_BGR2GRAY)cv2。imwrite(‘gray_lena。jpg’,gray_img)# 需要複製一份,不然是對影象的引用,後面的操作會重疊gray_img2 = gray_img。copy

# 儲存椒鹽噪聲影象cv2。imwrite(‘salt_and_pepper。jpg’, salt_and_pepper_noise(gray_img,0。3))# 儲存高斯噪聲影象cv2。imwrite(‘gaussian。jpg’, gaussian_noise(gray_img2, 0, 1, 32))

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-9 為影象新增噪聲示例

在圖4-9中,圖4-9b是椒鹽噪聲處理後的影象,圖4-9b是高斯噪聲處理後的影象。

2. 模糊與濾波

OpenCV為我們提供了幾種濾波方法,諸如中值濾波、雙邊濾波、高斯模糊、二維卷積等,這些操作的基本方法如程式碼清單⑨所示。

程式碼清單⑨ 影象濾波演示

import cv2import numpy as npimport randomsalt_and_pepper_img = cv2。imread(‘salt_and_pepper。jpg’)gaussian_img = cv2。imread(‘gaussian。jpg’)

# 2維卷積# 得到一個5*5大小的矩陣作為卷積核,矩陣中的每個值都為0。04kernel = np。ones((5,5),np。float32) / 25conv_2d_img = cv2。filter2D(salt_and_pepper_img, -1, kernel)cv2。imwrite(‘filter_2d_img。jpg’, conv_2d_img)

# 中值濾波# 引數5表示選擇附近5*5區域的畫素值進行計算median_blur_img = cv2。medianBlur(salt_and_pepper_img,5)cv2。imwrite(‘median_blur_img。jpg’, median_blur_img)

# 高斯模糊# 標準差引數設定為0是指根據視窗大小(5,5)來自行計算高斯函式標準差gaussian_blur_img = cv2。GaussianBlur(gaussian_img, (5,5), 0)cv2。imwrite(‘gaussian_blur_img。jpg’, gaussian_blur_img)

# 雙邊濾波# cv2。bilateralFilter(src, d, sigmaColor, sigmaSpace)# 9 代表鄰域直徑,兩個引數75分別代表值域與空域標準差bilateral_filter_img = cv2。bilateralFilter(gaussian_img, 9, 75, 75)cv2。imwrite(‘bilateral_filter_img。jpg’, bilateral_filter_img)

上述操作加入過噪聲的原始影象如圖4-9所示,這兩個帶有噪聲的影象經過濾波處理的結果如圖4-10所示。

對新增過椒鹽噪聲圖片經過二維卷積濾波後的結果

對新增過椒鹽噪聲圖片進行中值濾波後的結果

對經過高斯噪聲汙染後的圖片進行高斯濾波後的結果

對經過高斯噪聲汙染後的圖片進行雙邊濾波後的結果

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

乾貨|OpenCV看這篇就夠了,9段程式碼詳解影象變換基本操作

圖4-10 帶有噪聲的影象經過濾波處理後的結果

06 小結

OpenCV是一個非常優秀且使用廣泛的開源計算機視覺庫,該庫核心程式碼採用C++編寫,提供了多種語言介面。在本文中,我們學習了OpenCV的Python介面使用方法,學習使用OpenCV對影象進行操作的基本方法。