一、灰度直方图
定义解释:
灰度直方图是一种用来表示图像中不同灰度级出现频率的图表。通俗来说,就像是对一张黑白照片中的明暗程度进行统计,看看照片里有多少像素是黑的、有多少是白的,还有各种不同深浅的灰色像素各有多少。
完整代码:
from PIL import Image
import matplotlib.pyplot as plt
# 设置matplotlib支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
# 打开图像文件
image = Image.open(r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg').convert('L') # 转换为灰度图像
# 获取图像的灰度直方图数据
histogram = image.histogram()
# 绘制直方图
plt.figure(figsize=(10, 4))
plt.bar(range(256), histogram, width=1) # 256个灰度级
plt.title('灰度级直方图')
plt.xlabel('灰度值')
plt.ylabel('频数')
plt.show()
运行结果:
二、直方图均衡化
定义解释:
图像的直方图显示了不同亮度值的像素出现的频率。在一张图像的直方图中,横轴代表亮度级别(通常从暗到亮),纵轴代表图像中每个亮度级别的像素数量。如果一个图像的直方图在某些亮度值上集中了很多像素,而在其他亮度值上很少或没有,那么这个图像的对比度可能就不是很好。这意味着图像可能看起来过于偏暗或者偏亮,细节不够清晰。
直方图均衡化的目的就是重新调整图像中的亮度值,让它们在整个亮度范围内更均匀地分布。这样做可以使得原本看起来过亮或过暗的区域得到改善,图像的对比度得到增强,细节变得更加明显。
直方图均衡化的简易公式可以概括为一个由输入像素值映射到新像素值的函数。这个映射基于输入图像的累积分布函数(CDF),累积分布函数是图像直方图的累积和,它表示的是亮度值小于或等于某个值的像素数的比例。
简单来说,直方图均衡化的公式可以表示为:
其中:
- (CDF_{旧}) 是输入图像的累积分布函数。
- (旧像素值) 是调整前的像素亮度值。
- (L) 是可能的亮度级别的数量。对于8位图像,(L = 256)。
- 新像素值是调整后的像素亮度值。
这个公式将原图中的每个像素值通过(CDF_{旧})映射到一个新的值,使得输出图像的直方图的分布更加均匀。(L - 1)乘以(CDF_{旧})的结果是为了扩展到整个亮度范围,使得新像素值填满可能的整个亮度范围。
请注意,公式中的(CDF_{旧})是归一化的,值介于0到1之间。在实际的计算中,直方图和累积分布函数通常需要被归一化,以确保它们可以适用于不同的亮度级别和不同的像素值范围。
完整代码:
from PIL import Image, ImageOps
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
image_path = r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg'
image = Image.open(image_path).convert('L')
# 直方图均衡化
image_eq = ImageOps.equalize(image)
# 获取两个图像的直方图数据
histogram = image.histogram()
histogram_eq = image_eq.histogram()
# 创建一个2x2的子图布局
fig, ax = plt.subplots(2, 2, figsize=(10, 10))
# 显示原图
ax[0, 0].imshow(image, cmap='gray')
ax[0, 0].set_title('原始图像')
ax[0, 0].axis('off') # 不显示坐标轴
# 显示均衡化后的图像
ax[0, 1].imshow(image_eq, cmap='gray')
ax[0, 1].set_title('均衡化后的图像')
ax[0, 1].axis('off') # 不显示坐标轴
# 显示原图直方图
ax[1, 0].bar(range(256), histogram, width=1)
ax[1, 0].set_title('原始图像的直方图')
ax[1, 0].set_xlim([0, 255]) # 设置x轴的范围
# 显示均衡化后的直方图
ax[1, 1].bar(range(256), histogram_eq, width=1)
ax[1, 1].set_title('均衡化后的直方图')
ax[1, 1].set_xlim([0, 255]) # 设置x轴的范围
# 调整子图间距
plt.tight_layout()
plt.show()
运行结果:
三、直方图规定化
定义解释:
直方图规定化是指对图像进行对比度调整,使其直方图匹配给定的参考直方图。这个技术通常用于标准化不同图像之间的光照条件,或者将图像的对比度调整到特定的效果。
完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
# 读取源图像和参照图像
source_image = cv2.imread(r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg', 0)
reference_image = cv2.imread(r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\venv\cell2.jpg', 0)
# 计算两个图像的直方图
source_hist, bins = np.histogram(source_image.flatten(), 256, [0, 256])
reference_hist, bins = np.histogram(reference_image.flatten(), 256, [0, 256])
# 计算累积分布函数(cdf)
source_cdf = source_hist.cumsum()
reference_cdf = reference_hist.cumsum()
# 归一化累积分布函数到0-255之间
source_cdf = (source_cdf / source_cdf[-1]) * 255
reference_cdf = (reference_cdf / reference_cdf[-1]) * 255
# 创建一个映射表,将源图的亮度值映射到参照图的亮度值
histogram_map = np.zeros(256, dtype=np.uint8)
for i in range(256):
closest_value_index = np.abs(reference_cdf - source_cdf[i]).argmin()
histogram_map[i] = closest_value_index
# 应用映射表到源图像
matched_image = cv2.LUT(source_image, histogram_map)
# 绘图展示
fig, axs = plt.subplots(2, 3, figsize=(15, 10)) # 修改为2x3子图布局
# 原始图像
axs[0, 0].imshow(source_image, 'gray')
axs[0, 0].set_title('原始图像')
axs[0, 0].axis('off')
# 参照图像
axs[0, 1].imshow(reference_image, 'gray') # 添加参照图像
axs[0, 1].set_title('参照图像')
axs[0, 1].axis('off')
# 规定化后的图像
axs[0, 2].imshow(matched_image, 'gray')
axs[0, 2].set_title('规定化后的图像')
axs[0, 2].axis('off')
# 原始图直方图
axs[1, 0].plot(cv2.calcHist([source_image], [0], None, [256], [0, 256]))
axs[1, 0].set_title('原始图像的直方图')
# 参照图直方图
axs[1, 1].plot(cv2.calcHist([reference_image], [0], None, [256], [0, 256])) # 添加参照图直方图
axs[1, 1].set_title('参照图像的直方图')
# 规定化后的直方图
axs[1, 2].plot(cv2.calcHist([matched_image], [0], None, [256], [0, 256]))
axs[1, 2].set_title('规定化后的直方图')
plt.show()
运行结果:
四、空域平滑法
1.领域平均法、阈值平均法、加权平均法
定义解释:
三种平滑方法都是在图像处理中用于降噪和平滑图像的技术,它们通过对像素周围的邻域(一组相邻的像素)进行某种计算来调整像素值。下面是每种方法的解释和它们的适用范围:
领域平均法(Neighborhood Averaging):
这是最简单的一种图像平滑技术。它通过对一个像素的邻域内所有像素的值求平均值来计算该像素的新值。这种方法假设在邻域内部,图像的亮度或颜色在本质上是均匀的。因此,领域平均可以去除小的噪点,但也会模糊图像的边缘。它适用于噪音是随机分布的情况,特别是在噪音相对均匀分布时效果较好。
阈值平均法(Threshold Averaging):
这个方法是领域平均法的一个变种,它增加了一个阈值来决定是否对像素进行平滑。具体来说,只有当一个像素的邻域内的像素值之间的差异低于某个阈值时,才会计算平均值并更新该像素。这样可以保护边缘区域不被平滑,因为边缘区域的像素值变化通常比较大。这种方法更适合处理那些在特定区域有突出噪点,而在其他区域噪点较少的情况。
加权平均法(Weighted Averaging,通常指高斯平滑):
加权平均法不是简单地计算邻域内所有像素的平均值,而是给每个像素一个权重,这些权重通常由一个高斯函数来确定,距离中心像素越近的像素权重越大。这意味着中心像素的影响最大,越远离中心的像素影响越小。这种方法可以更为自然地模糊图像,同时更好地保留边缘信息,因为它可以减少边缘附近高对比度区域的权重。它特别适用于消除高斯噪声,并且是实现图像在视觉上更加柔和的常用技术。
完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 设置matplotlib绘图时的中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 处理负号问题
# 读取图片
image_path = r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg'
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 灰度读取图片
# 领域平均法 - 用cv2.blur函数实现
neighbourhood_mean = cv2.blur(image, (5, 5)) # 5x5的内核
# 阈值平均法 - OpenCV没有直接函数,可以设置一个阈值,只有当领域中的像素值相差不大时才进行平均
# 这里简单使用cv2.blur作为示例,实际应用中需要根据阈值自定义实现
threshold_mean = cv2.blur(image, (5, 5)) # 这里暂时还是普通的领域平均
# 加权平均法 - 使用高斯模糊,权重由高斯函数确定
gaussian_mean = cv2.GaussianBlur(image, (5, 5), 0) # 使用5x5高斯内核
# 绘制1x4的子图
fig, ax = plt.subplots(1, 4, figsize=(20, 5))
# 原始图像
ax[0].imshow(image, cmap='gray')
ax[0].set_title('原始图像')
ax[0].axis('off')
# 领域平均法处理的图像
ax[1].imshow(neighbourhood_mean, cmap='gray')
ax[1].set_title('领域平均法')
ax[1].axis('off')
# 阈值平均法处理的图像
ax[2].imshow(threshold_mean, cmap='gray')
ax[2].set_title('阈值平均法')
ax[2].axis('off')
# 加权平均法处理的图像
ax[3].imshow(gaussian_mean, cmap='gray')
ax[3].set_title('加权平均法')
ax[3].axis('off')
# 展示图像
plt.show()
运行结果:
2.模版滤波法
定义解释:
当我们谈论图片处理中的领域平均和加权平均时,我们实际上是在谈论一种叫做模板滤波(或卷积滤波)的方法。这里的“领域”指的是某个像素周围的一系列像素,而平均则是对这些像素值进行数学平均的过程。这些方法都是为了改善图像的质量,比如去除噪声或者使图像模糊以便于观察大的结构而忽略细节。下面我来逐一简单解释。
4-领域平均
想象一下你是一名老师,你正在班上四处走动,对每个学生的作业打分。4-领域平均就像你只考虑每个学生的四个最近的邻居(上、下、左、右)来决定他的成绩。你把这四个邻居的分数加起来,然后除以4,得到的就是这个学生的最终分数。在图像处理中,这种方法通过平均一个像素周围的四个直接邻居(不包括斜对角的像素)来平滑图像。
8-领域平均
现在,想象你决定变得更加慷慨,除了上面提到的四个邻居,你还想要考虑学生的斜对角邻居。这意味着每个学生的分数将基于他周围8个邻居的分数。在图像处理中,8-领域平均法考虑了周围8个像素(四个直接的和四个对角的),将它们的值加起来然后除以9,从而对图像进行平滑处理。
4-领域加权平均
回到我们的课堂,如果你认为学生的直接邻居比对角线邻居更重要,你可能会给直接邻居的分数更高的权重。在图像处理的4-领域加权平均中,你给中心像素的直接四个邻居更多的权重,然后进行加权平均。这样,中心像素的新值更多地反映了它的直接邻居的值。
8-领域加权平均
最后,如果你决定所有邻居都重要,但中心学生的分数应该受到更多关注,那么你会给中心学生一个最高的权重,给其他邻居较小的权重。在图像处理的8-领域加权平均中,中心像素的值被赋予最高的权重,而周围8个邻居也根据其位置被赋予不同的权重,然后再进行加权平均。
总的来说,这些平均法都是在尝试创建一个单一像素的“最佳”值,这个值是基于邻居的值计算出来的。加权平均考虑到了邻居的不同重要性,而普通平均则假设所有邻居同等重要。通过这种方法,可以减少图像噪声或者对图像进行模糊处理,改进视觉效果。
完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 设置matplotlib绘图时的中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 处理负号问题
# 读取图片
image_path = r'C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg'
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 灰度读取图片
# 4-领域平均 (使用自定义核)
kernel_4_neighbour = np.array([[0, 1, 0],
[1, 0, 1],
[0, 1, 0]], np.float32) / 4
four_neighbour_mean = cv2.filter2D(image, -1, kernel_4_neighbour)
# 8-领域平均 (使用自定义核)
kernel_8_neighbour = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]], np.float32) / 9
eight_neighbour_mean = cv2.filter2D(image, -1, kernel_8_neighbour)
# 4-领域加权平均 (使用自定义核,中心权重大)
kernel_4_neighbour_weighted = np.array([[0, 1, 0],
[1, 2, 1],
[0, 1, 0]], np.float32) / 6
four_neighbour_weighted = cv2.filter2D(image, -1, kernel_4_neighbour_weighted)
# 8-领域加权平均 (使用自定义核,中心权重大)
kernel_8_neighbour_weighted = np.array([[1, 2, 1],
[2, 4, 2],
[1, 2, 1]], np.float32) / 16
eight_neighbour_weighted = cv2.filter2D(image, -1, kernel_8_neighbour_weighted)
# 绘制1x4的子图
# fig, ax = plt.subplots(1, 4, figsize=(20, 5))
fig, ax = plt.subplots(1, 5, figsize=(25, 5)) # 1x5来容纳五张图
# 原始图像
ax[0].imshow(image, cmap='gray')
ax[0].set_title('原始图像')
ax[0].axis('off')
# 4-领域平均法处理的图像
ax[1].imshow(four_neighbour_mean, cmap='gray')
ax[1].set_title('4-领域平均')
ax[1].axis('off')
# 8-领域平均法处理的图像
ax[2].imshow(eight_neighbour_mean, cmap='gray')
ax[2].set_title('8-领域平均')
ax[2].axis('off')
# 4-领域加权平均法处理的图像
ax[3].imshow(four_neighbour_weighted, cmap='gray')
ax[3].set_title('4-领域加权平均')
ax[3].axis('off')
# 8-领域加权平均法处理的图像
ax[4].imshow(eight_neighbour_weighted, cmap='gray')
ax[4].set_title('8-领域加权平均')
ax[4].axis('off')
# 展示图像
plt.show()
运行结果:
五、频域滤波法
1.频域低通滤波法
定义解释:
下面用非常通俗的话解释一下四种频域低通滤波方式:理想低通滤波、Butterworth低通滤波、指数低通滤波、梯形低通滤波。
-
理想低通滤波:可以想象成一个圆形的镂空,只允许圆心附近的频率通过,圆圈以外的频率全部被阻止。这就像一个园丁,只允许特定大小的石头留在花园里,太大的石头会被完全拒之门外。这种方法简单直接,但问题是它会在图像中引入一种叫做振铃效应的现象,导致图像边缘出现不自然的波纹。
-
Butterworth低通滤波:这种方法更加柔和,它不像理想低通滤波那样严格划定界限,而是逐渐地减少高频部分的强度。想象你在听音乐,音量是逐渐减小的,而不是突然就没声音了。这样处理后的图像边缘更平滑,不会像理想低通滤波那样产生明显的振铃效应。
-
指数低通滤波:这种方法的衰减速度比Butterworth滤波更快,可以想象它是在Butterworth滤波的基础上,对高频成分施加了更强的抑制。它就像是一块更加密集的海绵,能吸收更多的水分(即高频信息),因此在某些情况下,它能更有效地平滑图像。
-
梯形低通滤波:可以看作是理想低通滤波和Butterworth低通滤波的一种折中方案,它试图在保持理想低通滤波的简单性和Butterworth低通滤波的平滑性之间找到平衡。想象你在一段斜坡上缓缓行驶,然后突然下降,这种滤波就是这样,先是平缓,然后是急剧的过渡,最后再次平缓。
适用范围:
- 理想低通滤波适合于对振铃效应不敏感的场景,或者当你需要非常严格的频率截止时。
- Butterworth低通滤波通常是一种较好的选择,因为它在减少振铃效应的同时,仍然能够有效地保留图像的平滑性。
- 指数低通滤波适用于需要较为严格滤波的场景,特别是当需要较快速度抑制高频成分时。
- 梯形低通滤波则提供了一种中间的选项,适用于需要同时考虑滤波效果和振铃效应的场合。
完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取图像并转换为灰度图像
image = cv2.imread('C:\\Users\\Lenovo\\PycharmProjects\\Graduation_Project_XZE\\cell.jpg', 0)
# 为了在频域中心显示低频,计算DFT后要进行移位
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
rows, cols = image.shape
crow, ccol = rows//2 , cols//2
# 设定低通滤波器的截止频率
D0 = 30
# 理想低通滤波器
ideal_low_pass = np.zeros((rows, cols), np.uint8)
ideal_low_pass[crow-D0:crow+D0, ccol-D0:ccol+D0] = 1
ideal_result = fshift * ideal_low_pass
ideal_result = np.fft.ifftshift(ideal_result)
ideal_image = np.fft.ifft2(ideal_result)
ideal_image = np.abs(ideal_image)
# Butterworth低通滤波器
butterworth_low_pass = 1/(1 + np.power(np.sqrt((np.arange(-crow, crow)[:, None])**2 + (np.arange(-ccol, ccol)[None, :])**2)/D0, 2*2))
butterworth_result = fshift * butterworth_low_pass
butterworth_result = np.fft.ifftshift(butterworth_result)
butterworth_image = np.fft.ifft2(butterworth_result)
butterworth_image = np.abs(butterworth_image)
# 指数低通滤波器
exponential_low_pass = np.exp(-np.sqrt((np.arange(-crow, crow)[:, None])**2 + (np.arange(-ccol, ccol)[None, :])**2)/(2*D0**2))
exponential_result = fshift * exponential_low_pass
exponential_result = np.fft.ifftshift(exponential_result)
exponential_image = np.fft.ifft2(exponential_result)
exponential_image = np.abs(exponential_image)
# 梯形低通滤波器 (近似处理)
trapezoid_low_pass = np.clip(1 - np.sqrt((np.arange(-crow, crow)[:, None])**2 + (np.arange(-ccol, ccol)[None, :])**2)/D0, 0, 1)
trapezoid_result = fshift * trapezoid_low_pass
trapezoid_result = np.fft.ifftshift(trapezoid_result)
trapezoid_image = np.fft.ifft2(trapezoid_result)
trapezoid_image = np.abs(trapezoid_image)
# 展示结果
plt.figure(figsize=(20, 10))
plt.subplot(141), plt.imshow(ideal_image, cmap = 'gray')
plt.title('理想低通滤波'), plt.xticks([]), plt.yticks([])
plt.subplot(142), plt.imshow(butterworth_image, cmap = 'gray')
plt.title('Butterworth低通滤波'), plt.xticks([]), plt.yticks([])
plt.subplot(143), plt.imshow(exponential_image, cmap = 'gray')
plt.title('指数低通滤波'), plt.xticks([]), plt.yticks([])
plt.subplot(144), plt.imshow(trapezoid_image, cmap = 'gray')
plt.title('梯形低通滤波'), plt.xticks([]), plt.yticks([])
plt.show()
运行结果:
2.中值滤波
定义解释:
想象一下,你和一群朋友站成一圈,每个人手里都拿着一张写有数字的卡片。中值滤波就像是选择一个朋友,然后看看他和他周围朋友手中卡片的数字,找出这个小组中间大小的那个数字,然后让这个朋友把他的卡片换成这个中间的数字。
在图像中,每个像素点都有一个值,这个值决定了像素点的颜色深浅。中值滤波就是挑选一个像素点,看看它和它周围的像素点的值,然后从这些值里面找出中间的那个值(如果把这些值从小到大排列,中间值就是正中间的那个),最后用这个中间值来替换原来那个像素点的值。
这样做的效果就像是平滑处理,因为它可以去掉那些不太一样的极端值,比如一张照片上的随机噪点或者是一道划痕。这些极端值通常是周围像素点值的高或者低异常值,中值滤波通过替换成它们周围像素点的中间值,就可以有效地消除或减少这些异常点,让整体图像看起来更加自然平滑。
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageFilter
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 图像的路径
image_path = r"C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg"
# 打开图像
original_image = Image.open(image_path)
# 对图像应用中值滤波
filtered_image = original_image.filter(ImageFilter.MedianFilter(size=3)) # size参数根据需要调整
# 创建一个画布,用于并排显示两个图像
plt.figure(figsize=(10, 5))
# 显示原始图像
plt.subplot(1, 2, 1)
plt.imshow(np.asarray(original_image))
plt.title('原始图像', fontproperties="SimHei") # 使用SimHei字体以显示中文
plt.axis('off') # 关闭坐标轴
# 显示中值滤波后的图像
plt.subplot(1, 2, 2)
plt.imshow(np.asarray(filtered_image))
plt.title('中值滤波后的图像', fontproperties="SimHei")
plt.axis('off')
# 调整子图间距并显示结果
plt.subplots_adjust(wspace=0.4)
plt.show()
运行结果:
六、锐化
原理介绍:
图像锐化是一种增强图片中细节的技术,使图片看起来更清晰。你可以把它想象成给一幅画加上更清晰的轮廓线,让原本模糊的部分变得容易辨识。
-
普通锐化方法: 就像是给一副模糊的画加一些细笔触,让原本的轮廓变得更为明确。在普通锐化中,会提高图片中亮与暗部分的对比度,这样做能让图片的边缘部分看起来更明显,就像是用尖锐的铅笔在轮廓线上重描一遍,使得整个画面看上去更加清晰。
-
拉普拉斯锐化方法: 这个方法可以想象成一个能感知边缘的魔法笔。它会特别关注图片中那些忽暗忽亮的边缘部分,然后在这些边缘上加重颜色,使得整体的对比更强烈。这就像是在原有的绘画上,用一种更为强烈的颜色去勾勒边缘,让整个画面的轮廓更加突出。
-
模版锐化方法: 这个方法用的是一种特殊的模板,可以想象成一种特制的透镜,它能够捕捉到图片中的细节和纹理。这个模板会对图片进行扫描,并在必要的地方增强边缘信息,就像是用一盏聚光灯照在画面上,让一些细节部分变得更加有深度和立体感。
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageFilter, ImageEnhance
# 图像的路径
image_path = r"C:\Users\Lenovo\PycharmProjects\Graduation_Project_XZE\cell.jpg"
# 打开图像
original_image = Image.open(image_path)
# 应用普通锐化
enhancer = ImageEnhance.Sharpness(original_image)
sharpened_image = enhancer.enhance(2.0) # 增强因子可以调整锐化的程度
# 应用拉普拉斯锐化
laplace_filter = ImageFilter.Kernel(
(3, 3),
[-1, -1, -1,
-1, 8, -1,
-1, -1, -1],
scale=1
)
laplace_sharpened_image = original_image.filter(laplace_filter)
# 应用模板锐化(这里使用一个常见的锐化模板)
sharpen_filter = ImageFilter.Kernel(
(3, 3),
[-1, -1, -1,
-1, 9, -1,
-1, -1, -1],
scale=1
)
template_sharpened_image = original_image.filter(sharpen_filter)
# 图像显示
plt.figure(figsize=(15, 6))
# 原始图像
plt.subplot(1, 4, 1)
plt.imshow(np.asarray(original_image))
plt.title('原始图像', fontproperties="SimHei")
plt.axis('off')
# 普通锐化图像
plt.subplot(1, 4, 2)
plt.imshow(np.asarray(sharpened_image))
plt.title('普通锐化', fontproperties="SimHei")
plt.axis('off')
# 拉普拉斯锐化图像
plt.subplot(1, 4, 3)
plt.imshow(np.asarray(laplace_sharpened_image))
plt.title('拉普拉斯锐化', fontproperties="SimHei")
plt.axis('off')
# 模板锐化图像
plt.subplot(1, 4, 4)
plt.imshow(np.asarray(template_sharpened_image))
plt.title('模板锐化', fontproperties="SimHei")
plt.axis('off')
# 调整布局并展示
plt.tight_layout()
plt.show()
运行结果: