侧边栏壁纸
博主头像
Dioxide-CN博主等级

茶边话旧,看几许星迢露冕,从淮海南来。

  • 累计撰写 47 篇文章
  • 累计创建 46 个标签
  • 累计收到 21 条评论

目 录CONTENT

文章目录

计算机视觉:7.1 卷积神经网络

Dioxide-CN
2022-07-09 / 0 评论 / 4 点赞 / 115 阅读 / 2,576 字
温馨提示:
本文最后更新于 2022-08-02,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

卷积神经网络

7.1 卷积操作

图片卷积

图像卷积就是卷积核在图像上按行滑动遍历像素时不断地相乘求和的过程。

原图 Image:
1
1
1x1
0x0
0x1
0
1
1x0
1x1
0x0
0
0
1x1
1x0
1x1
0
0
1
1
0
0
1
1
0
0
其中3x3的扫描区域作为卷积核,扫描区域中的矩阵与矩阵:

[101010101]\left[ \begin{matrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 0 & 1 \end{matrix} \right]

做线性运算:

(11+00+01)+(10+11+00)+(11+10+11)=4(1*1+0*0+0*1)+(1*0+1*1+0*0)+(1*1+1*0+1*1)=4

卷积特征 Convolved Feature:
4
3
4
2
4
3
2
3
4

Pasted image 20220710101744

步长

步长就是卷积核在图像上移动的步幅。在上一个例子中,卷积核每次移动一个像素步长的结果,如果将这个步长修改为2个像素,结果又不一样。
为了充分扫描图片,步长一般设置为1

Pasted image 20220710101802

padding

从上面的例子中我们发现,卷积之后图片的长宽会变小。如果要保持图片大小不变,我们需要在图片周围填充0,padding指的就是填充的0的圈数

Pasted image 20220710101951

我们可以通过公式计算出需要填充的0的圈数:

  1. 输入体积大小 H₁ * W₁ * D₁ (宽 x 高 x 通道数)
  2. 四个参数
    • Filter数量:K
    • Filter大小:F(3x3、5x5 等)
    • 步长:S
    • 0填充大小:P
  3. 输出体积大小 H₂ * W₂ * D₂

H2=(H1F+2P)S+1H_2={(H_1-F+2*P) \over S}+1

W2=(W1F+2P)S+1W_2={(W_1-F+2*P) \over S}+1

D2=KD_2=K

例题:
现给定一张28x28的图片,卷积核大小为5x5,步长为1,padding为0,计算一次卷积后得到的图片大小?
解:

(285+20)1+1=24{(28 - 5 + 2 * 0) \over 1} + 1 = 24

∴ 一次卷积后得到的图片大小为 24x24

综上:

  1. 3x3的卷积核若没有padding,则一次卷积后的图片宽高均 -2
  2. 5x5的卷积核若没有padding,则一次卷积后的图片宽高均 -4
  3. 7x7的卷积核若没有padding,则一次卷积后的图片宽高均 -6

如果要保持卷积之后图片大小不变,可以得出等式:

(N+2PF+1)=N(N+2*P-F+1)=N

从而可以推导出:

P=F12P={F-1 \over 2}

综上:

  1. 3x3的卷积核需要补1圈0
  2. 5x5的卷积核需要补2圈0
  3. 7x7的卷积核需要补3圈0

Pasted image 20220710110231

卷积核的大小

图片卷积中,卷积核一般为奇数,比如 3x3 5x5 7x7 为什么选用奇数卷积核,需要从以下两个方面进行考虑:

  1. 根据上述padding的计算公式,如果要保持图片大小不变,采用偶数卷积核的话会出现填充1.5层零圈的情况。
  2. 奇数维度的过滤器有中心点,便于指出过滤器的位置,即OpenCV卷积中的锚点。

卷积案例

  • filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
    • ddepth:卷积之后图片的位深,即卷积之后图片的数据类型,一般为-1,表示核原图类型保持一致;
    • kernel:卷积核大小,用元组或ndarray表示,要求数据类型必须是float类型;
    • anchor:锚点,即卷积核的中心点,是可选参数,默认为(-1, -1);
    • delta:可选参数,表示卷积之后额外加的一个值,相当于线性方程中的偏差,默认为0;
    • borderType:边界类型,一般不设置;
# OpenCV图像卷积操作
import cv2
import numpy as np

img = cv2.imread('./dog.jpg')

# kernel必须是float类型
# 相当于原始图片中的每个点都被平均了一次,所以图片变模糊了
kernel = np.ones((5, 5), np.float32) / 25

# 2D卷积
dst = cv2.filter2D(img, -1, kernel)

cv2.imshow('2Dfilter', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220710111205

使用不同的卷积核提取不同的特征:

  1. 轮廓卷积
# 轮廓卷积
import cv2
import numpy as np

img = cv2.imread('./dog.jpg')

kernel = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])

dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220710111501

  1. 浮雕卷积
# 浮雕卷积
import cv2
import numpy as np

img = cv2.imread('./dog.jpg')

kernel = np.array([[-2,1,0],[-1,1,1],[0,1,2]])

dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220710111620

  1. 锐化卷积
# 锐化卷积
import cv2
import numpy as np

img = cv2.imread('./dog.jpg')

kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])

dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

Pasted image 20220710111721

4

评论区