手写代码实现卷积操作(Python)

在卷积神经网络中,才用卷积技术实现对图片的降噪和特征提取。

一般我们构建卷积神经网络都是使用成熟的框架,今天我就来自己实现一下卷积,并使用不同的卷积核来看看效果。

 

卷积操作的原理可以由下图表示:

 一个3*3的卷积核,以滑动窗口的形式在图片上滑动,每滑动一次,就计算窗口中的数据的加权之和,权值就是卷积核的数据。

通过这个过程将图片进行转化。

 

准备图片数据:

 使用PIL库读取图片:

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

读取图片,并可视化:

img = Image.open('金鱼姬.jpg')
plt.axis("off")
plt.imshow(img)

 以灰度显示图片:

gray = img.convert('L')
plt.figure()
plt.imshow(gray, cmap='gray')
plt.axis('off')

 

 RGB三通道数据分离:

r, g, b = img.split()

        三色通道可视化:

plt.imshow(r, cmap='gray')
plt.axis('off')

 将图片数据转化为np矩阵:

np.array(img)
np.array(r)
np.array(g)
np.array(b)

单通道数据(r):

#定义卷积核(3*3)
k = np.array([[0,1,2],[2,2,0],[0,1,2]
])

我们使用单通道图片数据进行卷积:

data = np.array(r)
n,m = data.shape

       可以看到,图片的大小为:720*1280

 

关键点来了,定义卷积函数(二维):

def convolution(k, data):n,m = data.shapeimg_new = []for i in range(n-3):line = []for j in range(m-3):a = data[i:i+3,j:j+3]line.append(np.sum(np.multiply(k, a)))img_new.append(line)return np.array(img_new)

采用双循环遍历图片数据,line存储一行卷积后的数据,img_new记录每一行卷积后的数据,形成新的图片

 

下面来看一看卷积结果:

img_new = convolution(k, data)#卷积过程#卷积结果可视化
plt.imshow(img_new, cmap='gray')
plt.axis('off')

 因为卷积结果和卷积核有密切关系,虽然上图看上去没他大的区别,那是因为卷积核的关系。

 

我们来使用常见的几种卷积核来看看结果:

卷积核1:垂直边缘检测

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

可以看到,图片中物体的纵向边界特征被提取出来,而其他的特征被弱化了

 

卷积核2:水平边缘检测

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

可以看出,横向特征被凸显。

我们换一个,纵向特征比较明显的图片来试一下:

 例如该图中有很多竖向的扶手,我们看看他的卷积后的效果:

垂直边缘检测:

水平边缘检测:

这样看,特征就很明显了。

通过卷积后的图片,大小变化了,可以使用零填充技术使得输出图片和原图片大小一致,这里就不实现了,本文主要是实现卷积过程。

还有其他常用的卷积核,以下分别展示一下各自的效果:

 

sobel滤波(纵向,横向):

scharr滤波(纵向,横向):

 大家猜猜,最后我使用的是出自哪里的图片吧!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部