作业2
题目
对Flower.dat图像(1024×1024,np.uint8)用如下拉普拉斯算子进行空间滤波和增强:np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])
,图像边缘采用复制填充方式,不使用其他第三方库,使用numpy库完成数组操作。
思路
拉普拉斯算子进行空间滤波的主要作用是检测图像中的边缘和细节。它是一种二阶导数算子,通过计算图像中像素值的二阶导数来突出图像中的边缘和细节。滤波后的图像主要包含图像中的边缘和细节信息。通过将拉普拉斯滤波后的图像与原图像相加,可以增强图像的边缘和细节,从而使图像看起来更加锐利。
- 读取图像数据:使用
np.fromfile
读取mermaid flowchater.dat
文件中的图像数据,并将其重塑为 1024×1024 的二维数组。 - 定义拉普拉斯算子:使用给定的 3×3 拉普拉斯算子。
- 图像边缘填充:使用
np.pad
函数对图像进行边缘填充,填充值为边缘像素的复制。确保填充后的图像padded_image
的形状正确,仍然是二维数组,从而避免IndexError
。 - 应用拉普拉斯算子:通过遍历图像中的每个像素点,提取其周围的 3×3 区域,应用拉普拉斯算子进行卷积操作,计算每个像素点的拉普拉斯滤波值,并将结果存储在 filtered_image 中。
两层循环遍历图像中的每个像素点。i 和 j 分别表示图像的行和列索引。由于图像进行了边缘填充,循环从 1 开始,到for i in range(1, padded_image.shape[0] - 1): for j in range(1, padded_image.shape[1] - 1): region = padded_image[i-1:i+2, j-1:j+2] filtered_image[i-1, j-1] = np.sum(region * laplacian_kernel) # filtered_image 没有填充边缘,所以索引需要减去 1。
padded_image.shape[0] - 1
和padded_image.shape[1] - 1
结束,以避免访问填充的边缘。 - 增强图像:将滤波后的图像与原图像相加,得到增强后的图像,并使用
np.clip
将像素值裁剪到有效范围(0-255)。 - 显示和保存结果:使用
matplotlib
显示原图,滤波结果和增强后的图像,并将增强后的图像保存为Enhanced_Flower.dat
文件。
结果
效果并不理想,因为原图是一幅uint8类图像,输出结果仍为uint8类,所有像素均为正值,而拉普拉斯滤波模板中存在负值,变换结果中的所有负值被截掉了。
改进
由于拉普拉斯滤波会产生负值,需要在增强图像之前处理这些负值。可以将滤波结果转换为 int16 类型,以便保留负值信息,具体改动如下:
- 初始化输出图像,使用 int16 类型:在初始化 filtered_image 时,使用 int16 类型以保留负值。
- 增强图像,使用 int16 类型:在增强图像时,将原图像转换为 int16 类型,以便与 filtered_image 相加时保留负值。
- 将增强后的图像裁剪到有效范围:使用 np.clip 将像素值裁剪到有效范围(0-255)。
得到改进后的结果,Filtered Image可以较为有效地提取Flower图像的边缘,增强图像中的细节: