深度学习基础——图像卷积操作二维、三维(python)

参考:【深度学习入门】——亲手实现图像卷积操作

基础知识见参考链接

直接记录编程实践部分:

二维卷积

import numpy as np
import matplotlib.pyplot as plt

输入测试图片:

srcImg = plt.imread('./lena.jpg')

构建一个 3 x 3 的卷积核:

test_kernel = np.array([[-1,-1,-1],
                       [-1,9,-1],
                       [-1,-1,-1]])

构建输出图片的图像矩阵函数:

def generate_dst(srcImg):
    """
    srcImg:输入图像,512*512*3
    输出图像矩阵计算公式:
    l=(m−k)/stride+1
    c=(n−k)/stride+1
    stride =1
    
    output:输出图片的图像矩阵
    """
    m = srcImg.shape[0]
    n = srcImg.shape[1]
    n_channel = srcImg.shape[2]

    dstImg = np.zeros((m-test_kernel.shape[0]+1,n-test_kernel.shape[0]+1,n_channel ))
    return dstImg

构建输出图片的数据结构函数:

def conv_2d(src,kernel,k_size):
    """
    二维卷积:构建输出图片的数据结构
    
    src:输入图像
    kernal:卷积核
    k_size:卷积核大小,3
    
    """
    dst = generate_dst(src)
    print (dst.shape)
    
    conv(src,dst,kernel,k_size)
    
    return dst

构建卷积函数 :

def  conv(src,dst,kernel,k_size):
    """
    卷积:滑动卷积核重复
    最里面的嵌套:对每一个颜色通道都需要进行卷积操作
    
    """
    for i in range(dst.shape[0]):
        for j in range(dst.shape[1]):
            for k in range(dst.shape[2]):
                
                value = _con_each(src[i:i+k_size,j:j+k_size,k],kernel)
                
                dst[i,j,k] = value

使用sigmod激活函数对卷积后的数值进行操作 ,得到一个新的输出:

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

构建具体卷积操作函数:

def _con_each(src,kernel):
    """
    逐元素相乘,累计相加的操作,最终的数值求平均
    src_block:输入图片上截取下来的像素块,尺寸同卷积核一样  
    src[i:i+k_size,j:j+k_size,k] :从原数组中截取起始坐标为 (i,j),宽高都为 k_size 的数据块。
    RGB 模式中,数值的取值范围是 0 ~ 255
    小于 0 时,像素值取 0,大于 255 时取 255,其它情况保持现值
    """
    pixel_count = kernel.size
    pixel_sum = 0
    _src = src.flatten()
    _kernel = kernel.flatten()
    
    
    for i in range(pixel_count):
        pixel_sum += _src[i]*_kernel[i]
        
    value = pixel_sum / pixel_count
    value = value if value >0  else 0
    value = value if value < 255 else 255
    value = sigmoid(value)
    
    return value

构建测试函数:

def  test_conv(src,kernel,k_size):
    plt.figure()
    #121   1 代表 1行,2 代表 2 列,最后的 1 代表 图片显示在第一行第一列
    plt.subplot(121)
    plt.imshow(src)
    
    dst = conv_2d(src,kernel,k_size)
    #121   1 代表 1行,2 代表 2 列,最后的 2 代表 图片显示在第一行第发给列
    plt.subplot(122)
    plt.imshow(dst)
    
    plt.show()

测试用例:

test_conv(srcImg,test_kernel,3)

输出结果:

三维卷积

参考:【深度学习】多通道图像卷积过程及计算方式

import numpy as np
import matplotlib.pyplot as plt

def _conv_epoch(src_block,filter):
    input = src_block.flatten()
    filter = filter.flatten().T

    return np.dot(input,filter) #矩阵内积先累乘再累加,与卷积的过程一样

构建完整的图像卷积函数:

def conv(img,input_size,filter_size,stride=1):
    """
    
    完整的图像卷积
    
    input_size:(h,w,c)
    filter_size:(h,w,ic,oc)
    
    """
    ih = input_size[0]
    iw = input_size[1]
    ic = input_size[2]

    filter_h = filter_size[0]
    filter_w = filter_size[1]
    filter_ic = filter_size[2]
    filter_oc = filter_size[3]

    l = int((ih - filter_h) / stride + 1)
    m = int((iw - filter_w) / stride + 1)

    result = np.zeros(shape=(l,m,filter_oc),dtype=np.uint8)

    for i in range(l):
        for j in range(m):
            for k in range(filter_oc):
                f = np.random.uniform(0,1,filter_w*filter_h*filter_ic).T
                input = img[i:i+filter_h,j:j+filter_w,:]
                #if i == 1 and j == 1 and k == 1:
                #    print(f)
                #    print(input)
                result[i,j,k] = _conv_epoch(input,f)

    return result

三维卷积函数相当于把二维卷积里面的几个函数规整在一个函数中了。

测试用例:

def test():
    img = plt.imread("./cat.jpg")

    print("img shape ",img.shape)

    result = conv(img,img.shape,(3,3,img.shape[2],3))

    plt.figure()
    plt.subplot(121)
    plt.imshow(img)
    plt.subplot(122)
    plt.imshow(result)
    plt.show()

test()

输出结果:

补充及总结:

明白啦!下班前向老师请教了一下!filter_size是四维数据,分别是filter_h、filter_w、filter_ic、filter_oc,前两者是滤波器的高度和宽度,第三个事滤波器的输入通道数,应该与上层图片的通道数相同,最后一个是滤波器的输出通道数,也就是滤波器的数量。

 比如这个图是指三维卷积的滤波过程,三维卷积之后,有4个filter,所以在这里filter_oc=4

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值