卷积在图像处理中的应用

AI 2年前 (2022) admin
813 0 0


Convolution又名卷积卷积神经网络(Convolutional Neural NetworkCNN常常在网络的一层中使用卷积运算来代替一般的矩阵乘法运算。本文主要带大家了解一下卷积在图像处理中的应用

 卷积的原理及意义 
本质上,对于信号处理,卷积类似是一个对周围信息的加权求和,或者说是对信号进行滤波。
卷积在图像处理中的应用
在泛函分析中,卷积、旋积或褶积(英语:Convolution)是通过两个函数f和g生成第三个函数的一种数学运算,其本质是一种特殊的积分变换,表征函数f与g经过翻转和平移的重叠部分函数值乘积对重叠长度的积分。
卷积就是先对 g 函数进行翻转(一维)或者旋转(二维),这是“卷”的过程
然后再把 g 函数平移 n,在这个位置 f,g 两个函数的对应点相乘,然后相加,这个过程是卷积的“积”的过程。
 运算方法 

二维卷积 

卷积在图像处理中的应用
输入x(4,4):
x00
x01
x02
x03
x10
x11
x12
x13
x20
x21
x22
x23
x30
x31
x32
x33
卷积核h(3,3):
h00
h01
h01
h10
h11
h12
h20
h21
h22
输出y(2,2):
y00
y01
y10
y11

卷积在图像处理中的应用
需要将kernel进行逆时针翻转180然后平移
h22
h21
h20
h12
h11
h10
h02
h01
h00
y(0,0) = x(0,0)h(2,2) + x(0,1)h(2,1) + x(0,2)h(2,0) + x(1,0)h(1,2) + x(1,1)h(1,1) + x(1,2)h(1,0) + x(2,0)h(0,2) + x(2,1)h(0,1) + x(2,2)h(0,0)
依此类推
假设卷积核kernel
1
2
1
0
0
0
-1
-2
-1
待处理矩阵x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
y=x*h
将卷积核旋转180°,即
-1
-2
-1
0
0
0
1
2
1
将卷积核h第一个元素对准x的第一个元素,然后hx重叠的元素相乘,再将相乘后h对应的元素相加,得到结果矩阵中Y的第一个元素。如:
-1*1
-2*2
-1*3
4
0*5
0*6
0*7
8
1*9
2*10
1*11
12
13
14
15
16
所以结果矩阵中的第一个元素y00 =(-1*1) + (-2*2) + (-1*3) + (0*5) + (0*6) + (0*7) + (1*9) + (2*10) + (1*11) = 32
x中的每一个元素都用这样的方法来计算,得到的卷积结果矩阵为
32
32
32
32


  图像的padding 

我们发现上面的输入是4*4输出却是2*2这是因为每次卷积都会缩小图像的尺寸,结果得到一张缩小后的图像。
因此,为了避免这一问题,在进行卷积运算之前可以先对图像进行填充操作。 padding有两种方式,一种在填充0,一种是填充与其距离最近的元素。
如果想使得卷积之后的结果与原图像一致,padding_w,padding_h为卷积核大小的一半(向下取整,即卷积核大小对2的余数)。比如核的大小是5*5,那么padding的长宽便是2
同样再看上面的例子
假设卷积核kernel
1
2
1
0
0
0
-1
-2
-1
待处理矩阵x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
y=x*h
1.将卷积核旋转180°,即
-1
-2
-1
0
0
0
1
2
1
2.将输入进行padding因为kernel大小为3*3所以padding_w = padding_h = 3/2 =1填充的位置使用0代替。 
0
0
0
0
0
0
0
1
2
3
4
0
0
5
6
7
8
0
0
9
10
11
12
0
0
13
14
15
16
0
0
0
0
0
0
0
3.将卷积核h第一个元素对准paddingx的第一个元素,然后hx重叠的元素相乘,再将相乘后h对应的元素相加,得到结果矩阵中y的第一个元素。如:
-1*0
-2*0
-1*0
0
0
0
0*0
0*1
0*2
3
4
0
1*0
2*5
1*6
7
8
0
0
9
10
11
12
0
0
13
14
15
16
0
0
0
0
0
0
0
所以结果矩阵中的第一个元素Y11 = (-1 * 0) + (-2 * 0) + (-1 * 0) + (0 * 0) + (0 * 1) + (0 * 2) + (1 * 0) + (2 * 5) + (1 * 6) = 16
4.将h向右平移并对x中的每一个元素都用这样的方法来计算,得到的卷积结果矩阵为
16
24
28
23
24
32
32
24
24
32
32
24
-28
-40
-44
-35


 python 代码 

了解了卷积的计算方式之后我们就可以自己构建一个简单的脚本来进行计算。
f-8
import numpy as np
from PIL import Image
import math

def corr2D(image:np.array, kernel:np.array):
    # 翻转180度
    kernel = kernel[::-1,::-1]
    # kernel和图片的尺寸
    kernel_size_w = kernel.shape[0]
    kernel_size_h = kernel.shape[1]
    image_w = image.shape[0]
    image_h = image.shape[1]
    # 0填充padding
    padding_w = padding_h = int(kernel_size_w/2)
    padding_image = np.pad(image,((1,padding_w),(1,padding_h)))
    # 生成新的array
    new_image_array = np.zeros((image_w,image_h))
    for i in range(image_w):
        for j in range(image_h):
            # 卷积
            new_image_array[i][j] = (np.multiply(padding_image[i:i+kernel_size_w,j:j+kernel_size_h],kernel)).sum()
    return new_image_array.clip(0,255).astype("uint8")

def corr2D_xy(image:np.array, kernel_x:np.array,kernel_y:np.array):
    # 翻转180度
    kernel_x = kernel_x[::-1,::-1]
    kernel_y = kernel_y[::-1,::-1]
    # kernel和图片的尺寸
    kernel_size_w = kernel_x.shape[0]
    kernel_size_h = kernel_x.shape[1]
    image_w = image.shape[0]
    image_h = image.shape[1]
    # 0填充padding
    padding_w = padding_h = int(kernel_size_w/2)
    padding_image = np.pad(image,((1,padding_w),(1,padding_h)))
    # 生成新的array
    new_image = np.zeros((image_w,image_h))
    for i in range(image_w):
        for j in range(image_h):
            # 水平和垂直联合梯度
            mx = (np.multiply(padding_image[i:i+kernel_size_w,j:j+kernel_size_h],kernel_x)).sum()
            my = (np.multiply(padding_image[i:i+kernel_size_w,j:j+kernel_size_h],kernel_y)).sum()
            new_image[i][j] = math.sqrt(mx*mx+my*my)
    return new_image.clip(0,255).astype("uint8")


def pic_cor(pic,kernel,output="./output.png"):
    # 卷积核
    origin = Image.open(pic)
    # 图片转array
    image_array = np.array(origin)
    # 对三个通道分别卷积
    for tunnel in range(0,3):
        image_array[:, :, tunnel] = corr2D(image_array[:, :, tunnel],kernel)
    # 保存图片
    merged=Image.fromarray(image_array)
    merged.save(output)

def pic_cor_xy(pic,kernel_x,kernel_y,output="./output.png"):
    origin = Image.open(pic)
    # 图片转array
    image_array = np.array(origin)
    # 对三个通道分别卷积
    for tunnel in range(0,3):
        image_array[:, :, tunnel] = corr2D_xy(image_array[:, :, tunnel],kernel_x,kernel_y)
    # 保存图片
    merged=Image.fromarray(image_array)
    merged.save(output)

pic= "./apple.png"
kernel_laplacian = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
kernel_sobel_x = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
kernel_sobel_y = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
pic_cor(pic,kernel_laplacian,output="./laplacian.png")
pic_cor_xy(pic,kernel_sobel_x,kernel_sobel_y,output="./xy.png")

 卷积核 
1)原始图像通过与卷积核的数学运算,可以提取出图像的某些指定特征
2)不同卷积核,提取的特征也是不一样的
3)提取的特征一样,不同的卷积核,效果也不一样

 无用核 

没有任何作用的核。
0
0
0
0
1
0
0
0
0


 平滑滤波 

均值滤波

此时每个像素都是附近(包括自己)9个像素的平均值。
G:
1/9
1/9
1/9
1/9
1/9
1/9
1/9
1/9
1/9
下图是原图和滤波后的图片对比,可以看出来,模糊了一些。
卷积在图像处理中的应用
原图与卷积对比图
这样看其实不太明显,我们在原图的基础上添加了噪点,再运行卷积。
卷积在图像处理中的应用
噪点与卷积对比图
这个时候我们发现,经过卷积后,噪点不再明显。
 高斯滤波 
卷积在图像处理中的应用
G:
1/16
2/16
1/16
2/16
4/16
2/16
1/16
2/16
1/16
对原图进行高斯滤波,得到模糊的效果。
卷积在图像处理中的应用
原图与卷积对比图
对加了噪点的图进行高斯滤波,也达到了去噪点的效果。
卷积在图像处理中的应用 噪点与卷积对比图


 边缘检测 

Laplacian边缘检测

G:
-1
-1
-1
-1
8
-1
-1
-1
-1

卷积在图像处理中的应用
原图与卷积对比图

roberts边缘检测

Gx:
-1
0
0
1
Gy:
0
-1
1
0
 
卷积在图像处理中的应用
垂直的边界与水平边界对比图
卷积在图像处理中的应用
原图与联合梯度对比图

Perwitt边缘检测

-1
-1
-1
0
0
0
1
1
1
-1
0
1
-1
0
1
-1
0
1
 卷积在图像处理中的应用垂直的边界与水平边界对比图
卷积在图像处理中的应用
原图与联合梯度对比图

Sobel边缘检测

Gx:
-1
0
1
-2
0
2
-1
0
1
Gy:
-1
-2
-1
0
0
0
1
2
1
卷积在图像处理中的应用垂直的边界与水平边界对比图
卷积在图像处理中的应用
原图与联合梯度对比图
以上就是卷积在卷积在图像处理中的应用,当然整个过程中还有一些其他的知识点 
1.每次卷积核移动一个单位,这个距离就是步长(stride),一般来说,步长位置为1或者2即可。
2.这个卷积核的尺寸为3*3,也可以是5*57*711*11,一般来说为单数正方形,也会有3*5这种长方形卷积核。
      

原文始发于微信公众号(山石网科安全技术研究院):卷积在图像处理中的应用

版权声明:admin 发表于 2022年9月23日 上午10:36。
转载请注明:卷积在图像处理中的应用 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...