学习来自:
- 位平面分割(Bit-Plane Slicing)
- 使用OpenCV+Python进行图像处理的初学者指南
位平面
位平面(bitplane)是一个在计算机科学中用于描述图像数据的概念,具体定义如下:
- 【定义】:位平面是用图像作为底面,用表示像素亮度大小的二进制数(通常为8位)作为高度,所形成的一个立体直方图。在这个直方图中,各像素位置相同的位会形成一个平面,这个平面就被称为“位平面”。
- 【解释】:
- 对于一个灰度图像,每个像素的亮度通常由一个8位的二进制数表示,这个二进制数的范围是00000000(亮度为0)到11111111(亮度为255)。
- 如果我们将这些二进制数的每一位(从最低位到最高位)分别提取出来,并单独处理,那么就可以得到8个位平面。每个位平面都是一个二值图像,其中像素值要么是0,要么是1。
- 最低位(Least Significant Bit,LSB) 的位平面通常包含图像中的噪声和细节信息,而 最高位(Most Significant Bit,MSB) 的位平面则包含图像的主要轮廓和形状信息。
- 【用途】:位平面的概念在图像处理、压缩和传输中有重要应用。通过分析或修改不同的位平面,我们可以对图像进行各种操作,如降噪、增强、压缩等。
综上所述,位平面是图像处理中的一个重要概念,它通过将图像的每个像素的二进制表示进行分解,得到一系列的二值图像,这些二值图像就是位平面。每个位平面都包含了图像的不同信息,通过处理这些位平面,我们可以对图像进行各种操作。
位平面分割
位平面分割(Bit-Plane Slicing)是一种在数字图像处理中分析图像各个位级的方法。具体来说,位平面分割是指将图像的灰度值(通常是一个8位的二进制数)按照每一位(从最低位到最高位)进行拆解,从而得到多个独立的位平面。
-
【基本概念】:
- 位平面:一个灰度图像的每个像素值通常由一个8位的二进制数表示,这个二进制数的每一位都可以视为一个独立的平面,称为位平面。
- 位平面分割:将灰度图像的每个像素值的二进制表示中的每一位单独提取出来,形成独立的位平面图像。
-
【分割过程】:
- 对于一个8位深度的灰度图像,可以将其分割为8个位平面。
- 每个位平面上的像素值只有0或1,代表原图像在该位上的值。
- 最高位(MSB)的位平面通常包含图像的主要轮廓和形状信息,而最低位(LSB)的位平面则包含噪声和细节信息。
-
【应用】:
- 位平面分割在图像压缩中有着重要的应用,因为它可以有效减少图像的存储大小。例如,如果一个图像的最高位平面存储的是图像的主要信息,那么将其单独存储可以大大减小图像的大小。
- 位平面分割也广泛应用于数字水印、特征提取等领域,通过对每个位平面进行单独处理,可以更加精细地处理图像信息,提高图像处理的效率和精度。
-
【操作步骤】:
- 读入灰度图像并将其转换为二进制形式,即将每个像素点的灰度值表示成8位二进制数。
- 对于每个像素点的二进制数,将它们按位拆分为8个二进制数,每个数表示一个位平面。
- 对于每个位平面,将其转换为0或255的二值图像。具体方法是将每个像素点的该位的二进制数值提取出来,然后将该值赋为0或255。
- 保存每个位平面的二值图像,以便后续使用。
总之,位平面分割是一种有效的图像处理技术,它通过将图像的灰度值按照每一位进行拆解,得到多个独立的位平面,从而可以对图像进行更精细的分析和处理。
应用例子
实现一
利用 bitwise_and
import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)
bit_planes = []
for i in range(8):
bit_plane = cv2.bitwise_and(image, 1 << i)
bit_plane *= 255
bit_planes.append(bit_plane)
# for i, plane in enumerate(bit_planes):
# cv2.imshow(f'Bit plane {i}', plane)
# # cv2.imwrite(f"bitplane{i}.jpg", plane)
# cv2.waitKeyEx(0)
# cv2.destroyAllWindows()
fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(10, 8),
subplot_kw={'xticks':[], 'yticks':[]})
fig.subplots_adjust(hspace=0.05, wspace=0.05)
for ax, img in zip(axes.flat, bit_planes):
ax.imshow(img, cmap="gray")
plt.tight_layout()
plt.show()
原图
各级位平面图
下面仔细看看
bitplane1
bitplane2
bitplane3
bitplane4
bitplane5
bitplane6
bitplane7
bitplane8
实现二
暴力,获取每位二进制数值
import cv2
import numpy as np
import matplotlib.pyplot as plt
gray = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)
c1 = np.mod(gray, 2)
c2 = np.mod(np.floor(gray/2), 2)
c3 = np.mod(np.floor(gray/4), 2)
c4 = np.mod(np.floor(gray/6), 2)
c5 = np.mod(np.floor(gray/8), 2)
c6 = np.mod(np.floor(gray/16), 2)
c7 = np.mod(np.floor(gray/64), 2)
c8 = np.mod(np.floor(gray/128), 2)
# reconstructing image with 3 most significant bit planes
cc = 2 * (2 * (2 * c8 + c7) + c6)
bit_planes = [gray, c1, c2, c3, c4, c5, c6, c7, c8, cc]
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(10, 8),
subplot_kw={'xticks':[], 'yticks':[]})
fig.subplots_adjust(hspace=0.05, wspace=0.05)
for ax, img in zip(axes.flat, bit_planes):
ax.imshow(img, cmap="gray")
plt.tight_layout()
plt.show()
输入
输出
第一张图是原图的灰度图
第二张到第九张即为 8 层位平面可视化结果
最后一张图是合并了 6、7、8 三层位平面尝试还原原图,效果还是可以接受的