手写代码实现卷积操作

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.结果展示

原图像原图像
灰度化后的图像
灰度化后的图像
卷积核过后的图像
卷积核过后的图像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值