• 售前

  • 售后

热门帖子
入门百科

Python OpenCV高斯金字塔与拉普拉斯金字塔的实现

[复制链接]
哦也X5 显示全部楼层 发表于 2021-10-26 13:10:34 |阅读模式 打印 上一主题 下一主题
基础知识铺垫

学习图像金字塔,发现网上的资料比力多,检索起来比力轻松。
图像金字塔是一张图像多尺度的表达,或者可以明白成一张图像不同分辨率展示。
金字塔越底层的图片,像素越高,越向上,像素逐步低落,分辨率逐步低落。
高斯金字塔

我们仍然不对概念做过多表明,第一遍学习应用,应用,究竟 365 天的周期,时间长,背面补充理论知识。
高斯金字塔用于向下采样,同时它也是最基本的图像塔。
在互联网检索原理,得到最简单的阐明如下:
将图像的最底层(高斯金字塔的第 0 层),比方高斯核(5x5)对其进行卷积操作,这里的卷积重要处置处罚掉的是偶数行与列,然后得到金字塔上一层图像(即高斯金字塔第 1 层),在针对该图像重复卷积操作,得到第 2 层,反复执行下去,即可得到高斯金字塔。
每次操作之后,都会将 M×N 图像变成 M/2 × N/2 图像,即减少一半。
还有实测中发现,需要用图像的宽和高一致的图片,并且宽高要是 2 的次幂数,比方,8 像素,16 像素,32 像素等等,一会你也可以实际测试一下。
图像金字塔应用到的函数有
  1. <kbd>cv2.pyrDown()</kbd>
复制代码
  1. <kbd>cv2.pyrUp() </kbd>
复制代码

cv2.pyrDown 与 cv2.pyrUp 函数原型

通过 help 函数得到函数原型如下:
  1. pyrDown(src[, dst[, dstsize[, borderType]]]) -> dst
  2. pyrUp(src[, dst[, dstsize[, borderType]]]) -> dst
复制代码
两个函数原型参数一致,参数阐明如下:
      
  • src:输入图像;  
  • dst: 输出图像;  
  • dstsize: 输出图像尺寸,默认值按照
    1. ((src.cols+1)/2, (src.rows+1)/2)
    复制代码
    盘算。
关于两个函数的补充阐明:
      
  • cv2.pyrDown 从一个相对高分辨率的大尺寸的图像上构建一个金字塔,运行之后的效果是,图像变小,分辨率低落(下采样);  
  • cv2.pyrUp 是一个上采样的过程,只管相对尺寸变大,但是分辨率不会增长,图像会变得更暗昧。
测试代码如下:
  1. import cv2 as cv
  2. src = cv.imread("./testimg.jpeg")
  3. print(src.shape[:2])
  4. cv.imshow("src", src)
  5. # 向下采样
  6. dst = cv.pyrDown(src)
  7. print(dst.shape[:2])
  8. cv.imshow("dst", dst)
  9. # 再次向下采样
  10. dst1 = cv.pyrDown(dst)
  11. print(dst1.shape[:2])
  12. cv.imshow("dst1", dst1)
  13. cv.waitKey()
复制代码
运行代码之后,得到三张图片,大小依次减小,分辨率低落。


通过上面运行得到的最小图,在执行向上采样之后,图片会变的暗昧,这也阐明上采样和下采样是非线性处置处罚,它们是不可逆的有损处置处罚,因此下采样后的图像是无法还原的,纵然放大图片也会变暗昧(背面学习到拉普拉斯金字塔可以办理该问题)。
  1. # 向上采样
  2. dst2 = cv.pyrUp(dst1)
  3. print(dst2.shape[:2])
  4. cv.imshow("dst2", dst2)
复制代码


在总结一下上采样和下采样的步调:

      
  • 上采样:使用 cv2.pyrUp 函数, 先将图像在每个方向放大为原来的两倍,新增的行和列用 0 添补,再使用先前同样的内核与放大后的图像卷积,获得新增像素的近似值;  
  • 下采样:使用 cv2.pyrDown 函数,先对图像进行高斯内核卷积 ,再将所有偶数行和列去除。
拉普拉斯金字塔(Laplacian Pyramid, LP)

拉普拉斯金字塔重要用于重修图像,由上文我们已经知道在使用高斯金字塔的的时候,上采样和下采样会导致图像细节丢失。
拉普拉斯就是为了在放大图像的时候,可以推测残差,何为残差,即小图像放大的时候,需要插入一些像素值,在上文直接插入的是 0,拉普拉斯金字塔算法可以根据四周像素进行推测,从而实现对图像最大水平的还原。
学习到原理如下:用高斯金字塔的每一层图像,减去其上一层图像上采样并高斯卷积之后的推测图像,得到一系列的差值图像即为 LP 分解图像(此中 LP 即为拉普拉斯金字塔图像)。
关于拉普拉斯还存在一个公式(这是本系列课程第一次誊写公式),此中 L 为拉普拉斯金字塔图像,G 为高斯金字塔图像

使用下面的代码进行测试。
  1. import cv2 as cv
  2. src = cv.imread("./testimg.jpeg")
  3. print(src.shape[:2])
  4. cv.imshow("src", src)
  5. # 向下采样一次
  6. dst = cv.pyrDown(src)
  7. print(dst.shape[:2])
  8. cv.imshow("dst", dst)
  9. # 向上采样一次
  10. dst1 = cv.pyrUp(dst)
  11. print(dst1.shape[:2])
  12. cv.imshow("dst1", dst1)
  13. # 计算拉普拉斯金字塔图像
  14. # 原图 - 向上采样一次的图
  15. laplace = cv.subtract(src, dst1)
  16. cv.imshow("laplace", laplace)
  17. cv.waitKey()
复制代码
运行效果如下,相关的图像已经出现出来,重点留意最右侧的图片。


这个地方需要留意下,假如你使用 cv.subtract(src, dst1) 函数,得到的是上图效果,但是在使用还原的时候会发现问题,发起直接使用 -完成,匹配公式,修改代码如下:
  1. # cv.subtract(src, dst1)
  2. laplace = src - dst1
复制代码
代码运行效果如下。


学习过程中发现这样一段话:图像尺寸最好是 2 的整次幂,如 256,512 等,否则在金字塔向上的过程中图像的尺寸会不等,这会导致在拉普拉斯金字塔处置处罚时由于不同尺寸矩阵相减而出错。
这个我在实测的时候发现确实云云,比方案例中使用的图像,在向下采样 2 次的时候,图像的尺寸就会发生厘革,测试代码如下:
  1. import cv2 as cv
  2. src = cv.imread("./testimg.jpeg")
  3. print(src.shape[:2])
  4. cv.imshow("src", src)
  5. # 向下采样1次
  6. dst1 = cv.pyrDown(src)
  7. print(dst1.shape[:2])
  8. cv.imshow("dst", dst1)
  9. # 向下采样2次
  10. dst2 = cv.pyrDown(dst1)
  11. print(dst1.shape[:2])
  12. cv.imshow("dst2", dst2)
  13. # 向上采样1次
  14. up_dst1 = cv.pyrUp(dst2)
  15. print(up_dst1.shape[:2])
  16. cv.imshow("up_dst1", up_dst1)
  17. # 计算拉普拉斯金字塔图像
  18. # 采样1次 - 向上采样1次的图
  19. laplace = dst1 - up_dst1
  20. cv.imshow("laplace", laplace)
  21. cv.waitKey()
复制代码
留意
  1. print(up_dst1.shape[:2])
复制代码
部分的输出如下:
  1. (710, 400)
  2. (355, 200)
  3. (355, 200)
  4. (356, 200)
复制代码
假如在该基础上使用拉普拉斯图像金字塔,就会出现如下错误
  1. Sizes of input arguments do not match
复制代码
在总结一下拉普拉斯图像金字塔的执行过程:
      
  • 向下采样:用高斯金字塔的第 i 层减去 i+1 层做上采样的图像,得到拉普拉斯第 i 层的图像;  
  • 向上采样:用高斯金字塔的 i+1 层向上采样加上拉普拉斯的第 i 层,得到第 i 层的原始图像。
向下采样上面的代码已经实现了,但是拉普拉斯向上采样还未实现,完满一下代码如下,为了代码清楚,我们将变量命名进行修改。
  1. import cv2 as cv
  2. src = cv.imread("./testimg_rect.jpeg")
  3. print(src.shape[:2])
  4. cv.imshow("src", src)
  5. # 高斯金字塔第 0 层
  6. gus0 = src # 原图
  7. # 高斯金字塔第 1 层
  8. gus1 = cv.pyrDown(gus0)
  9. # 高斯第 2 层
  10. gus2 = cv.pyrDown(gus1)
  11. # 拉普拉斯金字塔第 0 层
  12. lap0 = gus0 - cv.pyrUp(gus1)
  13. # 拉普拉斯金字塔第 1 层
  14. lap1 = gus1 - cv.pyrUp(gus2)
  15. # 显示拉普拉斯第一层代码
  16. cv.imshow("laplace", lap1)
  17. cv.waitKey()
复制代码
下面用修改好的代码完成还原图片的操作。
  1. import cv2 as cv
  2. src = cv.imread("./testimg_rect.jpeg")
  3. print(src.shape[:2])
  4. cv.imshow("src", src)
  5. # 高斯金字塔第 0 层
  6. gus0 = src # 原图
  7. # 高斯金字塔第 1 层
  8. gus1 = cv.pyrDown(gus0)
  9. # 高斯第 2 层
  10. gus2 = cv.pyrDown(gus1)
  11. # 拉普拉斯金字塔第 0 层
  12. lap0 = gus0 - cv.pyrUp(gus1)
  13. # 拉普拉斯金字塔第 1 层
  14. lap1 = gus1 - cv.pyrUp(gus2)
  15. rep = lap0 + cv.pyrUp(lap1 + cv.pyrUp(gus2))
  16. gus_rep = cv.pyrUp(cv.pyrUp(gus2))
  17. cv.imshow("rep", rep)
  18. cv.imshow("gus_rep", gus_rep)
  19. cv.waitKey()
复制代码
以上代码最重要的部分为下面两句:
  1. rep = lap0 + cv.pyrUp(lap1 + cv.pyrUp(gus2))
  2. gus_rep = cv.pyrUp(cv.pyrUp(gus2))
复制代码
第一行代码中
  1. lap1 + cv.pyrUp(gus2)
复制代码
即文字公式 【用高斯金字塔的 i+1 层向上采样加上拉普拉斯的第 i 层,得到第 i 层的原始图像】的翻译。
第二行代码是使用直接向上采样,最终得到的是丧失细节的图像。
上述代码运行的效果如下,通过拉普拉斯可以完美还原图像。
学习本案例之后,你可以在复盘本文开始部分的代码,将其进行修改。


最后在学习一种本领,可以直接将两幅图片出现,代码如下:
  1. import cv2 as cv
  2. import numpy as np
  3. src = cv.imread("./testimg_rect.jpeg")
  4. print(src.shape[:2])
  5. cv.imshow("src", src)
  6. # 向下采样1次
  7. down_dst1 = cv.pyrDown(src)
  8. print(down_dst1.shape[:2])
  9. cv.imshow("dst", down_dst1)
  10. # 向上采样1次
  11. up_dst1 = cv.pyrUp(down_dst1)
  12. print(up_dst1.shape[:2])
  13. cv.imshow("up_dst1", up_dst1)
  14. res = np.hstack((up_dst1, src))
  15. cv.imshow('res', res)
  16. cv.waitKey()
复制代码
运行之后,通过 np.hstack((up_dst1, src))函数,将两个图像矩阵归并,实现效果如下:


到此这篇关于Python OpenCV高斯金字塔与拉普拉斯金字塔的实现的文章就介绍到这了,更多相关Python OpenCV金字塔内容请搜刮草根技能分享从前的文章或继续欣赏下面的相关文章盼望各人以后多多支持草根技能分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作