python实现图像卷积+池化

         CNN里面有很关键的步骤就是卷积和池化,所以这里代码实现了一下。这里滑动窗口大小我设置的是3,池化那里我设置的是2,大家可以改成自己想要的大小,之前那个代码只能是特定的步长,现在修改的可以是任意。要注意卷积之后的大小公式要准确表达。然后在做卷积的时候,加入了padding的部分。这里的图片用的是灰色,原因是色彩太多太亮可能不那么容易察觉,这里修改了一下池化的部分,加入了平均池化和最大池化的对比,池化尺寸的大小和步长可以按照自己的想法更改,这里我用的是三阶尺寸和3的滑动步长。这里最后的结果是个二维图像。如果有需要三维图像的uu可以联系我一下,私发三维图像的结果

代码实现

import matplotlib.pyplot as plt
import cv2
import numpy as np

# 导入图像
img = cv2.imread(r"C:/Users/wxc/Desktop/xuexi/matlab/PCA/Lena.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


a = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 16 # 卷积核我用的高斯模糊,理论上最后池化过后会比没有经过池化层要模糊一些
c1 = 2  # 这个卷积核滑动步长可以调整自己想要的

# 卷积操作函数
def desprate(matrix, kernel, b):
    m, n = matrix.shape
    km, kn = kernel.shape
    pm = int((km-1)/2)# 进行padding
    pdding_m1 = np.zeros((m, pm))
    pdding_m2 = np.zeros((m, pm))
    pdding_n1 = np.zeros((pm,n+2))
    pdding_n2 = np.zeros((pm,n+2))
    matrix1 = np.concatenate((pdding_m1, matrix, pdding_m2), axis=1)
    matrix2 = np.vstack((pdding_n1, matrix1, pdding_n2))#  将所有的0矩阵和原矩阵拼接在一起
    result = np.zeros(((m-km+2*pm)//b+1, (n-kn+2*pm)//b+1), dtype=int)  # 建立结果矩阵,这个就是根据卷积后大小的计算公式得到的

    for i in range(result.shape[0]):
        for j in range(result.shape[1]):
            window = matrix2[i*b:i*b+km, j*b:j*b+kn]  # 提取窗口
            result[i, j] = np.sum(window * kernel)  # 卷积操作
    return result

# 进行卷积操作
s1 = desprate(gray_img, a, c1)
c2=3

# 最大池化函数
def max_pooling(x,y,b): # x表示输入的矩阵,y表示的是池化的尺寸大小,b表示池化核滑动的大小
    max_pool_result = np.zeros(((x.shape[0]-y)//b+1, (x.shape[1]-y)//b+1))  # 初始化池化后的结果矩阵
    
   
    for i in range(0, max_pool_result.shape[0]):
        for j in range(0, max_pool_result.shape[1]):
            window = x[i*b:i*b+y, j*b:j*b+y] # 把滑动窗口给表示出来
            max_pool_result[i,j] = np.max(window)# 池化操作
              

    return max_pool_result

# 进行最大池化操作
p1 = max_pooling(s1,c2,3)
# 平均池化
def aver_pooling(x,y,b): # x表示输入的矩阵,y表示的是池化的尺寸大小,b表示池化核滑动的大小
    aver_pool_result = np.zeros(((x.shape[0]-y)//b+1, (x.shape[1]-y)//b+1))  # 初始化池化后的结果矩阵
    
   
    for i in range(0, aver_pool_result.shape[0]):
        for j in range(0, aver_pool_result.shape[1]):
            window = x[i*b:i*b+y, j*b:j*b+y] # 把滑动窗口给表示出来
            aver_pool_result[i,j] = np.mean(window)# 平均池化操作
              

    return aver_pool_result
p2 = aver_pooling(s1,c2,3)

# 显示图像
fig, axes = plt.subplots(2, 2, figsize=(25, 10))

# 显示原始图像
axes[0, 0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
axes[0, 0].set_title('Original Image')

# 显示卷积后的图像
axes[0, 1].imshow(s1, cmap='gray')
axes[0, 1].set_title('Convolved Image')

# 显示卷积和池化后的图像
axes[1, 0].imshow(p1, cmap='gray')
axes[1, 0].set_title('Convolved + max_Pooling Image')

axes[1, 1].imshow(p2, cmap='gray')
axes[1, 1].set_title('Convolved + aver_Pooling Image')

plt.show()

展示结果

        这个是得到的结果,

        第二张图片体现的就是卷积的作用,他把典型的特征放大,比如头发比以前变得黑了。这里第三张和第四张图片,他们看上去有些不同,这里是因为最大池化的作用是保留显著特征,忽略掉一些次要特征。平均池化是一些细微特征的丢失,但对于保持整体结构和较大特征的识别能力有一定帮助。所以你回看到比起第三张最大池化,第四张平均池化会更整体清晰一些。大家可以把图片第三张和第四张放大看看,同样是眼睛那里还是有区别的。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值