Python-OpenCV中的图像处理-图像金字塔

news/2024/7/21 6:25:48 标签: python, opencv, 图像处理

Python-OpenCV中的图像处理-图像金字塔

  • 图像金字塔
    • 高斯金字塔
    • 拉普拉斯金字塔
  • 金字塔图像融合

图像金字塔

  • 同一图像的不同分辨率的子图集合,如果把最大的图像放在底部,最小的放在顶部,看起来像一座金字塔,故而得名图像金字塔。
  • cv2.pyrUp():上采样
  • cv2.pyrDown():下采样
    在这里插入图片描述

高斯金字塔

高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值。这样操作一次一个 MxN 的图像就变成了一个 M/2xN/2 的图像。所以这幅图像的面积就变为原来图像面积的四分之一。这被称为 Octave。连续进行这样的操作我们就会得到一个分辨率不断下降的图像金字塔。我们可以使用函数cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔。

python">import numpy as np
import cv2
from matplotlib import pyplot as plt

# 图像金字塔 :同一图像的不同分辨率的子图集合
# 有两种:高斯金字塔(Gaussian Pyramid) 和 拉普拉斯金字塔(Pyramid)
# 高斯金字塔 每次处理后图像的面积变为原来的四分之一,也被称为Octave
# cv2.pyrDown() #分辨率降低
# cv2.pyrUp()   #分辨率增高

img = cv2.imread('./resource/opencv/image/messi5.jpg')
lower_reso = cv2.pyrDown(img)
lower_reso2 = cv2.pyrDown(lower_reso)

upper_reso = cv2.pyrUp(lower_reso2)
upper_reso2 = cv2.pyrUp(upper_reso)

cv2.imshow('img', img)
cv2.imshow('lower_reso', lower_reso)
cv2.imshow('lower_reso2', lower_reso2)
cv2.imshow('upper_reso', upper_reso)
cv2.imshow('upper_reso2', upper_reso2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

拉普拉斯金字塔

拉普拉斯金字塔可以有高斯金字塔计算得来,公式如下:
Li = Gi - pyrUp( Gi + 1 )
式中:

  • Li:表示拉普拉斯金字塔中的第i层
  • Gi:表示高斯金字塔中的第i层
    拉普拉金字塔的图像看起来就像边界图,其中很多像素都是 0。他们经常
    被用在图像压缩中。

在这里插入图片描述
图中各标记含义如下:

  • 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都可以通过拉普拉斯金字塔的构造表达式得到。如之前介绍的,拉普拉斯金字塔的目的就是为了恢复高分辨率的图像。

python"># 拉普拉斯金字塔构建
G0 = cv2.imread("./resource/opencv/image/lena.jpg")
cv2.imshow("input image",G0)
G1=cv2.pyrDown(G0)
G2=cv2.pyrDown(G1)
G3=cv2.pyrDown(G2)
G4=cv2.pyrDown(G3)
L0 = cv2.subtract(G0,cv2.pyrUp(G1))
L1 = cv2.subtract(G1,cv2.pyrUp(G2))
L2 = cv2.subtract(G2,cv2.pyrUp(G3))
L3 = cv2.subtract(G3,cv2.pyrUp(G4))
cv2.imshow("G1",G1)
cv2.imshow("G2",G2)
cv2.imshow("G3",G3)
cv2.imshow("G4",G4)
cv2.waitKey(0)
cv2.destroyAllWindows()
python">import numpy as np
import cv2

# 拉普拉斯金字塔是由高斯金字塔计数得到,公式如下
# Li = Gi - PyrUP(PyrDown(Gi))
 
# 拉普拉斯金字塔图像看起来像是边界图,其中很多像素都是0,常被用在图像压缩中。

import cv2 as cv
 
if __name__ == '__main__':
    img = cv.imread("./resource/opencv/image/lena.jpg")
 
    down1 = cv.pyrDown(img)
    res = img - cv.pyrUp(down1)
 
    down2 = cv.pyrDown(down1)
    res2 = down1 - cv.pyrUp(down2)
 
    cv.imshow("img", img)
    cv.imshow("res", res)
    cv.imshow("res2", res2)
 
    cv.waitKey(0)
    cv.destroyAllWindows()

在这里插入图片描述

金字塔图像融合

python">import numpy as np
import cv2
import sys

# 实现上述效果的步骤如下:
# 1. 读入两幅图像,苹果和橘子
# 2. 构建苹果和橘子的高斯金字塔( 6 层)
# 3. 根据高斯金字塔计算拉普拉斯金字塔
# 4. 在拉普拉斯的每一层进行图像融合(苹果的左边与橘子的右边融合)
# 5. 根据融合后的图像金字塔重建原始图像。

A = cv2.imread('./resource/opencv/image/apple.jpg')
B = cv2.imread('./resource/opencv/image/orange.jpg')
print(A.shape)
print(B.shape)
# 生成高斯金字塔
G = A.copy()
gpA = [G]
for i in range(5):
    G = cv2.pyrDown(G)
    gpA.append(G)
    
G = B.copy()
gpB = [G]
for i in range(5):
    G = cv2.pyrDown(G)
    gpB.append(G)
# 产生Laplacian金字塔
lpA = [gpA[5]]
for i in range(5,0,-1):
    GE = cv2.pyrUp(gpA[i])
    L = cv2.subtract(gpA[i-1],GE)
    lpA.append(L)

lpB = [gpB[5]]
for i in range(5,0,-1):
    GE = cv2.pyrUp(gpB[i])
    L = cv2.subtract(gpB[i-1],GE)
    lpB.append(L)
# 合并
LS = []
for la,lb in zip(lpA,lpB):
    rows,cols,dpt = la.shape
    ls = np.hstack((la[:,0:cols//2], lb[:,cols//2:]))
    LS.append(ls)
# 重新构建图像
ls_ = LS[0]
for i in range(1,6):
    ls_ = cv2.pyrUp(ls_)
    ls_ = cv2.add(ls_, LS[i])
# 连接
real = np.hstack((A[:,:cols//2],B[:,cols//2:]))
cv2.imshow("apple",A)
cv2.imshow("orange",B)
cv2.imshow("LS",ls_)
cv2.imshow("Real",real)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述


http://www.niftyadmin.cn/n/4924996.html

相关文章

协程和线程的区别

调度方式:线程由操作系统内核进行调度,而协程由程序员或运行时环境进行调度。线程的调度是由操作系统决定的,它可以在不同的核心上并行执行。而协程的调度是由程序员显式地控制的,它在单个线程内通过协作式调度来实现并发。 并发…

树状结构数据,筛选指定数据

问题描述: 应用场景和需求:对一个树状结构的数据,进行CRUD 时,想筛选出 树状结构数据中存在变动的部分。 操作步骤 准备需要的数据: 1.先拿到 你原来的树状结构数据 2.再筛选出 需要保留的数据集合id,也…

分班查询系统学生信息在线采集方法和具体操作教程

作为教师,特别是临近新学年,我们经常需要进行学生分班工作,这是一项繁琐但非常重要的工作。为了提高工作效率,我们可以利用易查分轻松生成一个学生分班查询系统。本文将介绍如何利用易查分设计和开发这样一个系统。 我们可以选择使…

Java课题笔记~ JavaWeb概述/开发基础

JavaWeb概述/开发基础 1.XML基础 (1)XML概述 (2)XML语法 (3)DTD约束 (4)Schema约束(XML Schema 比 DTD 更强大) 2.Web基础知识 Web是一个分布式的超媒…

tui.calender日历在vue中的使用1.0

官网:https://ui.toast.com/tui-calendar github:https://github.com/nhn/tui.calendar/tree/main 月、周、日视图都有,拖拽也比较方便,但是自己用起来比较费劲,参考文档写得不全,做个记录日后方便参考&…

前后端分离式项目架构流程复盘之宿舍管理系统

文章目录 🐒个人主页🏅JavaEE系列专栏📖前言:【🎇前端】先创建Vue-cli项目(版本2.6.10,仅包含babel),请选择此项目并创建 【整理简化项目模板】【🎀创建路由】…

qt qml中各种Layout之间是如何对齐的?

问题描述: qt qml中下一个RowLayout如何对齐顶部到上方的ColumnLayout的底部略低一些间隔的位置? 我们怎么使用achors去锚定位置? 这些都是可以用anchors锚定属性,以及margin来设置的。 解决办法: 要实现将下一个R…

运维工程师是做什么的?

一、运维工程师浅析 运维工程师是指负责系统的运行和维护的专业人士。他们的工作涵盖了各种方面,包括硬件和软件的管理、网络和服务器的维护、故障排除和问题解决等。具体来说,他们的主要职责包括: 1. 系统管理:运维工程师负责监…