第11章:图像金字塔

第11章:图像金字塔

    • 一、理论基础:
      • 1. 向下采样:
      • 2. 向上采样:
    • 二、pyrDown函数使用:
    • 三、pyrUp函数及使用:
    • 四、采样可逆性研究
    • 五、拉普拉斯金字塔
      • 1. 定义:
      • 2. 应用:

什么是图像金子塔?

​ 图像金字塔是由一幅图像的多个不同分辨率的子图构成的图像集合。是通过一个图像不断的降低采样率产生的,最小的图像可能仅仅有一个像素点。下图是一个图像金子塔的示例。从图中可以看到,图像金字塔是一系列以金字塔形状排列的、自底向上分辨率逐渐降低的图像集合。

image-20211103135027005

​ 通常情况下,图像金字塔的底部是待处理的高分辨率图像(原始图像),而顶部则为其低分辨率的近似图像。向金字塔顶部移动时,图像的尺寸和分辨率都不断地降低。通常情况下,每向上移动一级,图像的宽和高都降低为原来的二分之一。

一、理论基础:

图像金字塔是同一图像不同分辨率的子图集合,是通过原图像不断地向下降低采样而产生的,即由高分辨率的图像(大尺寸)产生低分辨率的近似图像(小尺寸)。

1. 向下采样:

​ 最简单的图像金字塔可以通过不断的删除图像的偶数行和偶数列得到的。例如,有一幅图像,其大小是N*N,删除其偶数行和偶数列后得到一幅(N/2)*(N/2)大小的图像。经过上述处理后,图像的大小变为原来的四分之一,不断重复该过程,就可以得到该图像的图像金字塔。

​ 也可以通过先对原始图像滤波,得到原始图像的近似图像,然后将近似图像的偶数行和偶数列删除以获取向下采样的结果。有多种滤波器可以选择。

  • 领域滤波器:采用邻域平均值计算求原始图像的近似图像。该滤波器能够产生平均金字塔。

  • 高斯滤波器:采用高斯滤波器对原始图像进行滤波,得到高斯金字塔。这是OpenCV函数cv2.pyrDown()所采用的的方式。

    高斯金字塔是通过不断地使用高斯金字塔滤波、采样所产生的,其过程如下:

    image-20211103141432789

​ 经过上述处理后,原始图像与各次向下采样所得到的结果图像共同构成了高斯金字塔。例如,可以将原始图像称为第0层,第1次向下采样的结果图像称为第一层、第2次向下采样的结果图像称为第2层,以此类推。上述图像所构成的高斯金字塔如图所示。

image-20211103141930222

​ 下面为了表述统一,我们一律将图像金字塔中底层称为第0层,底层上面一层称为第1层,并以此类推。

2. 向上采样:

​ 在向上采样的过程中,通常将图像的宽度和高度都变为原来的2倍。这意味着,向上采样的结果图像的大小是原始图像的4倍。因此,要在结果图像中补充大量的像素点。对新生成的像素点进行赋值的行为,称为 插值。该过程可以通过多种方式实现,例如最邻近插值就是使用最邻近的像素点给当前还没有值的像素点赋值。

​ 还有一种常见的向上采样,对像素点以补零的方式完成插值。通常是在每列像素点的右侧插入值为零的列,在每行像素点的下方插入值为零的行。如图,左侧是要进行向上采样的4个像素点,右侧是向上采样时进行补零后处理结果。

image-20211103142850912

​ 接下来,使用向下采样时所使用的的高斯滤波器对补零后的图像进行滤波处理,以获取向上采样的结果图像。 但是需要注意,此时图像中有四分之三的像素点的值都是零。所以,要将高斯滤波器系数乘以4,以保证得到的像素值在其原有像素值的范围内。

​ 例如,针对上图右侧的像素点,其对应的是8位图像,像素值的范围是[0, 255]。由于其中四分之三的像素点的值都是为零,如果直接使用高斯滤波器对其进行卷积计算,会导致像素值的范围变为[0, 255*1/4]。所以,要将所使用的高斯滤波器系数乘以4,以保证得到像素值的范围仍旧在[0, 255]内。

​ 或者,从另一个角度理解,在原始图像内每个像素点的右侧列插入零值列,在每个像素点的下一行插入零值行,将图像变为原来的两倍宽、两倍高。接下来,将补零后的图像用高斯滤波器进行卷积运算。最后,将图像内每个像素点的值乘以4,以保证像素值的范围与原始图像一致。

​ 通过以上分析可知,向上采样和向下采样是相反的两种操作。但是,由于上下采样会丢失像素值,所以两种操作并不是可逆的。 也就是说,对一幅图像先向上采样、再向下采样,是无法恢复期原始状态的;同样,对一幅图像先向下采样、再向上采样也是无法恢复到原始状态的。

二、pyrDown函数使用:

在OpenCV中使用函数cv2.pyrDown(),实现图像高斯金字塔操作中的向下采样,语法形式为:

dst = cv2.pyrDown(src [, dstsize [, borderType] ])

  • dst:目标图像
  • src:原始图像
  • dstsize:目标图像的大小
  • borderType:边界类型,默认值为BORDER_DEFAULT,且这里仅支持BORDER_DEFAULT。

默认情况下,输出图像的大小为Size((src.cols+1)/2, (src.rows+1)/2)。在任何情况下,图像的尺寸必须满足如下条件:

  • |dst.width * 2 - src.cols| ≤ 2

    |dst.height * 2 - src.rows| ≤ 2

cv2.pyrDown()函数首先对原始图像进行高斯滤波变换,以获取原始图像的近似图像。在获取近似图像后,该函数通过抛弃偶数行和偶数列来实现向下采样。

示例:

import cv2img = cv2.imread('../lena.bmp')
rst1 = cv2.pyrDown(img)
rst2 = cv2.pyrDown(rst1)
rst3 = cv2.pyrDown(rst2)print('img.shape=', img.shape)
print('rst1.shape=', rst1.shape)
print('rst2.shape=', rst2.shape)
print('rst3.shape=', rst3.shape)cv2.imshow('img', img)
cv2.imshow('rst1', rst1)
cv2.imshow('rst2', rst2)
cv2.imshow('rst3', rst3)cv2.waitKey()
cv2.destroyAllWindows()# 输出结果
img.shape= (512, 512, 3)
rst1.shape= (256, 256, 3)
rst2.shape= (128, 128, 3)
rst3.shape= (64, 64, 3)

image-20211103153007877

三、pyrUp函数及使用:

在OpenCV中,使用函数cv2.pyrUp()实现图像金字塔操作中的向上采样,其语法格式为:

dst = cv2.pyrUp(src, [, dstsize [, borderType ] ] )

  • dst:目标图像
  • src:原始图像
  • dstsize:目标图像的大小
  • borderType:边界类型,默认值为BORDER_DEFAULT,且这里仅支持BORDER_DEFAULT。

默认情况下,输出图像的大小为Size(src.cols*2, src.rows*2)。在任何情况下,图像的尺寸必须满足如下条件:

  • |dst.width - src.cols * 2| ≤ mod(dst.widh, 2)

    |dst.height - src.rows * 2| ≤ mod(dst.height, 2)

​ 在使用cv2.pyrUp()函数对图像向上采样时,在每个像素的右侧、下方分别插入零值列和零值行,得到一个偶数行、偶数列(即新增的行、列)都是零值的新图像New。接下来,用向下采样时所使用的高斯滤波器对新图像New进行滤波,得到向上采样的结果图像。需要注意的是,为了确保像素值的区间在向上采样后与原始图像保持一致,需要将高斯滤波器的系数乘以4。

示例:

import cv2img = cv2.imread('../boat.512.tiff')
rst1 = cv2.pyrUp(img)
rst2 = cv2.pyrUp(rst1)
rst3 = cv2.pyrUp(rst2)print('img.shape=', img.shape)
print('rst1.shape=', rst1.shape)
print('rst2.shape=', rst2.shape)
print('rst3.shape=', rst3.shape)cv2.imshow('img', img)
cv2.imshow('rst1', rst1)
cv2.imshow('rst2', rst2)
cv2.imshow('rst3', rst3)cv2.waitKey()
cv2.destroyAllWindows()# 输出结果
img.shape= (64, 64, 3)
rst1.shape= (128, 128, 3)
rst2.shape= (256, 256, 3)
rst3.shape= (512, 512, 3)

image-20211103162317850

四、采样可逆性研究

​ 图像在向上采样后,整体尺寸变为原来的4倍;在向下采样后,整体尺寸变为原来的四分之一。下图展示了图像在采样前后的大小变化关系。一幅M*N大小的图像经过向下采样后大小会变为(M/2)*(N/2);一幅M*N大小的图像经过向上采样后大小会变为(2M)*(2N)

​ 虽然一幅图像在先后经过向下采样、向上采样后,会恢复原始大小,但是向上采样和向下采样不是互逆的。也就是说,虽然在经历两次采样操作后,得到的结果图像与原始图像的大小一致,肉眼看起来也相似,但是二者的像素并不是一致的。

示例:

import cv2img = cv2.imread('../boat.512.tiff')down = cv2.pyrDown(img)
up = cv2.pyrUp(down)
diff = up - img
print('img.shape=', img.shape)
print('down.shape=', up.shape)
cv2.imshow('img', img)
cv2.imshow('up', up)
cv2.imshow('diff', diff)
cv2.waitKey()
cv2.destroyAllWindows()# 输出结果
img.shape= (512, 512, 3)
down.shape= (512, 512, 3)

image-20211103164347143

五、拉普拉斯金字塔

​ 前面所介绍的高斯金字塔,是通过对一幅图像一系列的向下采样所产生的。有时,我们希望通过对金字塔中的小图像进行向上采样以获取完整的大尺寸高分辨率图像,这时就需要用到拉普拉斯金字塔。

1. 定义:

​ 一幅图像在经过向下采样后,在对其进行向上采样,是无法恢复为原始状态的。对此,我们也用程序进行了验证。向上采样并不是向下采样的逆运算。这很明显,因为向下采样时在使用高斯滤波器处理后还要抛弃偶数行,偶数列,不可避免的要丢失一些信息。

为了在向上采样是能够恢复具有较高分辨率的原始图像,就要获取在采样过程中所丢失的信息,这些丢失的信息就构成了拉普拉斯金字塔。 也是拉普拉斯金字塔是有向下采样时丢失的信息构成。

拉普拉斯金字塔的定义形式为:

  • Li = Gi - pyrUp( Gi + 1 )

式中:

  • Li:表示拉普拉斯金字塔中的第i层
  • Gi:表示高斯金字塔中的第i层

​ 拉普拉斯金字塔中的第i层,等于"高斯金字塔中的第i层"与"高斯金字塔中的第 i + 1层的向上采样结果"之差。下图展示了高斯金字塔和拉普拉斯金字塔的对应关系。

image-20211104141957761

示例:使用cv2.pyrDown()和cv2.pyrUp()构造拉普拉斯金子塔

import cv2img = cv2.imread('../boat.512.tiff')
G1 = cv2.pyrDown(img)
G2 = cv2.pyrDown(G1)
G3 = cv2.pyrDown(G2)L0 = img - cv2.pyrUp(G1)
L1 = G1 - cv2.pyrUp(G2)
L2 = G2 - cv2.pyrUp(G3)print('L0.shape=', L0.shape)
print('L1.shape=', L1.shape)
print('L2.shape=', L2.shape)cv2.imshow('L0', L0)
cv2.imshow('L1', L1)
cv2.imshow('L2', L2)
cv2.waitKey()
cv2.destroyAllWindows()# 输出结果
L0.shape= (512, 512, 3)
L1.shape= (256, 256, 3)
L2.shape= (128, 128, 3)

image-20211104142942584

2. 应用:

拉普拉斯金字塔的作用在于,能够恢复高分辨率的图像。下图演示了如何通过拉普拉斯金字塔恢复高分辨率图像。

image-20211104143448105

图中各标记含义如下:

  • G0、G1、G2、G3分别是高斯金字塔的第0层、第1层、第2层、第3层。
  • L0、L1、L2、分别是拉普拉斯金字塔的第0层、第1层、第2层。
  • 向下的箭头表示向下采样操作(对应cv2.pyrDown()函数)
  • 向右的箭头表示向上采样操作(对应cv2.pyrUp() 函数)
  • "+"表示加法操作
  • "-"表示减法操作

上图中的操作关系有:

向下采样:

  • G1 = cv2.pyrDown(G0)
  • G2 = cv2.pyrDown(G1)
  • G3 = cv2.pyrDown(G2)

拉普拉斯金字塔:

  • L0 = G0 - cv2.pyrUp(G1)
  • L1 = G1 - cv2.pyrUp(G2)
  • L2 = G2 - cv2.pyrUp(G3)

向上采样恢复高分辨率图像:

  • G0 = L0 + cv2.pyrUp(G1)
  • G1 = L1 + cv2.pyrUp(G2)
  • G2 = L2 + cv2.pyrUp(G3)

上述关系是通过数学运算推导得到的。例如,已知L0=G0-cv2.pyrUp(G1),将表达式右侧的cv2.pyrUp(G1)移到左侧,就得到了表达式G0 = L0 + cv2.pyrUp(G1)。除此之外,G1和G2都可以通过拉普拉斯金字塔的构造表达式得到。如之前介绍的,拉普拉斯金字塔的目的就是为了恢复高分辨率的图像。

示例:使用拉普拉斯金字塔恢复高分辨率的图像

import cv2
import numpy as npimg = cv2.imread('../boat.512.tiff')G0 = img
G1 = cv2.pyrDown(G0)
G2 = cv2.pyrDown(G1)
G3 = cv2.pyrDown(G2)L0 = G0 - cv2.pyrUp(G1)
L1 = G1 - cv2.pyrUp(G2)
L2 = G2 - cv2.pyrUp(G3)rst_G0 = L0 + cv2.pyrUp(G1)
rst_G1 = L1 + cv2.pyrUp(G2)
rst_G2 = L2 + cv2.pyrUp(G3)print('rst_G0', np.sum(abs(G0 - rst_G0)))
print('rst_G1', np.sum(abs(G1 - rst_G1)))
print('rst_G2', np.sum(abs(G2 - rst_G2)))cv2.imshow('G0', G0)
cv2.imshow('G1', G1)
cv2.imshow('G2', G2)cv2.imshow('rst_G0', rst_G0)
cv2.imshow('rst_G1', rst_G1)
cv2.imshow('rst_G2', rst_G2)cv2.waitKey()
cv2.destroyAllWindows()

image-20211104145537252

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【树莓派学习笔记】七、(免费)内网穿透将树莓派作为服务器管理网站

目录nginx安装开机自启动测试查看nginx安装路径查看配置文件路径(测试用)修改index.nginx-debian.html内网穿透免费方案ngrok原版方案下载ngrok连接账户开启内网穿透httpSSH网云穿方案开通隧道下载开启内网穿透开机自启动花生壳方案下载和安装添加内网穿透映射测试平台&#xf…

第12章:图像轮廓

第12章:图像轮廓一、查找并绘制轮廓:1. 查找图像轮廓:2. 绘制图像轮廓:3. 绘制轮廓实例:二、矩特征1. 矩的计算:moments函数2. 计算轮廓面积:contourArea函数3. 计算轮廓长度:arcLen…

【树莓派学习笔记】八、两步安装VS Code (Visual Studio Code)

目录下载安装使用(可选)安装插件C/CCMake ToolsCode Runner平台:树莓派3B 版本: 2021-05-07-raspios-buster-armhf 下载 官网下载 Download Visual Studio Code 发送到树莓派 安装 sudo dpkg -i Desktop/code_1.60.2-1632316275_armhf.deb 使用 在…

20 best jquery 截图

digguka, January 05, 2012jQuery Image Crop - A very useful list of tools for cropping, zooming and resizing of images. Some of plugins come with the ability to upload croped images. 转载于:https://www.cnblogs.com/yqskj/archive/2013/05/25/3098411.html

【RK3399Pro学习笔记】一、Thinker Edge R 安装系统和VNC服务

目录下载固件安装USB驱动下载烧录工具刷机第一次开机连接WifiSSH登录换源设置语言安装VNC服务平台:华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本:Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 风火轮论坛资料网盘 提取码:wqbd 下载固件…

第13章:直方图处理

第13章:直方图处理一、直方图的含义:1. 普通直方图:2. 归一化直方图:二、绘制直方图:1. 使用Numpy绘制直方图:2. 使用OpenCV绘制直方图:3. 使用掩码绘制直方图:三、直方图均衡化&…

操作系统 内存管理篇

一.程序的装入和链接 装入方式: 链接方式: 二.进程的内存映像 三.内存的分配 1.连续分配 分配方式: 2.不连续分配 分页:页面大小一致 引入快表(和 cache 处理思路一致) 升级到二级页表 分段:…

【RK3399Pro学习笔记】二、Thinker Edge R 内网穿透以实现远程SSH

目录免费方案花生壳下载安装添加内网穿透映射测试平台:华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本:Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 因Thinker Edge R安装的镜像为64位的版本 getconf LONG_BIT免费方案 花生壳 下载 在花生壳下载…

第14章:傅里叶变换

第14章:傅里叶变换一、理论基础:二、Numpy实现傅里叶变换:1. 实现傅里叶变换:2. 逆傅里叶变换:3. 高通滤波示例:三、OpenCV实现傅里叶变换:1. 实现傅里叶变换:2. 实现逆傅里叶变换&a…

代码能不能不要写得这么烂?!

我是一个研二的即将实习和毕业的普通屌丝研究生,带着几个研一的同学一起做数据挖掘项目。为了在毕业的时候防止青黄不接导致老师不让我毕业,于是从他们刚进实验室起,就“开始了设计模式和代码风格的培养”。具体的做法,就是扔给他…

【Kali 树莓派版学习笔记】安装系统和VNC服务

目录下载固件和烧录系统第一次开机SSH连接换源设置语言安装VNC平台:树莓派3B 版本: Linux kali 5.4.83-Re4son-v7 #1 SMP Sat May 15 03:22:58 UTC 2021 armv7l GNU/Linux 下载固件和烧录系统 Get Kali 格式化TF卡 使用Win32DiskImager刷入镜像 第…

第15章:模板匹配

第15章:模板匹配一、模板匹配基础:1. cv2.matchTemplate()函数:2. 匹配原理:3. 查找最值:二、多模版匹配:1. 获取匹配位置集合:2. 循环:3.调整坐标4.标记匹配图像的位置​ 模板匹配是…

第16章:霍夫变换

第16章:霍夫变换一、霍夫直线变换:1. 霍夫直线变换原理:2. HoughLines函数:3. HoughLinesP函数:2. 霍夫圆环变换:霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。霍夫变换采用类似于投票的方…

一个java处理JSON格式数据的通用类(三)

/** *//** * 从json数组中解析出java Integer型对象数组 * param jsonString * return */ public static Double[] getDoubleArray4Json(String jsonString)...{ JSONArray jsonArray JSONArray.fromObject(jsonString); Doubl…

【树莓派学习笔记】九、C语言寄存器操作控制GPIO

目录CPU型号确定寄存器的地址问题GPIO寄存器GPFESLnGPSETnGPCLRn重要函数mmap函数munmap函数点灯程序平台:树莓派3B 版本: 2021-05-07-raspios-buster-armhf CPU型号确定 由 pinout命令可知,所用的板子Soc型号为BCM2837 寄存器的地址问题…

bzoj2527

首先环可以变成链来处理,对于l>r的情况就是修改区间[1,r],[l,mx]然后不难想到整体二分,二分答案k,然后算1~k场流星雨对国家的贡献然后判定将国家划分变成子问题解决,没什么难的终于不是tle,poi良心了一把 1 type wayrecord2 …

第17章:图像分割提取

第17章:图像分割提取一、用分水岭算法实现图像分割提取:1. 算法原理:2. 相关函数介绍:(1) 形态学函数回顾:(2) 距离变换函数distanceTransform:(3) 确定未知区域:(4) 函数connectedComponents对…

[转]可伸缩系统的架构经验

最近,阅读了Will Larson的文章Introduction to Architecting System for Scale,感觉很有价值。作者分享了他在Yahoo!与Digg收获的设计可伸缩系统的架构经验。在我过往的架构经验中,由于主要参与开发企业软件系统,这种面向企业内部…

【Linux技巧】cmake、make命令多线程编译,大大提高编译速度

目录获取最大可用线程数自动以最大线程数编译makecmake效果系统:Debian 获取最大可用线程数 nprocnproc命令可返回当前可用的最大线程数 树莓派3B (BCM2837):4 RK3399 Pro:6 自动以最大线程数编译 make sudo make -j $(nproc)cmake su…

redis学习(九)——数据持久化

一、概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的。所以,我们需要将内存中的数据持久化!典型的需要持久…