1.包的导入
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
2.图像的读取
img = Image.open(r'C:\Users\86139\Pictures\Camera Roll\1.jpg')
plt.axis("off")
plt.imshow(img)
# plt.show()
plt.axis表示坐标轴的开关
plt.imshow(img)用于在matplotlib的绘图区域中显示读取的图像img
如果需要显示再使用plt.show()
3.图像灰度化
gray = img.convert('L')
plt.figure()
plt.imshow(gray, cmap='gray')
plt.axis('off')
# plt.show()
4.分为三通道进行计算
r, g, b = img.split()
plt.imshow(r, cmap='gray')
plt.axis('off')
# plt.show()
5.将原始图片以及各通道图片转化为np矩阵
img_matrix = np.array(img)
r_matrix = np.array(r)
g_matrix = np.array(g)
b_matrix = np.array(b)
目的是为了方便后续进行卷积操作
6.卷积核的定义
# 定义第一个卷积核,用于提取图像中的某些特征,例如边缘等,具体效果取决于核内元素值
k = np.array([
[0, 1, 2],
[2, 2, 0],
[0, 1, 2]
])
# 定义第二个卷积核,常用于检测图像在水平方向上的边缘等特征
k1 = np.array([
[1, 0, -1],
[1, 0, -1],
[1, 0, -1]
])
# 定义第三个卷积核,常用于检测图像在垂直方向上的边缘等特征
k2 = np.array([
[1, 1, 1],
[0, 0, 0],
[-1, -1, -1]
])
k1 卷积核(水平边缘检测):
这个卷积核的设计是为了检测图像中的水平边缘。
它的结构特点是中心行元素值为 0,上下两行元素值分别为 1 和 - 1。当卷积核在图像上滑动时,对于水平方向上亮度不变的区域,由于上下元素值相加为 0(例如,一个水平的白色条带区域),卷积后的像素值接近 0;而对于水平方向上有亮度变化的区域(即可能存在水平边缘),如从白色区域过渡到黑色区域,上下行元素值与图像像素相乘求和后会得到一个较大的绝对值,从而突出显示水平边缘。
k2 卷积核(垂直边缘检测):
这个卷积核是专门用于检测垂直边缘的。
它的结构是中心列元素值为 0,左右两列元素值分别为 1 和 - 1。在卷积过程中,对于垂直方向上亮度不变的区域,左右元素值相加为 0,卷积后的像素值接近 0;而对于垂直方向上有亮度变化的区域(即可能存在垂直边缘),如从白色区域过渡到黑色区域,左右列元素值与图像像素相乘求和后会得到一个较大的绝对值,从而突出显示垂直边缘。
7.选择通道(以red为例)
# 选择红色通道数据进行卷积操作(以r_matrix为例,你也可尝试其他通道数据)
data = np.array(r_matrix)
8.进行卷积操作
def convolution(kernel, data):
"""
使用给定卷积核对图像数据进行卷积操作
:param kernel: 卷积核,二维numpy数组
:param data: 图像数据,二维numpy数组
:return: 卷积后的图像数据,二维numpy数组
"""
n, m = data.shape
img_new = []
for i in range(n - 2): # 修改循环范围,避免卷积后图像尺寸过小(之前是n - 3存在问题)
line = []
for j in range(m - 2):
a = data[i:i + 3, j:j + 3]
line.append(np.sum(np.multiply(kernel, a)))
img_new.append(line)
return np.array(img_new)
kernel:表示卷积核
data:代表图像数据的二维numpy数组
n,m = data.shape 表示 传入图像数据的形状,方便后续的卷积核进行循环操作
a = data[i:i + 3, j:j + 3]:numpy数组的切片操作,i:i + 3表示从第i行开始取连续的 3 行,j:j + 3表示从第j列开始取连续的 3 列,
9.卷积可视化
# 分别使用三个卷积核对图像数据进行卷积,并存储结果
img_new_k = convolution(k, data)
img_new_k1 = convolution(k1, data)
img_new_k2 = convolution(k2, data)
# 卷积结果可视化,展示使用三个卷积核卷积后的图像
# 创建三个子图用于展示不同卷积核的结果
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
# 展示使用第一个卷积核的卷积结果
axs[0].imshow(img_new_k, cmap='gray')
axs[0].axis('off')
axs[0].set_title('Convolution with Kernel k')
# 展示使用第二个卷积核的卷积结果
axs[1].imshow(img_new_k1, cmap='gray')
axs[1].axis('off')
axs[1].set_title('Convolution with Kernel k1')
# 展示使用第三个卷积核的卷积结果
axs[2].imshow(img_new_k2, cmap='gray')
axs[2].axis('off')
axs[2].set_title('Convolution with Kernel k2')
plt.show()
10.结果展示
原图像
灰度化后的图像
卷积核过后的图像