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

一、简单描述卷积、卷积核、多通道、特征图、特征选择概念。

卷积:
卷积常用于图像的特征提取,针对像素点进行处理的一种技术。
人工智能-作业4:CNN - 卷积_第1张图片
卷积核:
卷积核就是图像处理时,给定输入图像,输入图像中一个小区域中像素加权平均后成为输出图像中的每个对应像素,其中权值由一个函数定义,这个函数称为卷积核。示例如下:
人工智能-作业4:CNN - 卷积_第2张图片
多通道:
在多通道模式中,第个通道都合用256灰度级存放着图像中颜色元素的信息。该模式多用于特定的打印或输出。

特征图:
卷积计算的结果,图像与卷积核加权累加得到卷积(滤波)后的特征图。如“卷积核”中计算结果矩阵
( 19 25 37 43 ) \left( \begin{matrix} 19 & 25\\ 37 & 43 \end{matrix} \right) (19372543)
就是一个特征图。

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

人工智能-作业4:CNN - 卷积_第3张图片

二、探究不同卷积核的作用,研究背后的原理。

图像核心是一个小矩阵,一般有模糊、锐化、轮廓或浮雕等处理方式。它们还用于机器学习中的“特征提取”,这是一种确定图像最重要部分的技术。在这种情况下,这个过程通常被称为“卷积”。
详细学习和理解可以参考:Image Kernels
1.边缘检测
边缘检测的目的就是找到图像中亮度变化剧烈的像素点构成的集合,表现出来往往是轮廓。
卷积核:
人工智能-作业4:CNN - 卷积_第4张图片
处理效果示例:
人工智能-作业4:CNN - 卷积_第5张图片

2.锐化
图像锐化也称边缘增强。锐化技术用于加强图像中的边界和细节信息。由于边界和细节信息对应频域中的高频部分,所以在频域中通常对图像进行高通滤波,在空间域则进行微分处理。
卷积核:
人工智能-作业4:CNN - 卷积_第6张图片
处理效果:
人工智能-作业4:CNN - 卷积_第7张图片
3.模糊
卷积核:
人工智能-作业4:CNN - 卷积_第8张图片
示例:
人工智能-作业4:CNN - 卷积_第9张图片
作者提到:“The large, granulated picture has been blown up to make it easier to see;”均如上图所示
同时还可以选择自己的图片进行处理如下:
人工智能-作业4:CNN - 卷积_第10张图片

三、编程实现:

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
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 = 'test3.JPG'
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, 8, -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()


原图:
人工智能-作业4:CNN - 卷积_第11张图片

边缘检测:
轮廓检测算子:

sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 8, -1],
                         [-1, -1, -1]], dtype='float32')  # 定义轮廓检测算子

人工智能-作业4:CNN - 卷积_第12张图片

锐化:

sobel_kernel = np.array([[0, -1, 0],
                         [-1, 5, -1],
                         [0, -1, 0]], dtype='float32')  # 定义轮廓检测算子

人工智能-作业4:CNN - 卷积_第13张图片

模糊:

sobel_kernel = np.array([[0.0625, 0.125, 0.0625],
                         [0.125, 0.25, 0.125],
                         [0.0625, 0.125, 0.0625]], dtype='float32')  # 定义轮廓检测算子

人工智能-作业4:CNN - 卷积_第14张图片

2.调整经典卷积核参数,测试并总结。

可以看到上述实验中边缘检测的图片比较“不合适”,降低中心权重,可以发现图像对边缘的检测效率降低,修改算子如下:

sobel_kernel = np.array([[-1, -1, -1],
                         [-1, 5, -1],
                         [-1, -1, -1]], dtype='float32')  # 定义轮廓检测算子

实现效果:
人工智能-作业4:CNN - 卷积_第15张图片

3.使用不同尺寸图片,测试并总结。

换一个不同尺寸的图片如下:
人工智能-作业4:CNN - 卷积_第16张图片
边缘检测:
人工智能-作业4:CNN - 卷积_第17张图片
锐化:
人工智能-作业4:CNN - 卷积_第18张图片
模糊:
人工智能-作业4:CNN - 卷积_第19张图片

4.探索更多类型卷积核。

浮雕效果:

sobel_kernel = np.array([[-1, -1, 0],
                         [-1, 0, 1],
                         [0, 1, 1]], dtype='float32')  # 卷积核

人工智能-作业4:CNN - 卷积_第20张图片
right sobel:

sobel_kernel = np.array([[-1, 0, 1],
                         [-2, 0, 2],
                         [-1, 0, 1]], dtype='float32')  # 定义轮廓检测算子

人工智能-作业4:CNN - 卷积_第21张图片

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 = 'test3.jpg'
im = Image.open(file_path)  # 读入一张的图片
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])))
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()

人工智能-作业4:CNN - 卷积_第22张图片

四、总结

前半部分知识理解还是比较容易的,通过卷积核的计算方法也比较简单,但是当我开始实现代码的时候,系统总报错,查找原因发现是系统中有多个重复的库,添加代码后即可运行。

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

通过实验对于CNN-卷积部分有了更深的理解,同时也感觉很有意思。彩色图片的边缘检测还是遇到了点困难,通过同学的帮助,上网查找,成功实现~

参考资料:
什么是深度学习卷积
【深度学习入门】——亲手实现图像卷积操作
【2021-2022 春学期】人工智能-作业4:CNN - 卷积

你可能感兴趣的:(人工智能实验,cnn,人工智能,计算机视觉)