# Bit plane slicing in python

I recently came across a technique called bit-plane slicing for image compression in a book "Digital image processing" by gonzalez and woods . They just presented the theory and i wanted to implement it . So ,my code just creates images out of 8th bit and 7th bit plane seperately and saves them . I just wanted to make sure that the output is really correct . please check these code and make it more efficient or give your own version.

import numpy as np
import cv2

#create a image array
row ,col = img.shape
#convert each interger pixel value of given image to a bit pixel value of 8-
#bits
def intToBitArray(img) :
list = []

for i in range(row):
for j in range(col):
list.append (np.binary_repr( img[i][j] ,width=8  ) )

return list #the binary_repr() fucntion returns binary values but in
#string
#, not integer, which has it's own perk as you will notice

#as variable name says ,it's list of pixel values in binary , but in 1
#dimension
imgIn1D = intToBitArray(img)
#reshaping above 1D array to a matrix aka image
imgIn2D = np.reshape(imgIn1D , (360,640) )
def bitplane(bitImgVal , img1D ):

'''
this function extracts the specific bit out of each binary pixel values of
the matrix
for example , if bitImgVal = 3 , then , third bit of each pixel is extracted

:param bitImgVal: specifies the position of bit to be extracted
:param img1D: image which is to be compressed
:return: now returns 1 dimensional list of bits
'''
bitList = [  int(   i[bitImgVal]  )    for i in img1D]

return bitList
#i don't know why but the multiplication factor is : 2^(n-1) where n is the
bit number
#example, if binary pixel value is 11001010 and n = 3 , factor = 2^(3-1)
#image represented by 8th bit plane
eightbitimg = np.array( bitplane(0, imgIn1D ) ) * 128

#image represented by 7th bit plane
sevenbitimg = np.array( bitplane(1,imgIn1D) ) * 64

#bitplane of 8th and 7th bit
combine = eightbitimg + sevenbitimg
comb = np.reshape(combine,(row,col))

#save combined plane image
cv2.imwrite("comb.jpeg",comb)

#save eight bit plane
eightbitimg = np.reshape(eightbitimg,(row,col))
cv2.imwrite("8bitvalue.jpg" , eightbitimg )

#save eight bit plane
sevenbitimg = np.reshape(sevenbitimg,(row,col))
cv2.imwrite("7bitvalue.jpg",sevenbitimg)

#grayscale version of original image
cv2.imwrite("gray.jpeg",gray)


the images are as : eigth BIt image: seventh bit image import cv2
import numpy as np

out = []

for k in range(0, 7):
# create an image for each k bit plane
plane = np.full((img.shape, img.shape), 2 ** k, np.uint8)
# execute bitwise and operation
res = cv2.bitwise_and(plane, img)
# multiply ones (bit plane sliced) with 255 just for better visualization
x = res * 255
# append to the output list
out.append(x)

cv2.imshow("bit plane", np.hstack(out))
cv2.waitKey()


When we talk about Bit-Plane Slicing, we means to get each bit-plane eg. 0, 1 or more and then convert it to int and then try to show that bit plane. Then we will be able to see the impact of each Bit-Plane in image. My code do this as follow:

def getPlane(planeId, binary_image):
switcher = {
7:[int(b + '0'*7) for b in binary_image],
6:[int( '0' + b + '0'*6) for b in binary_image],
5:[int( '0'*2 + b + '0'*5) for b in binary_image],
4:[int( '0'*3 + b + '0'*4) for b in binary_image],
3:[int( '0'*4 + b + '0'*3) for b in binary_image],
2:[int( '0'*5 + b + '0'*2) for b in binary_image],
1:[int( '0'*6 + b + '0') for b in binary_image],
0:[int( '0'*7 + b) for b in binary_image]
}
return switcher.get(planeId, None)

# image size is (225, 225)
bit_planes = []
c = 0
while( c < 225*225):
bit_planes.append (np.binary_repr( img[c] ,width=8  ) )
c  = c + 1
c = 0
while(c < 8):
cv.imwrite('Bit_Plane\plane'+str(c)+ '.jpg', np.array(getPlane(c, bit_planes)).reshape(225, 225))
c = c + 1