1. 程式人生 > >【影象處理】使用OpenCV+Python進行影象處理入門教程(二)

【影象處理】使用OpenCV+Python進行影象處理入門教程(二)

       這篇隨筆介紹使用OpenCV進行影象處理的第二章 影象的運算,讓我們踏上繼續回顧OpenCV進行影象處理的奇妙之旅,不斷地總結、回顧,以新的視角快速融入計算機視覺的奧祕世界。

2  影象的運算

       複雜的影象處理是藉助基礎的影象運算來實現的,本章介紹影象運算的基本操作,為後續實現更加複雜的處理提供幫助。

2.1  影象加法運算

       可以通過加法運算子“+”和cv2.add函式實現影象的加法運算,但這兩種方法對資料求和後溢位255的處理方式不一樣。

       設a、b均為8為灰度影象,畫素飽和值為255。a影象畫素值為a,b影象畫素值為b。

(一)加法運算子“+”

原理:取餘運算:a+b = (a+b)mod(256)

語法格式:

print('a+b=\n',a+b)

該方法會使兩數之和大於255時取餘,兩數之和小於255時不變。

(二)cv2.add()函式

語法格式:

result=cv2.add(a,b)

該方法會使兩數之和大於255時置為255,兩數之和小於255時不變。

在cv2.add()函式中,有下列三種用法:影象與影象加法、影象與數值加法、數值與影象加法,如:

img3=cv2.add(img1,img2)   #影象與影象加法
img3=cv2.add(img1,5)         #影象與數值加法
img3=cv2.add(7,img2)         #數值與影象加法

 

2.2  影象加權之和

       實際影象加法過程中,可能要考慮不同影象的權重,也就是影象的加權之和。

       使用cv2.addWeighted()函式實現,但需保證兩幅圖片大小和型別相同。

語法格式:

#alpha是img1的權重,beta是img2的權重,gamma是整體亮度調節引數,不能省略
img3=cv2.addWeighted(img1,alpha,img2,beta,gamma)

 

2.3  按位邏輯運算

       按位邏輯運算的原理與電路中“與門”“或門”“異或門”“非門”類似,是非常重要的一種基本運算方式。

Opencv中使用如下函式進行按位邏輯運算:

cv2.bitwise_and()  #按位與,兩邏輯值為真,則為真
cv2.bitwise_or()   #按位或,兩邏輯值有一真,則為真
cv2.bitwise_xor()  #按位異或,兩邏輯值相同為假,不同為真
cv2.bitwise_not()  #按位非,邏輯值取反

其語法格式如下:

c=cv2.bitwise_and(a,b)
c=cv2.bitwise_or(a,b)
c=cv2.bitwise_xor(a,b)
c=cv2.bitwise_not(a,b)

注1:掩模影象用於對另一幅圖片中ROI區域的掩蓋處理,掩模影象只有兩種數值:0和255,常和另一幅影象進行按位邏輯運算。一幅圖片中的數值與掩模影象中的0值按位與後,數值變為0(黑色遮蓋);與掩模影象中的255值按位與後,數值不變(原區域)。

注2:如果待處理影象為彩色,就需要將掩模影象轉為BGR模式的彩色影象,如:

a=cv2.imread('tupian',1)    #讀取圖片
b=np.zeros(a.shape,dtype=np.uint8)   #轉為BGR型別

 

2.4  掩模(掩碼)

       上一小節中提到了掩模影象的概念,舉例來解釋,例如:

 1 import cv2
 2 import numpy as np
 3 img1=np.ones((4,4),dtype=np.uint8)*2  #生成4×4的二維陣列img1
 4 img2=np.ones((4,4),dtype=np.uint8)*6  #生成4×4的二維陣列img2
 5 mask=np.zeros((4,4),dtype=np.uint8)   #生成4×4的掩模陣列mask
 6 mask[1:3,1:3]=1
 7 img3=np.ones((4,4),dtype=np.uint8)*99 #生成4×4的二維陣列img3
 8 print('img1=\n',img1)
 9 print('img2=\n',img2)
10 print('mask=\n',mask)
11 print('初始值img3=\n',img3)
12 img3=cv2.add(img1,img2,mask=mask)     #img3與mask進行掩模運算
13 print('求和後的img3=\n',img3)

       上例所示的掩模mask值有兩種,一種是空值0,一種是非空值(一般取1或255等容易按位與操作的數值)。當mask值為0的畫素點,與另一畫素矩陣對應位點按位與操作後,數值依然是0,相當於把這一畫素矩陣構成的圖片用黑布遮蓋掉一部分;當mask值非空,就可以處理這些非空值對應在另一畫素矩陣上的位點。

       當彩色影象與掩模影象計算時,需要將掩模轉換為BGR模式的三通道彩色圖,繼而實現掩模運算。

 

2.5  位平面分解

       將一幅灰度影象中不同畫素位點上的同一位元位二進位制數組合在一起,會得到一張二進位制影象,該影象稱為灰度影象的一個位平面,該過程叫做位平面分解。是不是還不明白什麼叫做位平面?哈哈彆著急,我們看下面舉例。

       設一張灰度影象的畫素值為:

147 206 168 243
72 198 49 126
132 77 186 62
228 157 129 28

 

 

 

 

 

將其轉化為二進位制數為:

將這些畫素點A同一位元位點上的值組合,得到8個位平面:

A0表示第0個位平面,依次類推。

位平面分解,有5個步驟 :影象預處理、構造提取矩陣、提取位平面、閾值處理、顯示影象。其演算法實現如下例所示:

 1 import cv2
 2 import numpy as np
 3 lena=cv2.imread('E:\python_opencv\lena.jpg',0)
 4 cv2.imshow('lena',lena)
 5 r,c=lena.shape
 6 x=np.zeros((r,c,8),dtype=np.uint8)   #設定各個位平面的提取矩陣,8個通道
 7 for i in range(8):
 8     x[:,:,i]=2**i                    #設定各個位平面提取矩陣的值2**i
 9 r=np.zeros((r,c,8),dtype=np.uint8)
10 for i in range(8):
11     r[:,:,i]=cv2.bitwise_and(lena,x[:,:,i])  #原圖與提取矩陣值按位與運算
12     mask=r[:,:,i]>0                  #閾值處理
13     r[mask]=255
14     cv2.imshow(str(i),r[:,:,i])
15 cv2.waitKey()
16 cv2.destroyAllWindows()

 

2.6  影象加密和解密

       將影象與祕鑰影象按位異或,能夠實現影象的加密;將加密後的影象再次與祕鑰影象按位異或,可以實現影象的解密。對一個畫素點加密和解密的舉例如下:

bit_xor(216,178)=106  #對畫素點216加密
bit_xor(106,178)=216  #對畫素點216解密

影象的加密和解密程式舉例如下:

encryption=cv2.bitwise_xor(lena,key)  #lena與key按位異或加密
dncryption=cv2.bitwise_xor(encryption,key)  #加密圖與key按位異或解密

 

2.7  數字水印

       先介紹一個定義:最低有效位(Least Significant Bit, LSB)指一個二進位制數中的第0位。

       數字水印即一幅影象中的最低有效位上隱藏了資訊,該資訊可以是音訊、視訊、影象等,為了形象介紹,本節將隱藏的水印資訊使用簡單的二值影象表示。

       實現數字水印分為兩個過程:嵌入過程和提取過程。

嵌入過程:先將載體影象的畫素進行二進位制轉化處理,然後把水印影象的畫素值進行閾值處理變為1或0,最後把載體影象的最低有效位替換為二進位制水印影象(按位或運算)。

提取過程:先讀取嵌入水印後的影象,生成一個同樣大小和型別的提取矩陣(元素值均為1),最後將嵌入水印的影象與該提取矩陣進行按位與運算。

 

這次內容就分享到這裡了,下次繼續更新第3章色彩空間的型別轉換,希望與各位老師和小夥伴們交流學習~

&n