图像的像素值是由比特组成的。例如一副256级灰度图像中,图像是由8 bit组成。
与之前对比度拉伸的区别是,之前我们主要强调在某一范围的灰度值作为我们能感兴趣的目标将其变亮或者变暗。而位图切割主要强调每个bit对图像的贡献,通过方法将不同位的灰度值值取出来还原成图像。
如图所示,一副8 bit图像,我们可以将图像分割成8个,将每个图像对应的比特位取出构建成一副新的图像
例如图像某一点的像素值为100,对应的二进制为0110 0100
我们的目标很简单,就是将第1位的0取出来(这里不要把100看成一个数,将他想象成一幅图像的所有点,我们要把图像像素对应二进制的第一位全部取出,组成一副新的图像)以此类推...
最后为了防止取出的灰度值过暗,我们将他映射到最大值255
这里提供两种方法实现:
注:
这里用第二种÷的方法实现
如果用第一种与的方法的话,只需要将中间的代码段替换成后面的就行,结果是一样的
import cv2 import numpy as np gray = cv2.imread('./img.jpg',0) img = cv2.resize(gray,None,fx = 0.5,fy = 0.5,interpolation=cv2.INTER_AREA) #缩小图像 group = [] # 存放每一层的图像 for n in range(8): dst = np.zeros_like(img) for i in range(img.shape[0]): for j in range(img.shape[1]): ret = img[i][j] // pow(2,n) #ret = img[i][j] & pow(2,n) if (ret % 2) ==1: # if (ret ==pow(2,n)): dst[i][j] = 255 else: dst[i][j] = 0 group.append(dst) cv2.imshow('0-3',np.hstack((i for i in group[:4]))) cv2.imshow('4-7',np.hstack((i for i in group[4:]))) cv2.waitKey() cv2.destroyAllWindows()
输入图像:
输出结果:
如果还原图像的话,我们再输出图像的时候,就不要映射到255,之间将图像与比特平面相与的结果输出即可
import cv2 import numpy as np gray = cv2.imread('./img.jpg',0) img = cv2.resize(gray,None,fx = 0.5,fy = 0.5,interpolation=cv2.INTER_AREA) #缩小图像 group = [] # 存放每一层的图像 for n in range(8): dst = np.zeros_like(img) for i in range(img.shape[0]): for j in range(img.shape[1]): ret = img[i][j] & pow(2,n) dst[i][j] = ret # 将与的结果作为图像 group.append(dst) cv2.imshow('0-3',np.hstack((i for i in group[:4]))) cv2.imshow('4-7',np.hstack((i for i in group[4:]))) a = np.zeros_like(img) # 还原 for i in group: a += i cv2.imshow('img',a) cv2.waitKey() cv2.destroyAllWindows()
输出比特平面:
所以图像相加为: