OpenCV官方教程中文版 —— 图像金字塔

OpenCV官方教程中文版 —— 图像金字塔

  • 前言
  • 一、原理
  • 二、使用金字塔进行图像融合

前言

学习图像金字塔

使用图像创建一个新水果:“橘子苹果”

将要学习的函数有:cv2.pyrUp(),cv2.pyrDown()。

一、原理

一般情况下,我们要处理是一副具有固定分辨率的图像。但是有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标,比如脸,我们不知道目标在图像中的尺寸大小。这种情况下,我们需要创建创建一组图像,这些图像是具有不同分辨率的原始图像。我们把这组图像叫做图像金字塔(简单来说就是同一图像的不同分辨率的子图集合)。如果我们把最大的图像放在底部,最小的放在顶部,看起来像一座金字塔,故而得名图像金字塔。

有两类图像金字塔:高斯金字塔和拉普拉斯金字塔。

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

函数 cv2.pyrDown() 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)。

# -*- coding:utf-8 -*-
import cv2 as cv# 高斯金字塔
def pyramid_demo(image):level = 4  # 金字塔的层数temp = image.copy()  # 拷贝图像pyramid_images = []for i in range(level):dst = cv.pyrDown(temp)  # down是降采样-尺寸变小,分辨率降低(缩小)pyramid_images.append(dst)cv.imshow("pyramid" + str(i), dst)temp = dst.copy()return pyramid_imagessrc = cv.imread("ball.png")
cv.namedWindow('input image', cv.WINDOW_NORMAL)
cv.imshow("input image", src)
pyramid_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

下图是一个四层的图像金字塔。

在这里插入图片描述
函数 cv2.pyrUp() 从一个低分辨率小尺寸的图像向下构建一个金子塔(尺寸变大,但分辨率不会增加)。

higher_reso2 = cv2.pyrUp(lower_reso)

你要记住的是是 higher_reso2 和 higher_reso 是不同的。因为一旦使用 cv2.pyrDown(),图像的分辨率就会降低,信息就会被丢失。下图就是从 cv2.pyrDown() 产生的图像金字塔的(由下到上)第三层图像使用函数cv2.pyrUp() 得到的图像,与原图像相比分辨率差了很多。

在这里插入图片描述

拉普拉斯金字塔可以有高斯金字塔计算得来,公式如下:

在这里插入图片描述
拉普拉金字塔的图像看起来就像边界图,其中很多像素都是 0。他们经常被用在图像压缩中。下图就是一个三层的拉普拉斯金字塔:

# -*- coding:utf-8 -*-
import cv2 as cv
# 高斯金字塔
def pyramid_demo(image):level = 4  # 金字塔的层数temp = image.copy()  # 拷贝图像pyramid_images = []for i in range(level):dst = cv.pyrDown(temp)  # down是降采样-尺寸变小,分辨率降低(缩小)pyramid_images.append(dst)cv.imshow("pyramid" + str(i), dst)temp = dst.copy()return pyramid_images# 拉普拉斯金字塔,拉普拉斯金字塔时,图像大小必须是2的n次方*2的n次方,不然会报错
def laplian_demo(image):pyramid_images = cv.resize(image, (512, 512), interpolation=cv.INTER_CUBIC)  # 可以替换成INTER_LINEARpyramid_images = pyramid_demo(pyramid_images)level = len(pyramid_images)  # 4 层for i in range(level-1, 0, -1):  # 每次递减expand = cv.pyrUp(pyramid_images[i], dstsize=pyramid_images[i - 1].shape[:2])lpls = cv.subtract(pyramid_images[i - 1], expand)cv.imshow("lpls_down" + str(i), lpls)def pyramid_demo_2(image):higher_reso2 = cv.pyrUp(image)cv.imshow("pyramid", higher_reso2)return higher_reso2src = cv.imread("ball.png")
src2 = cv.imread("lower_reso.png")
cv.namedWindow('input image', cv.WINDOW_NORMAL)
cv.imshow("input image", src)
#pyramid_demo(src)
#pyramid_demo_2(src2)
laplian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

二、使用金字塔进行图像融合

图像金字塔的一个应用是图像融合。例如,在图像缝合中,你需要将两幅图叠在一起,但是由于连接区域图像像素的不连续性,整幅图的效果看起来会很差。这时图像金字塔就可以排上用场了,他可以帮你实现无缝连接。这里的一个经典案例就是将两个水果融合成一个,看看下图也许你就明白我在讲什么了。

你可以通过阅读后边的更多资源来了解更多关于图像融合,拉普拉斯金字塔的细节。实现上述效果的步骤如下:

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

在这里插入图片描述
整个过程的代码如下。(为了简单,每一步都是独立完成的,这回消耗更多的内存,如果你愿意的话可以对他进行优化)

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
from matplotlib import pyplot as plt
import numpy as npA = cv2.imread('apple.png')
A = cv2.resize(A, (256, 256), interpolation=cv2.INTER_CUBIC)  # 可以替换成INTER_LINEAR
B = cv2.imread('orange.png')
B = cv2.resize(B, (256, 256), interpolation=cv2.INTER_CUBIC)  # 可以替换成INTER_LINEAR
b, g, r = cv2.split(A)
A = cv2.merge([r, g, b])
b, g, r = cv2.split(B)
B = cv2.merge([r, g, b])# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in range(6):G = cv2.pyrDown(G)gpA.append(G)# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in range(6):G = cv2.pyrDown(G)gpB.append(G)# generate Laplacian Pyramid for A
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)# generate Laplacian Pyramid for B
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)# Now add left and right halves of images in each level
# numpy.hstack(tup)
# Take a sequence of arrays and stack them horizontally
# to make a single array.LS = []
for la, lb in zip(lpA, lpB):rows, cols, dpt = la.shapels = np.hstack((la[:, 0:int(cols / 2)], lb[:, int(cols / 2):]))LS.append(ls)# now reconstruct
ls_ = LS[0]
for i in range(1, 6):ls_ = cv2.pyrUp(ls_)ls_ = cv2.add(ls_, LS[i])# image with direct connecting each half
real = np.hstack((A[:, :int(cols / 2)], B[:, int(cols / 2):]))plt.figure()
plt.subplot(221)
plt.imshow(A)  # expects distorted color
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.title("apple")
plt.subplot(222)
plt.imshow(B)  # expect true color
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.title("orange")
plt.subplot(223)
plt.imshow(real)  # expect true color
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.title("Direct_connection")
plt.subplot(224)
plt.imshow(ls_)  # expect true color
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.title("Pyramid_blending")
plt.show()

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

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

相关文章

全连接层是什么,有什么作用?

大家好啊,我是董董灿。 如果你是搞AI算法的同学,相信你在很多地方都见过全连接层。 无论是处理图片的卷积神经网络(CNN),还是处理文本的自然语言处理(NLP)网络,在网络的结尾做分类…

竞赛选题 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

循环队列c语言版

一、循环队列结构体 typedef int QueueDataType; #define CQ_MAX_SIZE 10typedef struct CircularQueue {QueueDataType data[CQ_MAX_SIZE];/**标记队列首*/QueueDataType head;/**标记队列尾部*/QueueDataType rear;} CircularQueue; 二、循环队列操作函数声明 /**创建队…

软件工程——期末复习知识点汇总

本帖的资料来源于某国内顶流高校的期末考试资料,仅包含核心的简答题,大家结合个人情况,按需复习~ 总的来说,大层面重点包括如下几个方面: 软件过程需求工程 设计工程软件测试软件项目管理软件过程管理 1.掌握软件生命…

SQL 选择数据库 USE语句

SQL 选择数据库 USE语句 当SQL Schema中有多个数据库时,在开始操作之前,需要选择一个执行所有操作的数据库。 SQL USE语句用于选择SQL架构中的任何现有数据库。 句法 USE语句的基本语法如下所示 : USE DatabaseName;数据库名称在RDBMS中必须是唯一的。…

How to install mongodb-7.0 as systemd service with podman

How to install mongodb-7.0 as systemd service with podman 1、安装1.1、创建卷1.2、配置文件1.3、创建容器1.4、服务管理1.5、容器管理 2、客户端管理 1、安装 1.1、创建卷 配置卷 podman volume create --label typemongo-7.0 --label envdev mongo-7.0-conf数据卷 pod…

Canny算子详解及例程

Canny算子是一种经典的边缘检测算法,于1986年由John Canny提出。相比其他边缘检测算法,Canny算子具有以下特点: 高准确性:Canny算子能够对图像中真实边缘进行准确检测,并尽量排除非边缘部分的干扰。 低错误率&#xf…

Creaform形创HandySCAN MAX l Elite三维扫描仪便携式3D测量解决方案

CASAIM中科院广州电子智能制造事业部连续多年荣获形创Creaform战略级代理商证书。战略级代理商是形创Creaform最高级别的合作伙伴。 2023年CASAIM中科院广州电子智能制造事业部的形创Creaform战略级代理商证书: Creaform 形创是便携式三维测量解决方案和工程服务领…

[Python进阶] 消息框、弹窗:tkinter库

6.16 消息框、弹窗:tkinter 6.16.1 前言 应用程序中的提示信息处理程序是非常重要的部分,用户要知道他输入的资料到底正不正确,或者是应用程序有一些提示信息要告诉用户,都必须通过提示信息处理程序来显示适当的信息&#xff0c…

NPDP产品经理证书是什么行业的证书?

NPDP是一个跨行业的证书,它适用于各种不同类型和规模的组织。无论是制造业、服务业还是科技领域,都可以从NPDP认证中获益。 1. 制造业: 制造业涉及大量的产品开发和创新活动。从汽车制造到电子设备制造,从家居用品到航天航空&…

【vue3】子传父-事件总线-mitt(子组件派发事件,父组件接收事件和传递的参数)

安装库&#xff1a;cnpm install mitt 封装 eventbus.ts&#xff1a; src->utils->eventbus.ts //eventbus.tsimport mitt from mittconst emitter mitt()export default emitter使用 B2.vue&#xff1a; //B2.vue <template><div class"aa">…

idea + Docker-Compose 实现自动化打包部署(仅限测试环境)

一、修改docker.service文件&#xff0c;添加监听端口 vi /usr/lib/systemd/system/docker.service ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock重启docker服务 systemctl daemo…

邦盛科技冲刺上市“冷思考”:身处红线边缘,达摩克利斯之剑高悬

撰稿|行星 来源|贝多财经 近日&#xff0c;浙江邦盛科技股份有限公司&#xff08;下称“邦盛科技”&#xff09;因发行上市申请文件中记载的财务资料已过有效期&#xff0c;需要补充提交。根据相关规定&#xff0c;上海证券交易所中止其发行上市审核。 据介绍&#xff0c;邦…

下载zip源码并使用交叉编译工具进行编译

可以按照以下步骤进行操作&#xff1a; 确保已经设置好交叉编译工具链并将其添加到系统的环境变量中。 打开终端&#xff0c;进入你想要存放源码的目录&#xff1a; cd /path/to/source/directory使用git命令克隆zip库的源码仓库&#xff1a; git clone https://github.com/ni…

量变引起质变:安卓改多了,就是自己的OS

最近小米也发布了自己的OS&#xff0c;其他也有厂家跟进。这是自华为鸿蒙之后&#xff0c;大家都说自己开发OS。对此&#xff0c;也是有很多争论的。 有人说&#xff0c;这些东西不都是安卓套壳或者改名吗&#xff1f;怎么就变成了自己的OS&#xff1f;这种观点对不对呢&#x…

StartCoroutine/yield 返回模式在 Unity 中到底如何工作?

Unity3D协程详解 游戏中的许多过程都是在多个帧的过程中发生的。你有“密集”的过程&#xff0c;比如寻路&#xff0c;每个帧都努力工作&#xff0c;但会分成多个帧&#xff0c;以免对帧速率产生太大影响。您拥有“稀疏”进程&#xff0c;例如游戏触发器&#xff0c;它们在大多…

Shopee、Lazada卖家不得不看的提升销量技巧,自养号测评打造权重

近年来&#xff0c;大部分虾皮、Lazada卖家开始通过测评补单的方式来提升店铺权重和产品排名&#xff0c;以吸引更多流量。这种方式可以有效提高产品的销售转化率&#xff0c;对店铺的运营起到推动作用。然而&#xff0c;测评补单并非简单的购买过程&#xff0c;其中涉及到许多…

干洗店预约下单管理系统收衣开单拍照必备软件

随着生活水平的提高和节奏的加快&#xff0c;商务人士的衣物越来越多&#xff0c;但精力和时间却越来越少。于是&#xff0c;干洗店应运而生&#xff0c;在中国&#xff0c;几乎所有的中心城市干洗店都门庭若市。若每人每月需要干洗一套服装&#xff0c;一个城市每月则需干洗50…

面试中经常问道的问题二

深入理解前端跨域方法和原理 前言 受浏览器同源策略的限制&#xff0c;本域的js不能操作其他域的页面对象&#xff08;比如DOM&#xff09;。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。所以我们要通过一些方法使本域的js能够操作其他域的页面对象或者使…

HTML5语义化标签 header 的详解

&#x1f31f;&#x1f31f;&#x1f31f; 专栏详解 &#x1f389; &#x1f389; &#x1f389; 欢迎来到前端开发之旅专栏&#xff01; 不管你是完全小白&#xff0c;还是有一点经验的开发者&#xff0c;在这里你会了解到最简单易懂的语言&#xff0c;与你分享有关前端技术和…