目录
一、获取并绘制图像
二、手写卷积
1、设置卷积核及权重
2、卷积
2-1、卷积实现
2-2、 限值
2-3、图像赋值
2-4、显示
卷积代码
三、手写池化
1、创建图像
2、遍历池化
3、显示图像
池化代码
总代码
import cv2
import numpy as np
# 从scipy库中获取名为"上升"的图像。这是一张漂亮的内置图片,有很多角度和线条
from scipy import misc
image = misc.ascent() #获取图像
width,height = image.shape #获取图像宽高
# 绘制图像(灰度图)
import matplotlib.pyplot as plt
plt.imshow(image)
plt.gray()
plt.show()
如果过滤器中的所有数字加起来不是0或1,那么就应该设置权重,让过滤器的总和为0或1。
例如,如果过滤器是1,1,1,1,2,1,1,1,1。
它们加起来是10,所以可以设置0.1的权重,使它标准化。
# 设置卷积核及权重
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
weight = 1
# 卷积
# 对图像每行每列分别卷积(除去最外层)
for x in range(1, width-1):
for y in range(1, height-1):
# 实现卷积
# convolution += 图像列元素*卷积核行元素
convolution = 0.0
for i in range(3):
for j in range(3):
convolution += image[x-1+j, y-1+i]*filter[i][j]
convolution *= weight
# 限值
if convolution > 255:
convolution = 255
elif convolution <0:
convolution = 0
注:不能直接对原图赋值:被赋值后,原图会发生改变,后面还要用原图做卷积。
# 图像赋值
copy[x][y] = convolution
如果直接对原图赋值,得到的就是这种图像:
# 显示灰度图
plt.imshow(copy)
plt.show()
# 手写实现图像卷积
# 设置卷积核及权重
copy = image.copy()
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
weight = 1
# 如果过滤器中的所有数字加起来不是0或1,那么就应该设置权重,让过滤器的总和为0或1。
# 例如,如果过滤器是1,1,1,1,2,1,1,1,1。
# 它们加起来是10,所以可以设置0.1的权重,使它标准化。
# 卷积
for x in range(1, width-1):
for y in range(1, height-1):
# 实现卷积(图像对应位置 分别乘 卷积核对应位置)
convolution = 0.0
for i in range(3):
for j in range(3):
# 列和行分别对应相乘
convolution += image[x-1+j, y-1+i]*filter[i][j]
convolution *= weight
# 限值
if convolution > 255:
convolution = 255
elif convolution <0:
convolution = 0
# 图像赋值
copy[x][y] = convolution
# 显示灰度图
plt.gray()
plt.grid(False)
plt.imshow(copy)
#plt.axis('off')
plt.show()
在减小图像数据量的同时,保留图像的特征。
# 创建图像(大小为原图的1/4)
new_image2 = np.zeros((int(width/2), int(height/2)))
在:本像素、右像素、下像素、右下像素等四个像素中,选取一个最大值,作为缩小后的新图像当前位置值。
# 遍历池化(步长为2)
for x in range(0, width, 2):
for y in range(0, height, 2):
# 选取最大像素
pixels = []
pixels.append(new_image[x][y])
pixels.append(new_image[x+1][y])
pixels.append(new_image[x][y+1])
pixels.append(new_image[x+1][y+1])
new_image2[int(x/2)][int(y/2)] = max(pixels)
# 显示图像
plt.gray()
plt.imshow(new_image2)
plt.show()
可以发现图像大小减半的同时,特征也得以保留。
# 池化(最大值)
import numpy as np
# 创建图像(大小为原图的1/4)
new_image2 = np.zeros((int(width/2), int(height/2)))
# 遍历池化(步长为2)
for x in range(0, width, 2):
for y in range(0, height, 2):
# 选取最大像素
pixels = []
pixels.append(new_image[x][y])
pixels.append(new_image[x+1][y])
pixels.append(new_image[x][y+1])
pixels.append(new_image[x+1][y+1])
new_image2[int(x/2)][int(y/2)] = max(pixels)
# 显示图像
plt.gray()
plt.imshow(new_image2)
plt.show()
import cv2
from scipy import misc
image = misc.ascent()
import matplotlib.pyplot as plt
plt.grid(False)
plt.gray()
plt.imshow(image)
plt.show()
# 图像尺寸
width, height = image.shape
# 手写实现图像卷积
# 设置卷积核及权重
new_image = image.copy()
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
weight = 1
# 如果过滤器中的所有数字加起来不是0或1,那么就应该设置权重,让过滤器的总和为0或1。
# 例如,如果过滤器是1,1,1,1,2,1,1,1,1。
# 它们加起来是10,所以可以设置0.1的权重,使它标准化。
# 卷积
for x in range(1, width-1):
for y in range(1, height-1):
# 实现卷积(图像对应位置 分别乘 卷积核对应位置)
convolution = 0.0
for i in range(3):
for j in range(3):
# 列和行分别对应相乘
convolution += image[x-1+j][y-1+i]*filter[i][j]
convolution *= weight
# 限值
if convolution > 255:
convolution = 255
elif convolution <0:
convolution = 0
# 图像赋值
new_image[x][y] = convolution
# 显示灰度图
plt.gray()
plt.grid(False)
plt.imshow(new_image)
plt.show()
# 池化(最大值)
import numpy as np
# 创建图像(大小为原图的1/4)
new_image2 = np.zeros((int(width/2), int(height/2)))
# 遍历池化(步长为2)
for x in range(0, width, 2):
for y in range(0, height, 2):
# 选取最大像素
pixels = []
pixels.append(new_image[x][y])
pixels.append(new_image[x+1][y])
pixels.append(new_image[x][y+1])
pixels.append(new_image[x+1][y+1])
new_image2[int(x/2)][int(y/2)] = max(pixels)
# 显示图像
plt.gray()
plt.imshow(new_image2)
plt.show()