這篇隨筆介紹使用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 |
將其轉化為二進制數為:

將這些像素點Ai 同一位元位點上的值組合,得到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章色彩空間的型別轉換,希望與各位老師和小伙伴們交流學習~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/265597.html
標籤:其他
