人工智能-作业4:CNN - 卷积

一、相关概念

1.卷积

对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。
在这里插入图片描述

2.卷积核

卷积核就是滤波矩阵,是做内积运算的对象,决定了滑动窗口的大小和范围。

在这里插入图片描述

3.多通道

输入图像的通道数根据图片特性和自己需求自己确定,输入图像的通道决定了卷积核的通道,卷积核的个数又决定了特征图的通道数。在这里插入图片描述

4.特征图

图像与卷积核加权累加得到卷积(滤波)后的特征图。
在这里插入图片描述

5.特征选择

人的视觉神经细胞对不同的视觉模式具有特征选择性, 不同视觉神经细胞对边界、运动和颜色等不同信息具有强弱不同的选择性。 不同卷积核 可被用来刻画 不同选择性。

在这里插入图片描述

二、探究多种卷积核的作用和原理

多种卷积核的作用

这里的测试都是来自测试网站

1、边缘检测

边缘检测的目的就是找到图像中亮度变化剧烈的像素点构成的集合,表现出来往往是轮廓。
在这里插入图片描述

在这里插入图片描述

2、锐化

锐化可以加强图像中的边界和细节信息。
在这里插入图片描述

在这里插入图片描述

3、 模糊

达到视觉上模糊的效果。
在这里插入图片描述
在这里插入图片描述

原理的分析

网上查阅了一下,讲解都看不太懂(可能个人能力有限)。这里表达一下个人的看法。首先我们需要了解的是灰度图中0是黑色,255是白色。我们通过核函数也就是滤波器来完成原图到特征图的转化,经过滤波器我们把这这个像素点和周围点的关系反映到特征图中。
首先分析边缘检测,假如你不是位于像素区域边缘的话,你和周围的像素值的差距理论上很小,在经过边缘检测的核函数之后这个点的像素值就会接近0(因为采用的是8相邻,中间的数字正好是8,周围是-1),就会变黑,自然边缘白色的部分就显示出来了。
接着是锐化,我们可以看到锐化的核函数和边缘检测的核函数是很相似的,只不过锐化采用的是四相邻,中间的数值是5,所以说即使这个像素点的值和周围的像素点的值相差不多,它还是会保持自己原本的状态,所以并不会出现很多黑色的部分,只是简单的突出了一下自己。
最后分析一下模糊,我们可以发现核函数里面的数加起来正好是1,如果某张图片的像素值都非常接近的话,那么很明显,经过模糊处理之后不会发生任何改变。模糊过程会把你和周围像素的差距进行分摊,使你和周围的像素差没有那么明显,当然还是以你自己为主,毕竟中间的值最大,从而达到了模糊的效果。

卷积核实现的不同效果及其原理

三、编程实现:

1.经典卷积核

代码实现

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号 #有中文出现的情况,需要u'内容
# https://blog.csdn.net/weixin_40123108/article/details/83510592
file_path = 'pic.jpeg'
im = Image.open(file_path).convert('L')  # 读入一张灰度图的图片
im = np.array(im, dtype='float32')  # 将其转换为一个矩阵
print(im.shape[0], im.shape[1])
plt.imshow(im.astype('uint8'), cmap='gray')  # 可视化图片
plt.title('原图')
plt.show()

im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))
conv1 = nn.Conv2d(1, 1, 3, bias=False)  # 定义卷积

sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 1, -1],
                         [-1, -1, -1]], dtype='float32')  # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3))  # 适配卷积的输入输出
conv1.weight.data = torch.from_numpy(sobel_kernel)  # 给卷积的 kernel 赋值

edge1 = conv1(Variable(im))  # 作用在图片上

x = edge1.data.squeeze().numpy()
print(x.shape)  # 输出大小


plt.imshow(x, cmap='gray')
plt.show()

就利用上面的核函数的参数进行处理。

原图
在这里插入图片描述
边缘检测
在这里插入图片描述
锐化
在这里插入图片描述
模糊

在这里插入图片描述

2.更换卷积核参数

经典的核函数虽然说有特定的作用,但是对不同的图片来说,同一个核函数很可能效果都不一样。所以想要达到想要的效果还是要根据需求变一下的。

上一个边缘检测黑白对比显然不是很明显,我们试着把中心点的8改成1在这里插入图片描述
再试一下把8改成16,发现增大之后越来越接近原图了。在这里插入图片描述

分析可以发现如果把8变成16就会变得更“白”,确实接近原图。因为电脑运行例子的过程实在太缓慢,这里不过多展示。

3.更换不同尺寸的图片

原图
在这里插入图片描述
边缘检测
在这里插入图片描述
不同尺寸的图片,观察不到明显区别。

4.更多卷积核

直接用网站测试测试网站
这个测试网站时非常便捷的,非常适合观察卷积核参数改变的过程中特征图的变化情况,更加深刻的理解卷积这个过程,强烈推荐去尝试一下。
1、bottom sobel 底部边缘检测
可以看到这个卷积核,顶部和底部像素差别大的地方突出显示。效果很不错。
在这里插入图片描述

2、left sobel 左部边缘加测,可以看到和底部检测还是有不同的
在这里插入图片描述

3、identity 一致,从卷积核函数就可以看出来,就是原图
在这里插入图片描述
4、emboss 浮雕
这个卷积核很有意思,对角线对称取相反数,可能时图片的问题,效果不是很明显。
在这里插入图片描述

5.彩色图片边缘检测

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号 #有中文出现的情况,需要u'内容
# https://blog.csdn.net/weixin_40123108/article/details/83510592
file_path = 'p.png'
im = Image.open(file_path)  # 读入一张的图片
im = np.array(im, dtype='float32')  
print(im.shape[0], im.shape[1])
im=np.transpose(im,(2,1,0))
im=im[np.newaxis,:]
conv1 = nn.Conv2d(3, 3, 3, bias=False)  # 定义卷积
sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 8, -1],
                         [-1, -1, -1]], dtype='float32')/3  # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3))  # 适配卷积的输入输出
sobel_kernel=np.repeat(sobel_kernel,3,axis=1)#数组,次数,维度
sobel_kernel=np.repeat(sobel_kernel,3,axis=0)
conv1.weight.data = torch.from_numpy(sobel_kernel)  # 给卷积的 kernel 赋值

edge1 = conv1(Variable(torch.from_numpy(im)))  # 作用在图片上
x = edge1.data.squeeze().numpy()
print(x.shape)  # 输出大小
x=np.transpose(x,(2,1,0))
plt.imshow(x, cmap='gray')
plt.title('彩色')
plt.show()

在这里插入图片描述
想要了解更多有关彩色图像处理的可以参考这里

总结

想要达到自己想要的图片效果,并不一定可以通过卷积固定函数实现,往往需要根据实际的情况改变合适的参数来达到自己想要的结果。

参考

卷积核实现的不同效果及其原理
第6章 Python 数字图像处理(DIP) - 彩色图像处理3
【2021-2022 春学期】人工智能-作业4:CNN - 卷积

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值