我们首先要了解图像输出的size

(图源见图片右下角) (尽管上图已将valid、same、full说得很清楚了,但我还是画蛇添足再描述一下)

  • full,full嘛,全部的意思,将边界填充,使得,kernel四个角的像素点能与原图像的像素点刚好对应重合,output会变大
  • same,same嘛,相同的意思,原图像的四个角像素点与kernel中心像素点重合,output与原图一样大
  • valid,图片不需要填充,直接进行运算,会使图片变小

接下来再上手边界条件

这是原图:

ZeroPadding:


WrapAround


EdgeCopy


Reflect

为了减少代码冗余,我写了一个装饰器filterDecorator,在我写的函数boundaryZeroPaddingboundaryWrapAround中,留存了部分注释以帮助大家理解


# 为减少部分代码,定义装饰器函数
def filterDecorator(someFilter):'''someFilter : 传入的滤波器函数'''def inner(img, kernel_size, shape='same'):# 1.检查 shape 参数正确与否assert shape in ['full', 'same','valid'], "弟弟, shape参数填错了!"# 2.valid 情况无需填充if shape == 'valid':return img.copy()if shape == 'full':# k -> 2K 即和 'same' 一样kernel_size = np.array(kernel_size) * 2 - 1# 调用被装饰函数result_img = someFilter(img, kernel_size, 'same')return result_imgreturn inner# 全零填充函数
@filterDecorator
def boundaryZeroPadding(img, kernel_size, shape):'''img         :   要填充的imgkernel_size :   你kernel的形状,(先行后列)与kernel.shape顺序相反shape       :   填充的类型, 你懂得:full, same, valid返回值为 padding 后的图片'''
#    # -------------------------代码冗余,转至装饰器中----------------------------
#    # 检查 shape 参数正确与否
#    assert shape in ['full', 'same','valid'], "弟弟, shape参数填错了!"
#    if shape == 'valid':
#        # 此情况无需 padding
#        return img.copy()
#    # -------------------------代码冗余,转至装饰器中----------------------------# 获取图片的高,宽img_height, img_width = img.shape# 获得 K 值kx, ky = kernel_size[1]//2, kernel_size[0]//2if shape == 'same': # 不加 if 非常可# 左右需要填充的 zero# 此处必须加上 dtype=np.uint8,否则 cv2 float 显示全白zeros_array = np.zeros((img_height, kx), dtype=np.uint8)# 给图片左右两边添加 0img_copy = np.concatenate([zeros_array, img, zeros_array], axis=1)# 上下需要填充的 zerozeros_array = np.zeros((ky, 2*kx + img_width), dtype=np.uint8)# 给图片上下两边添加 0img_result = np.concatenate([zeros_array, img_copy, zeros_array], axis=0)return img_result#    # -------------------------代码冗余,转至装饰器中----------------------------
#    else:
#        # k -> 2K 即和 'same' 一样
#        kernel_size = np.array(kernel_size) * 2 - 1
#        return boundaryZeroPadding(img, kernel_size, 'same')
#    # -------------------------代码冗余,转至装饰器中----------------------------# 块复制,相当于搞一个周期函数
@filterDecorator
def boundaryWrapAround(img, kernel_size, shape):'''img         :   要填充的imgkernel_size :   你kernel的形状,(先行后列)与kernel.shape顺序相反shape       :   填充的类型, 你懂得:full, same, valid返回值为 WrapAround 后的图片'''# 获取图片的高,宽img_height, img_width = img.shape# 获得 K 值kx, ky = kernel_size[1]//2, kernel_size[0]//2'''块复制 位置分布定义, X为原图片E |     D     | F--------------------| 1 | 2 | 3 || - | - | - |A | 4 | X | 5 | B| - | - | - || 6 | 7 | 8 |--------------------G |     C     | H'''if shape == 'same': # 不加 if 非常可# 求上下part_D = img[-ky:]part_C = img[: ky]# part_A = img[:, -kx:]# part_B = img[:,  :kx]# 中间合并part_DXC = np.concatenate([part_D, img, part_C], axis=0)# 复制 DXC 的 右边part_EAG = part_DXC[:, -kx:]# 复制 DXC 的 左边part_FBH = part_DXC[:,  :kx]# 整体合并img_result = np.concatenate([part_EAG, part_DXC, part_FBH], axis=1)return img_result
#    # -------------------------代码冗余,转至装饰器中----------------------------
#    else:
#        # k -> 2K 即和 'same' 一样
#        kernel_size = np.array(kernel_size) * 2 - 1
#        return boundaryWrapAround(img, kernel_size, 'same')
#    # -------------------------代码冗余,转至装饰器中----------------------------# 边界复制,就是把边界拉出去
@filterDecorator
def boundaryEdgeCopy(img, kernel_size, shape):'''img         :   要填充的imgkernel_size :   你kernel的形状,(先行后列)与kernel.shape顺序相反shape       :   填充的类型,你懂得:full, same, valid返回值为 EdgeCopy 后的图片'''# 获取图片的高,宽img_height, img_width = img.shape# 获得 K 值kx, ky = kernel_size[1]//2, kernel_size[0]//2'''边界复制 位置分布 X为图片| 1 | 2 | 3 || - | - | - || 4 | X | 5 || - | - | - || 6 | 7 | 8 |'''if shape == 'same': # 不加 if 非常可# 求上下左右part_2 = np.concatenate([img[ 0].reshape(1, -1)]*ky, axis=0)part_7 = np.concatenate([img[-1].reshape(1, -1)]*ky, axis=0)part_4 = np.concatenate([img[:, 0].reshape(-1, 1)]*kx, axis=1)part_5 = np.concatenate([img[:,-1].reshape(-1, 1)]*kx, axis=1)# 求四个角# 此处必须加上 dtype=np.uint8,否则 cv2 float 显示全白part_1 = np.ones(shape=(kx, ky), dtype=np.uint8) * img[0,0]part_3 = np.ones_like(part_1, dtype=np.uint8) * img[0, -1]part_6 = np.ones_like(part_1, dtype=np.uint8) * img[-1, 0]part_8 = np.ones_like(part_1, dtype=np.uint8) * img[-1,-1]# 三列合并part_146 = np.concatenate([part_1, part_4, part_6], axis=0)part_2X7 = np.concatenate([part_2, img   , part_7], axis=0)part_358 = np.concatenate([part_3, part_5, part_8], axis=0)# 整体合并img_result = np.concatenate([part_146, part_2X7, part_358], axis=1)return img_result# 边界镜像对称函数
@filterDecorator
def boundaryReflect(img, kernel_size, shape):'''img         :   要填充的imgkernel_size :   你kernel的形状,(先行后列)与kernel.shape顺序相反shape       :   填充的类型返回值为 Reflect 后的图片'''# 获取图片的高,宽img_height, img_width = img.shape# 获得 K 值kx, ky = kernel_size[1]//2, kernel_size[0]//2'''镜像对称 位置分布定义, X为原图片E |     D     | F--------------------| 1 | 2 | 3 || - | - | - |A | 4 | X | 5 | B| - | - | - || 6 | 7 | 8 |--------------------G |     C     | H'''if shape == 'same': # 不加 if 非常可# 先通过堆成求 DCpart_D = img[(ky-1)::-1, :]part_C = img[-1:-(ky+1):-1, :]# DC 与 X 合并part_DXC = np.concatenate([part_D, img, part_C], axis=0)# 通过对称求 EAG 和 FBHpart_EAG = part_DXC[:, (kx-1)::-1]part_FBH = part_DXC[:, -1:(-kx-1):-1]# 合并img_result = np.concatenate([part_EAG, part_DXC, part_FBH], axis=1)return img_result

图像处理四种边界条件Python轮子实现——ZeroPadding、WrapAround、EdgeCopy、Reflect(同时应对各种size——valid、same、full)相关推荐

  1. 【深度学习】深度学习中模型计算量(FLOPs)和参数量(Params)等的理解以及四种在python应用的计算方法总结

    接下来要分别概述以下内容: 1 首先什么是参数量,什么是计算量 2 如何计算 参数量,如何统计 计算量 3 换算参数量,把他换算成我们常用的单位,比如:mb 4 对于各个经典网络,论述他们是计算量大还 ...

  2. python 调用linux命令-四种执行python系统命令的方法

    Python中执行系统命令常见的几种方法有 注意:以下实例代码在Python3.5下运行通过. 一.os.system方法 os.system(cmd) 在子终端运行系统命令,可以获取命令执行后的返回 ...

  3. 用四种方法Python求出两个有序数组中的中位数

    方法一: def median_1(A, B):# 思路一: 先组合成一个有序数列,再取中位数# 时间复杂度O(m+n)len_A = len(A)len_B = len(B)C = []if len ...

  4. [Python图像处理] 四十二.Python图像锐化及边缘检测万字详解(Roberts、Prewitt、Sobel、Laplacian、Canny、LOG)

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  5. 万字长文告诉新手如何学习Python图像处理(上篇完结 四十四) | 「Python」有奖征文

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  6. 【数字图像处理】四种常用的滤波器

    数字图像处理 四种常用滤波器 数字图像处理 一.平滑滤波器 1.1 基本原理 1.2 作用 1.3 邻域加权平均实现方式 二.高斯滤波器 2.1 基本原理 2.2 特点 三.中值滤波器 3.1 基本原 ...

  7. 图像处理/计算机视觉/python环境下/如何用四种不同滤波器处理噪声【附代码、亲测有效】

    计算机视觉实操之图像处理 一.问题描述 二.效果图 三.代码附录 四.相关链接 一.问题描述 向图片中分别加入椒盐噪声.高斯噪声,使用四种不同的滤波器观察图片的处理效果(算术均值滤波.几何均值滤波 . ...

  8. python图像处理库ImageEnhance实现图像的亮度、对比度、色度和锐度四种方式增强

    python中PIL模块中有一个叫做ImageEnhance的类,该类专门用于图像的增强处理,可以实现图像的亮度.对比度.色度和锐度四种方式的增强(或减弱)处理. 具体见下面的例子: # -*- co ...

  9. Perl,Python,Ruby,Javascript 四种脚本语言比较

    Perl 为了选择一个合适的脚本语言学习,今天查了不少有关Perl,Python,Ruby,Javascript的东西,可是发现各大阵营的人都在吹捧自己喜欢的语言,不过最没有争议的应该是Javascr ...

最新文章

  1. 前端临床手扎——简单易用的fetch
  2. 高通平台MSM8916LCM模块移植(一)-bootloader部分
  3. C++ 类型转换(强制类型转换)
  4. struts2文件上传(2)
  5. 牛客 - 双流机场(思维)
  6. 【OJ】华东师范大学Python程序设计OJ题解
  7. win10 + VS2015 + EF6 + MySQL
  8. Cocos2dx 小技巧(十五)话说ScrollView的delegate实现过程
  9. 微信分享#后面被截断,导致安卓分享失效
  10. Tortoise svn 基础知识
  11. HDU 4031 Attack
  12. Visual Studio 2012下载安装方法
  13. maxscale mysql5.7_Centos7安装maxscale 实现mysql的读写分离
  14. NLTK-006:分类文本(性别鉴定)
  15. 2013年度中国优秀开源项目入围奖
  16. delphi oracle 分页,使用原生ADO对数据进行分页显示delphi数据库操作下载
  17. PS网页设计教程XVII——在Photoshop中设计创意组合网页
  18. 低功耗设计(low power design)和UPF介绍(含代码示例)
  19. Oracle获取年月日时分秒毫秒微秒
  20. vue vant优惠券使用

热门文章

  1. android电视root权限获取,电视盒子/ 智能电视如何通过ADB获取ROOT权限?
  2. 值得看两遍,解决99%的文件搜索难题!
  3. 推动门html5,白鹭引擎CEO陈书艺:推动游戏前行 开启HTML5游戏之门
  4. 笔记——C51的LCD1602屏幕显示
  5. 程序员如何成长设计师,软件公司如何成为苹果
  6. 案例:中科润泽鞋业专用ERP(CRS-ERP)在东艺鞋业的成功实施(转)
  7. OffsetRect的使用
  8. 截取嵌入网页的一部分
  9. 最值得关注的八家创业公司
  10. 三极管应用电路实例讲解(配参数分析)