邏輯運(yùn)算是一種非常重要的運(yùn)算方式,圖像處理過程中經(jīng)常要按照位進(jìn)行邏輯運(yùn)算,本節(jié)介紹 OpenC'V 中的按位邏輯運(yùn)算,簡稱位運(yùn)算
在 OpenCV內(nèi),常見的位運(yùn)算函數(shù)如表 31 所示
序號 | 函數(shù)名 | 基本含義 |
---|---|---|
1 | cv2.bitwise_and() | 按位與 |
2 | cv2.bitwise_or() | 按位或 |
3 | cv2.bitwise_xor() | 按位異或 |
4 | cv2.bitwise_not() | 按位取反 |
3.3.1 按位與運(yùn)算
在與運(yùn)算中,當(dāng)參與與運(yùn)算的兩個邏輯值都是直時,結(jié)果才為真只锻。其邏輯關(guān)系可以類比圖 34 所示的串聯(lián)電路,只有當(dāng)兩個開關(guān)都閉合時,燈才會亮
表 32 對與運(yùn)算算子的不同情況進(jìn)行了說明,表中使用“and”表示與運(yùn)算
與運(yùn)算
序號 | 算子1 | 算子2 | 結(jié)果 | 規(guī)則 |
---|---|---|---|---|
1 | 0 | 0 | 0 | and(0,0)=0 |
2 | 0 | 1 | 0 | and(0,1)=0 |
3 | 1 | 0 | 0 | and(1,0)=0 |
4 | 1 | 1 | 1 | and(1,1)=1 |
按位與運(yùn)算是指將數(shù)值轉(zhuǎn)換為二進(jìn)制值后,在對應(yīng)的位置上進(jìn)行與運(yùn)算拐格。例如,表 3-3層示了兩個數(shù)值進(jìn)行按位與運(yùn)算的示例
按位與運(yùn)算
序號 | 數(shù)值 | 十進(jìn)制值 | 二進(jìn)制值 |
---|---|---|---|
1 | 數(shù)值 1 | 198 | 1100 0110 |
2 | 數(shù)值 2 | 219 | 1101 1011 |
3 | 按位與運(yùn)算結(jié)果 | 194 | 1100 0010 |
在 opencv 中,可以使用 cv2.bitwise_and(a,b) 函數(shù)來實(shí)現(xiàn)按位與運(yùn)算,其語法格式為:
dst = cv2.bitwise_and(src1,src2[,mask]])
dst 表示與輸入值具有同樣大小的 ararry輸出值
src1表示第一個 ararry 或 scalar類型的輸入值
src2 表示第二個ararry 或 scalar 類型的輸入值
mask 表示可選操作掩碼,8 位單通道 ararry
按位與操作有如下特點(diǎn)
將任何數(shù)值N 與數(shù)值0 進(jìn)行按位與操作,都會得到數(shù)值0
將任何數(shù)值N(這里僅考慮8 位值)與數(shù)值 255(8 位二進(jìn)制數(shù)是1111 1111)進(jìn)行按位與操作,都會得到數(shù)值N 本身
可以通過表 34 觀察數(shù)值N(表中是 219)與特殊值0和 255 進(jìn)行按位與運(yùn)算的結(jié)果
根據(jù)上述特點(diǎn),可以構(gòu)造一幅掩模圖像M,掩模圖像M 中只有兩種值:一種是數(shù)值0 一種是數(shù)值 255 將該掩模圖像M 與幅灰度圖像G 進(jìn)行按位與操作,在得到的結(jié)果圖像R中
與掩模圖像M 中的數(shù)值 255 對應(yīng)位置上的值,來源于灰度圖像G
與掩模圖像M 中的數(shù)值0 對應(yīng)位置上的值為零(黑色)
第 13 章將從另外一個角度對上述情況進(jìn)行說明,以幫助大家更好地理解掩模及處理方式
【例 3.7】使用數(shù)組演示與掩模圖像的按位與運(yùn)算
根據(jù)題目要求,編寫代碼如
import cv2
import numpy as np
a=np.random.randint(0,255,(5,5),dtype=np.uint8)
b=np.zeros((5,5),dtype=np.uint8)
b[0:3,0:3]=255
b[4,4]=255
c=cv2.bitwise_and(a,b)
print("a=\n",a)
print("b=\n",b)
print("c=\n",c)
a=
[[111 159 2 209 5]
[ 41 209 100 66 105]
[ 90 10 59 125 213]
[ 52 71 145 64 171]
[124 74 67 77 113]]
b=
[[255 255 255 0 0]
[255 255 255 0 0]
[255 255 255 0 0]
[ 0 0 0 0 0]
[ 0 0 0 0 255]]
c=
[[111 159 2 0 0]
[ 41 209 100 0 0]
[ 90 10 59 0 0]
[ 0 0 0 0 0]
[ 0 0 0 0 113]]
從程序可以看出,數(shù)組c 米源于數(shù)組a 與數(shù)組b 的按位與操作,運(yùn)算結(jié)果顯示,對于 數(shù)組c 內(nèi)的值,與數(shù)組b 中數(shù)值 255 對應(yīng)位置上的值來源于數(shù)組 a:與數(shù)組b 中數(shù)值0 對應(yīng)位置上的值為0
【例 3.8】構(gòu)造一個掩模圖像,使用按位與運(yùn)算保留圖像中被掩模指定的部分在本例中,我們構(gòu)造一個掩模圖像,保留圖像 lena 的頭部
根據(jù)目要求,編寫代碼如下:
import cv2
import numpy as np
a=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\lena.bmp",0)
b=np.zeros(a.shape,dtype=np.uint8)
b[100:400,200:400]=255
b[100:500,100:200]=255
c=cv2.bitwise_and(a,b)
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.imshow("c",c)
cv2.waitKey()
cv2.destroyAllWindows()
運(yùn)行上述程序,輸出結(jié)果如圖 3.5 所示,左圖是原始圖像 lena,中間的圖是掩模圖像,右圖是按位與結(jié)果圖像,可以看到,被掩模指定的頭部圖像被保留在了運(yùn)算結(jié)果中
除了需要對灰度圖像進(jìn)行掩模處理,還經(jīng)常需要針對 BGR 糢式的彩色圖像使用掩模提取指定部分。由于按位與操作要求參與運(yùn)算的數(shù)據(jù)有相同的通道,所以無法直接將彩色圖像與道的掩模圖像進(jìn)行按位與操作吼具。一般情況下,可以通過將掩模圖像轉(zhuǎn)換為 BGR 模式的彩在像,讓彩色圖像與掩模圖像進(jìn)行按位與操作,實(shí)現(xiàn)掩模運(yùn)算浆劲。
【例 3.9】構(gòu)造一個掩模圖像,使用按位與操作保留圖像內(nèi)被掩模所指定的部分雨席。
根據(jù)題目要求,編寫代碼如下
import cv2
import numpy as np
a=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\lena.bmp",1)
b=np.zeros(a.shape,dtype=np.uint8)
b[100:400,200:400]=255
b[100:500,100:200]=255
c=cv2.bitwise_and(a,b)
print("a.shape=",a.shape)
print("b.shape=",b.shape)
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.imshow("c",c)
cv2.waitKey()
cv2.destroyAllWindows()
運(yùn)行上述程序,輸出結(jié)果如圖 36 所示,其中左圖是原始圖像,中間的圖是掩模圖像,右圖是原始圖像和掩模圖像按位與后提取的圖像止邮。由于本書為黑白印刷,所以為了更好地觀察行效果,請大家親自上機(jī)運(yùn)行程序
輸出:
a.shape= (512, 512, 3)
b.shape= (512, 512, 3)
3.3.2 按位或運(yùn)算
或運(yùn)算的規(guī)則是温技,當(dāng)參與或運(yùn)算的兩個邏輯值中有一個為真時笛求,結(jié)果就為真廊移,其邏輯關(guān)系可以類比為如圖的并聯(lián)電路,兩個開關(guān)中只要有任何一個閉合時探入,燈就會亮
序號 | 算子1 | 算子2 | 結(jié)果 | 規(guī)則 |
---|---|---|---|---|
1 | 0 | 0 | 0 | or(0,0)=0 |
2 | 0 | 1 | 0 | or(0,1)=1 |
3 | 1 | 0 | 0 | or(1,0)=1 |
4 | 1 | 1 | 1 | or(1,1)=1 |
按位或運(yùn)算是指將數(shù)值轉(zhuǎn)換為二進(jìn)制值后,在對應(yīng)的位置上進(jìn)行或運(yùn)算狡孔。例如,表 3.6展 示了兩個數(shù)值邊行按位或運(yùn)算的示例
序號 | 數(shù)值 | 十進(jìn)制值 | 二進(jìn)制值 |
---|---|---|---|
1 | 數(shù)值 1 | 198 | 1100 0110 |
2 | 數(shù)值 2 | 219 | 1101 1011 |
3 | 按位與運(yùn)算結(jié)果 | 223 | 1101 1111 |
在 OpenCV中,可以使用 cv2.bitwise_or(a,b) 函數(shù)來實(shí)現(xiàn)按位或運(yùn)算,其語法格式為
dst = cv2.bitwise_or(src1,src2[,mask]])
式中
dst 表示與輸入值具有同樣大小的 arrary輸出值
src1表示第一個 ararry 或 scalar類型的輸入值
src2 表示第二個ararry 或 scalar 類型的輸入值
mask 表示可選操作掩碼,8 位單通道 arrary值
3.3.3 按位非運(yùn)算
非運(yùn)算是取反操作,滿足如下邏輯
1 當(dāng)運(yùn)算數(shù)為真時,結(jié)果為假
2 當(dāng)算數(shù)為為假時,結(jié)果為真
表 3.7 對參與運(yùn)算算子的不同情況進(jìn)行了說明,表中使用“not”表示非運(yùn)算
序號 | 算子 | 結(jié)果 | 規(guī)則 |
---|---|---|---|
1 | 0 | 1 | not(0)=1 |
2 | 1 | 0 | not(1)=0 |
按位非運(yùn)算是指將數(shù)值轉(zhuǎn)換為二進(jìn)制值后,在對應(yīng)的位置上進(jìn)行非運(yùn)算,例如,3-8 示了按位非運(yùn)算的示例
序號 | 說明 | 十進(jìn)制值 | 二進(jìn)制值 |
---|---|---|---|
1 | 原始值 | 198 | 1100 0110 |
2 | 按位非運(yùn)算結(jié)果 | 57 | 0011 1001 |
在 OpenCV中,可以使用函數(shù) cv2.bitwise_not 來實(shí)現(xiàn)按位取反操作,其語法格式為
dst = cv2.bitwise_not(src[,mask]])
式中
dst 表示與輸入值具有同樣大小的 arrary輸出值
src表示第一個 ararry 或 scalar類型的輸入值
mask 表示可選操作掩碼,8 位單通道 arrary值
3.3.4 按位異或運(yùn)算
異或運(yùn)算也叫半加運(yùn)算,其運(yùn)算法則與不帶進(jìn)位的二進(jìn)制加法類似,其英文為"exclusive OR" 因此其函數(shù)常表示為 xor
表 3-9 對參與異或運(yùn)算的算子的不同悟況進(jìn)行了說明,其中“xor”表示異或運(yùn)算
序號 | 算子1 | 算子2 | 結(jié)果 | 規(guī)則 |
---|---|---|---|---|
1 | 0 | 0 | 0 | xor(0,0)=0 |
2 | 0 | 1 | 1 | xor(0,1)=1 |
3 | 1 | 0 | 1 | xor(1,0)=1 |
4 | 1 | 1 | 0 | xor(1,1)=0 |
按位異或運(yùn)算是指將數(shù)值轉(zhuǎn)換為二進(jìn)制值后,在對應(yīng)的位置進(jìn)行異或運(yùn)算,
展示了兩個數(shù)值進(jìn)行按位異或運(yùn)算的示例
序號 | 數(shù)值 | 十進(jìn)制值 | 二進(jìn)制值 |
---|---|---|---|
1 | 數(shù)值 1 | 198 | 1100 0110 |
2 | 數(shù)值 2 | 219 | 1101 1011 |
3 | 按位異或運(yùn)算結(jié)果 | 29 | 0001 1101 |
在 OpenCV中,可以使用函數(shù) cv2.bitwise_xor 來實(shí)現(xiàn)按位異或操作,其語法格式為
dst = cv2.bitwise_xor(src1蜂嗽,src2[,mask]])
式中
dst 表示與輸入值具有同樣大小的 arrary輸出值
src1表示第一個 ararry 或 scalar類型的輸入值
src2 表示第二個ararry 或 scalar 類型的輸入值
mask 表示可選操作掩碼,8 位單通道 arrary值