什么是位平面分解
將灰度圖像中處于統(tǒng)一比特位上的二進制像素值進行組合,得到一副二進制圖像筑凫,該圖像被稱為灰度圖像的一個位平面,這個過程被稱為位平面分解。例如诫惭,將一副灰度圖像內(nèi)所有像素點上處于二進制位內(nèi)的最低位上的值進行組合翩活,可以構(gòu)成“最低有效位”位平面。
在8位灰度圖像中,每一個像素使用8位二進制來表示缓艳,其值的范圍在[0,255]之間,從低到高的分別位:
00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000
取這些值之后看峻,我們通過按位與運算阶淘,就可以得到所有位平面分解圖。至于有什么用呢互妓?聰明的小伙伴肯定知道溪窒。比如,我們需要給一個圖像添加水印冯勉,是在高位平面添加好澈蚌,還是最低有效位平面添加好呢?
當然是低位平面灼狰,因為它的信息最少宛瞄,添加水印后,去除水印也比較容易交胚。
灰度圖位平面分解
既然份汗,我們了解了灰度位平面分解以及它的所有知識。下面承绸,我們就來獲取一張繪圖圖像裸影,提取它的所有位平面圖。
具體代碼如下所示:
import cv2
import numpy as np
a = cv2.imread("4.jpg", 0)
r, c = a.shape
b = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
b[:, :, i] = 2 ** i
for i in range(8):
temp = cv2.bitwise_and(a, b[:, :, i])
cv2.imshow(str(i),temp)
cv2.waitKey()
cv2.destroyAllWindows()
運行之后军熏,我們得到灰度圖像的8個位平面圖:
彩色圖位平面分解
既然灰度圖像有其位平面,那么彩色圖像同樣也可以提取出來卷扮。但是因為彩色圖像的矩陣為3維矩陣荡澎,所以我們需要給RGB的每個顏色值進行按位與運算。
具體代碼如下所示:
import cv2
import numpy as np
a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
b[:, :, i] = 2 ** i
temp = np.zeros((x, y, 3), dtype=np.uint8)
for i in range(8):
temp[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
temp[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
temp[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])
cv2.imshow(str(i), temp)
cv2.waitKey()
cv2.destroyAllWindows()
運行之后晤锹,我們會得到下面8張位平面圖:
閾值
不知道摩幔,讀者注意到了沒有,不管是灰度圖像還是彩色圖像鞭铆,其0-4位圖的細節(jié)幾乎看不到或衡,都是黑色的。這個時候如何讓其細節(jié)更加凸顯呢车遂?
答案是改變其閾值封断,它們數(shù)值肯定非常小,我們直接把其更改為255舶担,除0之外都可以凸顯其細節(jié)出來∑绿郏現(xiàn)在我們把彩色位圖提取的代碼更改一下,代碼如下:
import cv2
import numpy as np
a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
b[:, :, i] = 2 ** i
temp = np.zeros((x, y, 3), dtype=np.uint8)
for i in range(8):
temp[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
temp[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
temp[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])
m = temp[:, :] > 0
temp[m] = 255
cv2.imshow(str(i), temp)
cv2.waitKey()
cv2.destroyAllWindows()
運行之后衣陶,效果如下所示:
彩色位平面圖合成
既然有分解柄瑰,那么肯定有合成闸氮。所以我們也需要掌握如何將所有位平面合成為一張圖。代碼如下:
import cv2
import numpy as np
a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
b[:, :, i] = 2 ** i
bit_img = np.zeros((x, y, 3), dtype=np.uint8)
temp = np.zeros((x, y, 3), 'uint8')
for i in range(8):
bit_img[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
bit_img[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
bit_img[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])
temp[:, :, 0] = cv2.bitwise_or(temp[:, :, 0], bit_img[:, :, 0])
temp[:, :, 1] = cv2.bitwise_or(temp[:, :, 1], bit_img[:, :, 1])
temp[:, :, 2] = cv2.bitwise_or(temp[:, :, 2], bit_img[:, :, 2])
m = bit_img[:, :] > 0
bit_img[m] = 255
#cv2.imshow(str(i)+".bmp",bit_img)
cv2.imshow('00000000', temp)
cv2.waitKey()
cv2.destroyAllWindows()
這里教沾,我們通過按位或bitwise_or函數(shù)合并為位平面圖蒲跨。運行之后,temp就是原圖授翻,而bit_img就是位平面圖财骨。這樣我們在實際處理的時候,能在中間對位平面圖bit_img進行操作后藏姐,在合并為一張圖隆箩。
灰度位平面圖合成
彩色比灰度要復雜的多,灰度位平面圖合并就相對較為簡單羔杨。話不多說捌臊,我們直接上代碼:
import cv2
import numpy as np
a = cv2.imread("4.jpg", 0)
r, c = a.shape
b = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
b[:, :, i] = 2 ** i
c=np.zeros((r,c),dtype=np.uint8)
for i in range(8):
temp = cv2.bitwise_and(a, b[:, :, i])
c=cv2.bitwise_or(c,temp)
cv2.imshow("111",c)
cv2.waitKey()
cv2.destroyAllWindows()