OpenCV入门(二十一)快速学会OpenCV 20 图像金字塔

OpenCV入门(二十一)快速学会OpenCV 20 图像金字塔

  • 1.基本概念
  • 2.高斯金字塔
    • 2.1 向下取样
    • 2.2 向上取样
  • 3.拉普拉斯金字塔

作者:Xiou

1.基本概念

一般情况下,我们要处理的是一幅具有固定分辨率的图像。有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标(比如脸),但是不知道目标在图像中的尺寸大小。在这种情况下,我们需要创建一组图像,这些图像是具有不同分辨率的原始图像。

我们把这组图像叫作图像金字塔(简单来说就是同一图像的不同分辨率的子图集合)。如果我们把最大的图像放在底部、最小的放在顶部,看起来就像一座金字塔,故而得名图像金字塔,如图所示。

在这里插入图片描述
图像金字塔是以多个分辨率来表示图像的一种有效且概念简单的结构。图像金字塔最初用于机器视觉和图像压缩。一个图像金字塔是一系列以金字塔形状排列的、分辨率逐步降低的图像集合。

图像金字塔可以通过梯次向下采样获得,直至达到某个终止条件才停止采样;在向下采样中,层级越高,图像越小,分辨率越低。

图像金字塔有两种:第一种是高斯金字塔(Gaussian pyramid),第二种是拉普拉斯金字塔(Laplacian pyramid)。

高斯金字塔用来向下采样,是主要的图像金字塔。

拉普拉斯金字塔用来从金字塔底层图像重建上层未采样的图像,在数字图像处理中也就是预测残差,可以对图像进行最大限度的还原,配合高斯金字塔一起使用。

两者的区别是:高斯金字塔用来向下降采样图像,拉普拉斯金字塔用来从金字塔底层图像中向上采样重建一个图像。

2.高斯金字塔

高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。

高斯金字塔的向下采样过程是:对于给定的图像先做一次高斯平滑处理,也就是先对原始图像进行高斯内核卷积操作,然后对图像进行采样,去除图像中的偶数行和偶数列,然后得到一幅图像,对这幅图像再进行上述操作,就可以得到高斯金字塔。
在这里插入图片描述

2.1 向下取样

在图像向下取样中,一般分两步:
(1)对图像Gi进行高斯卷积核(高斯滤波)。
(2)删除所有的偶数行和列,如图所示:

在这里插入图片描述
其中,高斯核卷积运算(高斯滤波)就是对整幅图像进行加权平均的过程,每一个像素点的值都由其本身和邻域内的其他像素值(权重不同)经过加权平均后得到。常见的3×3和5×5高斯核如图所示。

在这里插入图片描述

假设原始图像Gi具有M×N个像素,进行向下取样之后所得到的图像Gi+1具有M/2×N/2个像素,只有原图的1/4。
通过对输入的原始图像不停迭代以上步骤,就会得到整个金字塔。

在OpenCV中,向下取样使用的函数为pyrDown(),函数声明如下:

     pyrDown(src,dst = None,dstsize = None, borderType = None)

其中,参数
src表示输入图像;
dst表示输出图像(和输入图像具有一样的尺寸和类型);
dstsize表示输出图像的大小,默认值为Size();
borderType表示像素外推方法(仅支持BORDER_DEAFULT)。

代码实例一:

import cv2 as cv
  
img = cv.imread(r"test.jpg")
down=cv.pyrDown(img) 	#图像向下取样
cv.imshow("original", img);  	#显示图像
cv.imshow("PyrDown", down);
cv.waitKey(0);
cv.destroyAllWindows(); #销毁所有窗口

在上述代码中,使用函数pyrDown进行了向下取样。可以看到,pyrDown函数的使用非常简单。

输出结果:

在这里插入图片描述
代码实例一是对图像一次向下取样,下面再看一个对图像多次向下取样的例子。
代码实例二:

import cv2 as cv
  
img = cv.imread(r"img.jpg")
r1=cv.pyrDown(img);   
r2=cv.pyrDown(r1);
r3=cv.pyrDown(r2);
cv.imshow("PyrDown1", r1);
cv.imshow("PyrDown2", r2);
cv.imshow("PyrDown3", r3);
cv.waitKey(0);
cv.destroyAllWindows(); #销毁所有窗口

输出结果:

在这里插入图片描述

2.2 向上取样

图像向上取样是由小图像不断放大图像的过程。它将图像在每个方向上扩大为原图像的2倍,新增的行和列均用0来填充,并使用与“向下取样”相同的卷积核乘以4,再与放大后的图像进行卷积运算,以获得“新增像素”的新值。值得注意的是,放大后的图像比原始图像要模糊。例如,在原始像素45、123、89、149之间新增一行和一列值为0的像素,如图所示。
在这里插入图片描述
在OpenCV中,向上取样使用pyrUp函数,其函数声明如下:

     pyrUp (src,dst = None,dstsize = None, borderType = None)

其中,参数
src表示输入图像;
dst表示输出图像(和输入图像具有一样的尺寸和类型);
dstsize表示输出图像的大小,默认值为Size();
borderType表示像素外推方法。

代码实例:

import cv2 as cv
  
img = cv.imread(r"img.jpg")
r1=cv.pyrDown(img);  
r2=cv.pyrUp(r1);
cv.imshow("PyrDown1", r1);
cv.imshow("PyrDown2", r2);
cv.waitKey(0);
cv.destroyAllWindows(); #销毁所有窗口

在上述代码中,我们先对一幅图像做向下取样,再进行向上取样,可以发现向上取样后图像变模糊了。

输出结果:

在这里插入图片描述

3.拉普拉斯金字塔

拉普拉斯金字塔可以从高斯金字塔计算得来,拉普拉斯金字塔主要应用于图像融合。在OpenCV 4版本中,拉普拉斯金字塔位于imgproc模块的Image Filtering子模块中。

拉普拉斯金字塔是高斯金字塔的修正版,可以通过计算残差图来还原到原图。拉普拉斯金字塔第i层的数学定义如下:

在这里插入图片描述
在OpenCV中,拉普拉斯金字塔的函数原型如下:

     Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

其中,参数
src表示原图;
dst表示目标图像;
ddepth表示目标图像的深度;
ksize表示用于计算二阶导数滤波器的孔径大小,必须为正数和奇数;
scale用于计算拉普拉斯值的可选比例因子,默认情况下,不应用缩放;
delta表示在将结果存储到dst之前添加到结果中的可选增量值;
borderType用于决定在图像发生几何变换或者滤波操作(卷积)时边沿像素的处理方式。

代码实例:

import cv2 as cv
import numpy as np

# 拉普拉斯算子
def Laplace_demo(image):
    dst = cv.Laplacian(image, cv.CV_32F)
    lpls_1 = cv.convertScaleAbs(dst)
    cv.imshow("Laplace_1", lpls_1)
    # 自定义拉普拉斯算子
    kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
    dst = cv.filter2D(image, cv.CV_32F, kernel)
    lpls_2 = cv.convertScaleAbs(dst)
    cv.imshow("Laplace_2", lpls_2)

if __name__ == "__main__":
    src = cv.imread(r"img.jpg")
    src = cv.resize(src, None, fx=0.5, fy=0.5)
    cv.imshow("image", src)
    Laplace_demo(src)
    cv.waitKey(0)
    cv.destroyAllWindows()

在上述代码中,我们先利用函数Laplacian进行了拉普拉斯边缘计算,然后实现了自定义拉普拉斯算子。

输出结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ 入门到应用 ( 六 ) 消息可靠性

7.RabbitMQ可靠性投递 为了保证信息不丢失, 可靠抵达,引入确认机制 消息从生产者传递到消费者的过程中, 不同的阶段使用不同的确认方式. 7.0.准备请求 一次性发送10 个消息 通过 new.exchange.direct交换机 接收消息, 使用 new.admin路由键 向 new.admin队列 发送消息. Aut…

【 构造 HTTP 请求 】

文章目录一、通过 form 表单构造 HTTP 请求1.1 form 发送 GET 请求1.2 form 发送 POST 请求二、通过 ajax 构造 HTTP 请求2.1 ajax 发送 GET 请求2.2 ajax 发送POST 请求2.3 关于 ajax三、通过 Java socket 构造 HTTP 请求(了解)一、通过 form 表单构造 HTTP 请求 form (表单)…

Element Plus 实例详解(六)___Progress 进度条

Element Plus 实例详解(六)___Progress 进度条 本文目录: 一、前言 二、搭建Element Plus试用环境 1、搭建Vue3项目(基于Vite Vue) 2、安装Element Plus 三、Element Plus Progress 进度条功能试用 1、直线进度条…

【数据结构】栈和队列

🚀write in front🚀 📜所属专栏:初阶数据结构 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论,是对…

血细胞智能检测与计数软件(Python+YOLOv5深度学习模型+清新界面版)

摘要:血细胞智能检测与计数软件应用深度学习技术智能检测血细胞图像中红细胞、镰状细胞等不同形态细胞并可视化计数,以辅助医学细胞检测。本文详细介绍血细胞智能检测与计数软件,在介绍算法原理的同时,给出Python的实现代码以及Py…

HTTP协议详解(上)

目录 前言: 认识URL HTTP协议方法 通过Fiddler抓包 GET和POST之间典型区别 header详解 HTTP响应状态码 常见状态码解释 状态码分类 HTTP协议报文格式 小结: 前言: HTTP协议属于应用层协议,称为超文本传输协议&#xff…

C++中的string类【详细分析及模拟实现】

string类 目录string类一、stirng的介绍及使用1.为什么学习string类?2.标准库中的string类2.1 引入:编码2.2 basic_string3.string类的使用3.1 构造函数3.2 遍历string方式1:for循环方式2:范围for4.迭代器4.1 正向迭代器4.2反向迭…

STM-32:按键控制LED灯 程序详解

目录一、基本原理二、接线图三、程序思路3.1库函数3.2程序代码注:一、基本原理 左边是STM322里电路每一个端口均可以配置的电路部分,右边部分是外接设备 电路图。 配置为 上拉输入模式的意思就是,VDD开关闭合,VSS开关断开。 浮空…

互联网数据挖掘与分析讲解

一、定义 数据挖掘(英语:Data mining),又译为资料探勘、数据采矿。它是数据库知识发现(英语:Knowledge-Discovery in Databases,简称:KDD)中的一个步骤。数据挖掘一般是指从大量的数…

多线程(四):线程安全

在开始讲解线程安全之前我们先来回顾一下我们学了那些东西了: 1. 线程和进程的认识 2. Thread 类的基本用法 3. 简单认识线程状态 4. 初见线程安全 上一章结束时看了一眼线程安全问题,本章将针对这个重点讲解。 一个代码在单线程中能够安全执行&am…

204. 计数质数 (埃式筛法详解)——【Leetcode每日一题】

素数最朴素判断思路:(一般会超时) 对正整数 n,如果用 2 到 n\sqrt{n}n​ 之间的所有整数去除,均无法整除,则 n 为素数又称为质数。 为什么到n\sqrt{n}n​ 就可以了,因为因数如果存在一定是成对…

【三】一起算法---栈:STL stack、手写栈、单调栈

纸上得来终觉浅,绝知此事要躬行。大家好!我是霜淮子,欢迎订阅我的专栏《算法系列》。 学习经典算法和经典代码,建立算法思维;大量编码让代码成为我们大脑的一部分。 ⭐️已更系列 1、基础数据结构 1.1、链表➡传送门 1…

使用Node.js+Koa 从零开始写个人博客系统——后端部分(一)

使用Node.jsKoa 从零开始写个人博客系统系列 提示:在此文章中你可以学习到的内容如下: 1 如何使用Koa快速搭建项目 2 对Koa的核心组件Koa-Route的简单使用 3 3层架构思想 4 nodejs的ORM框架——sequelize的使用 5 sequelize-auto的使用 6 简单的增删查改…

【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛客观题以及详细题解

题1 概念题。 USRAT:异步串口通信,常用于数据传输;SW-DP:SWD 的全称应该是 The Serial Wire Debug Port (SW-DP),也就是串行调试端口,是 >ARM 目前支持的两种调试端口之一;JTAG-DP:另一个调试…

git基本用法教程(fork软件+git命令)

git基本用法教程1. git commit2. git branch3. git checkout4. git merge5. git rebase6. 在提交树中移动7. 撤销变更8. 整理提交记录9. 提交的技巧10. git clone11. git push12. git pull13. git fetch14. git flow15. git stash16. fork的使用当然除了环境和demo的运行和改写…

chartgpt 告诉我的,loss 函数的各种知识

一、libtorch中常见的损失函数及其使用场景的总结1. CrossEntropyLoss:CrossEntropyLoss(交叉熵损失)主要用于分类任务。它适用于多分类问题,其中每个样本只属于一个类别(互斥)。该损失函数将预测概率与真实标签的one-…

应届生投腾讯,被面试官问了8个和 ThreadLocal 相关的问题。

问:谈一谈ThreadLocal的结构。 ThreadLocal内部维护了一个ThreadLocalMap静态内部类,ThreadLocalMap中又维护了一个Entry静态内部类,和Entry数组。 Entry类继承弱引用类WeakReference,Entry类有一个有参构造函数,参数…

【数据结构】用队列实现栈

💯💯💯 本篇总结利用队列如何实现栈的相关操作,不难观察,栈和队列是可以相互转化的,需要好好总结它们的特性,构造出一个恰当的结构来实现即可,所以本篇难点不在代码思维,…

大数据应用——Hadoop运行模式(伪分布式运行)

4.2 伪分布式运行模式4.2.1 启动HDFS并运行MapReduce程序1. 分析 (1)配置集群(2)启动、测试集群增、删、查没有改(多台机子麻烦)(3)执行WordCount案例2. 执行步骤(1&…

前端vue实现导出pdf文件报告组件

大屏项目有一个需求,需要对展示的内容进行文件导出,但是目前后台没有相关的逻辑,所以只能前端硬上,在参考了其他许多的逻辑之后,目前我自己这边做了一套比较笨的组件,通过拼接标签这种方法来实现对你想需要…
最新文章