You probably know that everything on a computer is stored as strings of bits. In Bit-plane slicing, we take the advantage of this fact to perform various image operations. Let’s see how.
I hope you have basic understanding of binary and decimal relationship.
For an 8-bit image, a pixel value of 0 is represented as 00000000 in binary form and 255 is encoded as 11111111. Here, the leftmost bit is known as the most significant bit (MSB) as it contributes the maximum. e.g. if MSB of 11111111 is changed to 0 (i.e. 01111111), then the value changes from 255 to 127. Similarly, rightmost bit is known as Least significant bit (LSB).
In Bit-plane slicing, we divide the image into bit planes. This is done by first converting the pixel values in the binary form and then dividing it into bit planes. Let’s see by an example.
For simplicity let’s take a 3×3, 3-bit image as shown below. We know that the pixel values for 3-bit can take values between 0 to 7.
I hope you understand what is bit plane slicing and how it is preformed. Next Question that comes to mind is What’s the benefit of doing this?
Pros:
- Image Compression (We will see later how we can construct nearly the original image using less number of bits).
- Converting a gray level image to a binary image. In general, images reconstructed from bit planes is similar to applying some intensity transformation function to the original image. e.g. Image reconstructed from MSB is same as applying thresholding function to the original image. We will validate this in the code below.
- Through this, we can analyze the relative importance of each bit in the image that will help in determining the number of bits used to quantize the image.
Let’s see how we can do this using OpenCV-Python
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import numpy as np import cv2 # Read the image in greyscale img = cv2.imread('D:/Downloads/reference.jpg',0) #Iterate over each pixel and change pixel value to binary using np.binary_repr() and store it in a list. lst = [] for i in range(img.shape[0]): for j in range(img.shape[1]): lst.append(np.binary_repr(img[i][j] ,width=8)) # width = no. of bits # We have a list of strings where each string represents binary pixel value. To extract bit planes we need to iterate over the strings and store the characters corresponding to bit planes into lists. # Multiply with 2^(n-1) and reshape to reconstruct the bit image. eight_bit_img = (np.array([int(i[0]) for i in lst],dtype = np.uint8) * 128).reshape(img.shape[0],img.shape[1]) seven_bit_img = (np.array([int(i[1]) for i in lst],dtype = np.uint8) * 64).reshape(img.shape[0],img.shape[1]) six_bit_img = (np.array([int(i[2]) for i in lst],dtype = np.uint8) * 32).reshape(img.shape[0],img.shape[1]) five_bit_img = (np.array([int(i[3]) for i in lst],dtype = np.uint8) * 16).reshape(img.shape[0],img.shape[1]) four_bit_img = (np.array([int(i[4]) for i in lst],dtype = np.uint8) * 8).reshape(img.shape[0],img.shape[1]) three_bit_img = (np.array([int(i[5]) for i in lst],dtype = np.uint8) * 4).reshape(img.shape[0],img.shape[1]) two_bit_img = (np.array([int(i[6]) for i in lst],dtype = np.uint8) * 2).reshape(img.shape[0],img.shape[1]) one_bit_img = (np.array([int(i[7]) for i in lst],dtype = np.uint8) * 1).reshape(img.shape[0],img.shape[1]) #Concatenate these images for ease of display using cv2.hconcat() finalr = cv2.hconcat([eight_bit_img,seven_bit_img,six_bit_img,five_bit_img]) finalv =cv2.hconcat([four_bit_img,three_bit_img,two_bit_img,one_bit_img]) # Vertically concatenate final = cv2.vconcat([finalr,finalv]) # Display the images cv2.imshow('a',final) cv2.waitKey(0) |
The output looks like this
Clearly from the above figure, the last 4 bit planes do not seem to have much information in them.
Now, if we combine the 8,7,6,5 bit planes, we will get approximately the original image as shown below.
This can be done by the following code
1 2 3 4 5 |
# Combining 4 bit planes new_img = eight_bit_img+seven_bit_img+six_bit_img+five_bit_img # Display the image cv2.imshow('a',new_img) cv2.waitKey(0) |
Clearly, storing these 4 frames instead of the original image requires less space. Thus, it is used in Image Compression.
I hope you understand Bit plane slicing. If you find any other application of this, please let me know. Hope you enjoy reading.
If you have any doubt/suggestion please feel free to ask and I will do my best to help or improve myself. Good-bye until next time.
i am new to python. Your post are great. I am taking interest into python. Please help me to understand line.
eight_bit_img = (np.array([int(i[0]) for i in lst],dtype = np.uint8)
or give me link to understand ([int(i[0]) for i in lst] line
Thanks. This is known as List comprehension in Python (You can google it). The above line is equivalent to
Hope this helps.
Many this for this helpful post.
Can we apply this to a video?
Thank you very much
This tutorial and code is useful for me
Good luck
Excellent and concise explanation with an example to boot. Thank you.
I’ve been strugglig with this topic and thus always left it… thank you for making it so easy for me to understand !