0
点赞
收藏
分享

微信扫一扫

CNN卷积网络_图像处理


文章目录

  • ​​一、卷积介绍​​
  • ​​1、origination:​​
  • ​​2、significance:​​
  • ​​3、卷积计算​​
  • ​​a-、滤波器(卷积核)​​
  • ​​a、卷积例子​​
  • ​​b、卷积之padding填充​​
  • ​​c、步幅​​
  • ​​e、注意​​
  • ​​f、整体理解​​
  • ​​二、图像处理基础​​
  • ​​1、读取图像​​
  • ​​2、撒点椒盐​​
  • ​​3、图像二值化​​
  • ​​4、分量提取​​
  • ​​5、灰度图片​​
  • ​​6、图像卷积处理之numpy​​
  • ​​7、图像卷积处理之tensorflow​​


本文主要从卷积, 图像, 图像的卷积处理, 卷积神经网络CNN的构建三部分,从理论到代码应用


使用python3.6编译器, jupyter编辑器


未完待续…

一、卷积介绍

1、origination:

一个面积不变的长方形,底边被挤的窄窄的,高度被挤的高高的,在数学中它可以被挤到无限高,但即使它无限瘦、无限高、但它仍然保持面积不变;为了证实它的存在,可以对它进行积分。

2、significance:

  • 意义1
    假设system1, 时刻t输入为x(t), 输出为y(t), 系统响应时间为h(t), 按道理输入输出关系是y(y)=h(t)*x(t); however, 系统输出不仅与系统t时刻相关, 还与t时刻之前响应相关, 所以t时刻的输出应该为t时刻之前系统响应函数在各个时刻响应的叠加,这就是卷积,用数学公式表示就是y(s)=∫x(t)h(s-t)dt
  • 物理意义

    卷积图像处理方面的应用
    用一个模板和一幅图像进行卷积,对于图像上的一个点,让模板的原点和该点重合,然后模板上的点和图像上对应的点相乘,然后各点的积相加,就得到了该点的卷积值。对图像上的每个点都这样处理。由于大多数模板都是对称的,所以模板不旋转。卷积是一种积分运算,用来求两个曲线重叠区域面积。可以看作加权求和,可以用来消除噪声、特征增强。
    把一个点的像素值用它周围的点的像素值的加权平均代替。
    卷积是一种线性运算,图像处理中常见的mask运算都是卷积,广泛应用于图像滤波。
    卷积在数据处理中用来平滑,卷积有平滑效应和展宽效应.
    ​参考:卷积的本质及物理意义(全面理解卷积)​​

3、卷积计算

为了更好的理解, 直接上例子

a-、滤波器(卷积核)

CNN卷积网络_图像处理_卷积核

a、卷积例子

CNN卷积网络_图像处理_卷积核_02


CNN卷积网络_图像处理_卷积_03

b、卷积之padding填充

CNN卷积网络_图像处理_卷积_04

填充方法有:

补零填充

CNN卷积网络_图像处理_卷积_05


边界复制填充, 镜像填充, 块填充

c、步幅

CNN卷积网络_图像处理_ide_06

### d、计算增加参数后, 卷积输出shape

CNN卷积网络_图像处理_ide_07

e、注意

CNN卷积网络_图像处理_卷积核_08

f、整体理解

CNN卷积网络_图像处理_ide_09

二、图像处理基础

1、读取图像

import numpy as np
import matplotlib.pyplot as plt
import sys,os
sys.path.append(os.pardir)
%matplotlib inline
img = np.array(plt.imread("../data/刘亦菲.jpg")) # 将图像格式转化np.array格式,方便后续处理
plt.figure("刘大姐")
plt.imshow(img) # 函数负责对图像进行处理,并显示其格式,但是不能显示
plt.axis("off")
plt.show()
print( img.shape )
print( img.dtype )
print( img.size )
print( type(img) )
print(img[0,0]) # 因为是RGB三通道

(1200, 1920, 3)
uint8
6912000
<class 'numpy.ndarray'>
[ 95 96 124]

CNN卷积网络_图像处理_ide_10

2、撒点椒盐

#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in range(5000):
x=np.random.randint(0,rows) # 在0-rows之间随便取值
y=np.random.randint(0,cols) #
img[x,y,:]=255 # 将这个随机点设置为白点, 即椒盐

plt.figure("beauty")
plt.imshow(img)
plt.axis('off')
plt.show()

CNN卷积网络_图像处理_卷积核_11

3、图像二值化

# 图像二值化
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

img = np.array(Image.open("../data/刘亦菲.jpg").convert('L'))
rows, cols = img.shape
for i in range(rows):
for j in range(cols):
if (img[i, j] <= 128):
img[i, j] = 0
else:
img[i, j] = 1

plt.figure("Mona Lisa")
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.show()

CNN卷积网络_图像处理_卷积_12

4、分量提取

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
img = np.array(plt.imread("../data/刘亦菲.jpg"))
plt.imshow(img[:, :, 0], cmap="gray") #L 分量转化为灰度图
plt.show()

plt.imshow(img[:, :, 1], cmap="gray") #G 分量转化为灰度图
plt.show()

plt.imshow(img[:, :, 1], ) # 只显示G 分量
plt.show()

CNN卷积网络_图像处理_ide_13

CNN卷积网络_图像处理_卷积_14

CNN卷积网络_图像处理_ide_15

5、灰度图片

from PIL import Image
img = np.array([1]) # 读取图片,并转换为灰度图片
img_1 = Image.open("../data/刘亦菲.jpg").convert('1') # 非黑即白
img = np.array(Image.open("../data/刘亦菲.jpg").convert('L')) # 0黑255白,其他数字灰度不同

plt.imshow(img_1, cmap="gray") # 图片只显示像素点为0或者255的值
plt.show()

plt.imshow(img, cmap="gray")
plt.show()

CNN卷积网络_图像处理_卷积核_16

CNN卷积网络_图像处理_ide_17

6、图像卷积处理之numpy

  • 本部分的图像卷积处理使用的是科学计算包numpy , 利用numpy的广播功能, 能够很简单的进行矩阵运。
  • 本部分的图像卷积, 是直接将图像的每一个像素点的三个通道的像素都进行了卷积处理,然后显示

# 图像卷积运算
import numpy as np
import matplotlib.pyplot as plt
import sys
sys.path.append("../")
%matplotlib inline
img = np.array(plt.imread("../data/刘亦菲.jpg"))
# 构建输出矩阵形状, 使用0填充,
def generate_dst(img, kernel, stride=1, padding=0): #默认步幅=1, 填充为0
m = (img.shape[0] + 2*padding - kernel.shape[0] + stride)/stride # 高
n = (img.shape[1] + 2*padding - kernel.shape[1] + stride)/stride # 长
rgb_channel = img.shape[2] # RGB三通道
print("新构建的图片形状%0.3f,%0.3f,%0.3f"%(m,n,rgb_channel))
return np.zeros((int(m),int(n),int(rgb_channel)),)

# 单个卷积核的运算
def div_convolution(img_block,kernel):
_img = np.array(img_block).flatten() #转化为一维
_kernel = np.array(kernel).flatten()
# return np.mean(_img*_kernel) #
return np.sum(_img*_kernel) # 正常的卷积运算是直接加和,并不进行均值计算


# 将图片按照convolution变换, 注意这里还没有对最终结果进行归一化
def convolution2dst(img,dst,kernel):
for i in range(dst.shape[0]):
for j in range(dst.shape[1]):
for k in range(dst.shape[2]): #通道
dst[i,j,k] = div_convolution(img[i:i+kernel.shape[0],
j:j+kernel.shape[1],k], # 与kernel一致的矩阵
kernel)


# 将图片归一化到256之间
def img2normalization_256(img_convolution):
_img = img_convolution.flatten()
_max = np.max(_img)
_min = np.min(_img)
_img = (_img-_min)*255/(_max-_min)
_img = np.array(_img, dtype="int64") # 将所有数据转化为int型
img_convolution_normalization = _img.reshape((img_convolution.shape[0],
img_convolution.shape[1],
img_convolution.shape[2]))
return img_convolution_normalization

def convolution(img,kernel,is_normalization=False):
dst = generate_dst(img,kernel)
convolution2dst(img,dst,kernel)
if not is_normalization:
return dst
else:
new_img = img2normalization_256(dst)
return new_img

img = np.array(plt.imread("../data/刘亦菲.jpg"))
test_kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]])
img_convolution = convolution(img,test_kernel, True)

# 显示直接卷积后的结果
plt.figure("刘大姐")
plt.imshow(img_convolution)
plt.axis("off")
plt.show()
print(img_convolution[0,0])

CNN卷积网络_图像处理_卷积_18

# 显示处理完的图像
img_convolution = img2normalization_256(img_convolution)
plt.figure("刘大姐")
plt.imshow(img_convolution)
plt.axis("off")
plt.show()

CNN卷积网络_图像处理_卷积_19

7、图像卷积处理之tensorflow

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
%matplotlib inline
'''
tf.nn.conv2d(input=, # 输入图像 [batch, height, width, channels]
filter=, # 卷积核,
strides=, # 步幅 一维向量,长度为4
padding, # 扩展 SAME表示在扫描的时候,如果遇到卷积核比剩下的元素要大时,这个时候需要补0进行最后一次的行扫描或者列扫描
use_cudnn # 启用cudnn加速
name) # 执行该操作name
'''

img = np.array([1]) # 读取图片,并转换为灰度图片
Image.open("../data/刘亦菲.jpg").convert('1') # 非黑即白
img = np.array(Image.open("../data/刘亦菲.jpg").convert('L')) # 0黑255白,其他数字灰度不同



img_full = np.reshape(img, [1, img.shape[0], img.shape[1], 1])
print(img_full.shape) # (1, 1200, 1920, 1)
#创建占位
input_full = tf.Variable(tf.constant(1.0, shape=img_full.shape))
# input_full = tf.Variable(img_R_full, dtype=tf.float32) # 可以直接输入

# 创建卷积核
filter_kernel = tf.Variable(tf.constant([#[1.0, 2, 1], [0, 0, 0], [-1, -2, -1] # 水平边缘滤波器
#[0, -4, 0], [-4, 16, -4], [0, -4, 0] # 整体边缘滤波器
# [1, 0, -1], [2, 0, -2], [1, 0, -1] # 垂直边缘滤波器
[-1,-1,-1],[-1,9,-1],[-1,-1,-1]
],
shape = [3,3,1, 1], dtype="float32")) # 3卷积核格式为3*3 输入通道1, 输出通道1

op = tf.nn.conv2d(input_full, filter=filter_kernel, strides=[1,1,1,1], padding="VALID") # SAME是自动填充, 这里选择不自动填充的VALID
o=tf.cast(((op-tf.reduce_min(op))/(tf.reduce_max(op)-tf.reduce_min(op)) ) *255 ,tf.uint8) # 归一化, 因为经过卷积后像素会有不在0-255范围内的

with tf.Session() as sess:
sess.run(tf.global_variables_initializer() )
conv_img = sess.run(o, feed_dict={ input_full:img_full})
print(conv_img.shape)

conv_img = conv_img.reshape([conv_img.shape[1], conv_img.shape[2]])
plt.imshow(conv_img, cmap="gray") # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()

(1, 1200, 1920, 1)
(1, 1198, 1918, 1)

CNN卷积网络_图像处理_ide_20




举报

相关推荐

0 条评论