8-Bit Plane Slicing 位元平面分割 詳細解說 # 附 Python 程式碼

[影像處理 Image Processing]

8-Bit Plane Slicing 位元平面分割 詳細解說 # 附 Python 程式碼

觀念解說︰

8-bit plane slicing 主要作用於進行影像處理時,在影像中切割出高頻與低頻的資訊

8-bit plane slicing分割抽像圖
8-bit plane slicing分割抽像圖

如上圖所示,你可以想像,在一張灰階(8-bits)圖片的每一個像素pixel將被分層切割(0-7層),總共8層,像漢堡一樣,這就是8-bit plane slicing

在一張灰階圖片,其像素值範圍是 0 - 255 ,分別用於表達不同的深淺灰度,而圖片中每一個像素點(pixel),都會有一個像素值(pixel value)。這一章將會以灰階圖片作為示例。

像素點、像素值的解釋,可以參考這篇文章。

其實圖片在數值處理上,就像一張網格網格裡每一個格子都有不同的數值,代表著不同的顏色。(RGB色彩圖示則用了三層的網格去表示,每一格由 RED, GREEN, BLUE 三種顏色組成)

計算方法︰

8-bit plane slicing 其實就是將每一個像素值(pixel value)的二進制值,以其每個位數 (20 - 27) 進行過濾。

假設以下表格是一張灰階圖片的像素值(數值範圍0-255)︰

2179785
21219115
177204104
e.g. 網格裡每一個格子都有不同的數值,代表著不同的顏色。(如上所示) ( 0 - 255)

1. 首先我們可以將灰階圖片裡的所有像素值 (範圍︰0 - 255) 轉為2進制表達。

十進制二進制
00000 0000
10000 0001
20000 0010
30000 0011
............
1270111 1111
............
2551111 1111

2. 然後我們將圖片裡的每一格像素(pixel),抽取其二進制值每個位數的值,成為Bit-plane。我將會以下方像素值為例︰

2179785
21219115
177204104
像素值(十進制表示)

假設我們要提取第0層 (Bit-plane 0) ︰

首先,檢查每個像素值的「第0位」(以下標示綠色的位置)的值,檢查第0位的值是0或是1。

若值是1時,表示這個位數擁有圖像的資訊,在 Bit-plane 0 需要保留。

若值是0時,表示這個位數沒有原圖的資訊,在 Bit-plane 0 不需要保留。

1101 10010110 00010101 0101
0001 01011101 10110111 0011
1011 00011100 11000110 1000
像素值(二進制表示) - 擷取 Bit-plane 0 進行中...

經過過濾擷取後,Bit-plane 0 就生成了,如下表所示︰

0000 00010000 00010000 0001
0000 00010000 00010000 0001
0000 00010000 00000000 0000
Bit-plane 0

Bit-plane 1 :

1101 10010110 00010101 0101
0001 01011101 10110111 0011
1011 00011100 11000110 1000
像素值(二進制表示) - 擷取 Bit-plane 1 進行中...
0000 00000000 00000000 0000
0000 00000000 00100000 0010
0000 00000000 00000000 0000
Bit-plane 1

Bit-plane 2 :

1101 10010110 00010101 0101
0001 01011101 10110111 0011
1011 00011100 11000110 1000
像素值(二進制表示) - 擷取 Bit-plane 2 進行中...
0000 00000000 00000000 0100
0000 01000000 00000000 0000
0000 00000000 01000000 0000
Bit-plane 2

Bit-plane 3, Bit-plane 4, Bit-plane 5, Bit-plane 6, Bit-plane 7, 如此類推......

可以參考這張圖片幫助理解

利用以上方法,取得Bit-plane 0 - 7層。若是將圖片的像素值以灰階圖顯示,效果如下︰

灰階原圖
灰階原圖
Bit-plane 0 - 7層示例圖
Bit-plane 0 - 7層示例圖

可以看出,bit plane 1 , bit plane 2 , bit plane 3 的圖像十分模糊,甚至可視之為雜訊,人類的肉眼是無法辨識的。一些圖像壓縮方法便是將這些低頻資訊去除,保留其高頻資訊,以達致壓縮效果。

Python 程式碼實作

以下是使用Python 進行 8-bit plane slicing 的程式碼︰

程式是讀取這張圖片,可以下載回去試試運行。

Lenna原圖
Lenna原圖
def showImage(title, img): #顯示圖像function
      ishow = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
      plt.imshow(ishow)
      plt.axis('off')
      plt.title(title)
      plt.show()

  #需要import的函式庫
  import cv2
  import numpy as np
  import matplotlib.pyplot as plt
  
  # 讀取灰階影像
  Lenna = cv2.imread("Lenna.png", 0)
  #cv2.imshow("Lenna", Lenna)
  showImage("Lenna", Lenna)

  # 取出影像 rows and cols
  r, c = Lenna.shape

  # 產生 8 個 bit-plane 對應的 mask
  x = np.zeros((r,c), dtype = np.uint8)
  print("x.ndim = ", x.ndim)

  # 建立 8 個空白的 bit-planes
  r = np.zeros((r,c,8), dtype = np.uint8)
  #print(r)

  # 建立相對應的 bit-planes
  # r[:,:,i] 代表著被分割出來的每一層bit-planes
  # r2只是用作將r[:,:,i]每一層bit-planes大於0的元素轉變為白色(用於顯示圖片),會比較清晰。
  for i in range(8):
      x = 2**i
      r[:,:,i] = cv2.bitwise_and(Lenna, x)
      mask = r[:,:,i] > 0
      r2 = np.copy(r)
      r2[mask] = 255
      #cv2.imshow(str(i), r2[:,:,i])
      showImage(str(i), r2[:,:,i])

  print("重構圖片:")
  original = r[:,:,7]
  for i in range(8,0,-1): 
      #print(i)
      original = cv2.bitwise_or(original,r[:,:,i-1])
      showImage(str(i-1),original)

  showImage("Reault: Original",original)

  #cv2.waitKey()
  #cv2.destroyAllWindows()
被分割出來的bit plane
被分割出來的bit plane

留言

張貼留言

這個網誌中的熱門文章

2023年回到香港IT面試經驗

Histogram Equalization - 直方圖均衡化 詳細解說 # 附 Python 程式碼