文章目录
一、概念理解
1.卷积核
卷积核是一个矩阵,用于在卷积过程中与图片的表示矩阵相乘完成图片特征的提取。卷积核就相当于权重,所以不同的卷积核提取到的特征不同,卷积的结果也不同。
2.卷积
卷积运算多用于图像处理,计算机处理图像是将图像转化为数字矩阵表示。
卷积就是用卷积核与表示图片的数字矩阵相乘(不是矩阵乘法),得到的新矩阵就是结果特征提取的图片。
3.多通道
对于同一张图片的数字矩阵,使用不同的卷积核进行卷积运算得到不同的结果,将不同的卷积核得到的结果相加得到最终结果,这就是卷积运算中的多通道。
在卷积过程中使用的卷积核的个数就是通道数
4.特征图
图像的数字矩阵和卷积核进行加权累加的到的结果就是特征图。
5.特征选择
正如前面所说,使用不同的卷积核进行卷积运算得到的特征图不同,也可以理解为不同的卷积核所提取到的图片特征不同,实现图片的特征选择。
二、卷积核
1.锐化卷积核
该卷积核利用的是图像中的边缘信息有着比周围像素更高的对比度,而经过卷积之后进一步增强了这种对比度,从而使图像显得棱角分明、画面清晰,起到锐化图像的效果。
2.高斯模糊卷积核
高斯模糊使卷积结果在水平和垂直方向呈现高斯分布,更突出了中心点在像素模糊后的权重,相比于均值滤波而言,有着更好的模糊效果。
3.边缘检测卷积核
边缘检测卷积核利用边缘部分的两侧的数值会有较大差别的原理
当卷积核与边缘区域作卷积运算时得出的结果较大,在图片中显示外白色
在非边缘部分计算的卷积结果较小,表现为黑色;由此可以突出边缘显示。
三、编程实现
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 = 'deer.png'
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 = 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.title('边缘检测')
plt.show()
原图
a.锐化
填入锐化卷积核
sobel_kernel = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]], dtype='float32')
卷积结果
b.模糊
填入模糊卷积核
sobel_kernel = np.array([[0.0625, 0.125, 0.0625],
[0.125, 0.25, 0.125],
[0.0625, 0.125, 0.0625]], dtype='float32')
卷积结果
c.边缘检测
填入边缘卷积核
sobel_kernel = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]], dtype='float32')
卷积结果
2.更换卷积核参数
a.更改锐化参数
###原参数
sobel_kernel = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]], dtype='float32')
###更改后的参数
sobel_kernel = np.array([[0, -1, 0],
[-1, 15, -1],
[0, -1, 0]], dtype='float32')
卷积结果,可以看到和原图的区别不大
b.更改边缘检测参数
###原参数
sobel_kernel = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]], dtype='float32')
###更改后的参数
sobel_kernel = np.array([[-1, -1, -1],
[-1, 1, -1],
[-1, -1, -1]], dtype='float32')
卷积结果,可以看到达到了类似颜色反转的效果
3.更换不同尺寸的图片
使用700x698的图片进行边缘检测
原图:
结果:
使用高斯模糊的卷积核进行卷积的结果:
可以看到边缘检测的结果并不理想,更换了参数时候效果也不好。
对于较大的图片需要修改卷积核的大小,以实现更好的卷积效果。
4.更多卷积核
原图:
a.另一个边缘检测卷积核
sobel_kernel = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]], dtype='float32')
结果:
使用此卷积核实现的边缘检测效果较好
b.另一个模糊卷积核
sobel_kernel = np.array([[1, 1, 1],
[1, -6, 1],
[1, 1, 1]], dtype='float32')
结果:
可以看到非常的模糊,模糊到认不清
5.彩色图片边缘检测
使用opencv库中的函数进行彩色图片的特征提取。
原图:
a.模糊
code:
import cv2
rgb = cv2.imread("cat.jpg")
# 设置上下阈值
edge = cv2.blur(rgb,(10,10))
cv2.imshow("1", rgb)
cv2.imshow("blur", edge)
cv2.waitKey()
cv2.destroyAllWindows()
效果
b.边缘检测
code:
import cv2
rgb = cv2.imread("cat.jpg")
# 设置上下阈值
canny = cv2.Canny(rgb, 32, 128)
cv2.imshow("1", rgb)
cv2.imshow("canny", canny)
cv2.waitKey()
cv2.destroyAllWindows()
结果:
c.锐化
code:
import cv2
import numpy as np
rgb = cv2.imread("cat.jpg")
kernel = np.array([
[-2,-1,0],
[-1,1,1],
[0,1,2]])
sharpen = cv2.filter2D(rgb,-1,kernel)
cv2.imshow('1',rgb)
cv2.imshow('sharpen',sharpen)
cv2.waitKey()
cv2.destroyAllWindows()
结果
总结
学习了图片在加算机中的表示方法和处理方法。了解到了神经网络模型中的卷积的概念以及卷积的实现方法和实现过程中的各个参数的作用。
在了解到了理论之后又自己编码实现了简单的卷积图片提取,更加深刻的认识到了卷积的实现原理和不同卷积核对图片特征提取效果的不同。
参考文章
1.卷积神经网络(Convolutional Neural Network,CNN)
2.人工智能 作业4:CNN - 卷积
3.图像卷积详细解释 常用卷积核解释说明
4.[作业/人工智能] 作业4 CNN - 卷积
5.Python-OpenCV中的filter2D()函数实现图像变化
6.Python OpenCV对图像进行模糊处理详解流程