[OpenCV] 数字图像处理 C++ 学习——09图像金字塔上采样(PyrUp)和降采样(PyrDown) 附完整代码

文章目录

前言

本博客主要学习图像金字塔技术中的上采样和降采样操作。这些操作用于改变图像的分辨率,是多尺度图像处理的基础。通过上采样(拉普拉斯金字塔)可以放大图像,恢复或接近原始图像,而降采样(高斯金字塔)可以缩小图像,减少图像的细节,从而降低图像处理的计算复杂度。本博客将详细讲解上采样和降采样的原理,并提供完整的实现代码,通过具体示例来展示这些操作的实际效果。

1.理论基础

图像金字塔是一种通过连续降低图像分辨率来创建一系列图像的技术。每一个层次的图像都是前一层次图像的降采样版本。图像金字塔分为两种类型:高斯金字塔和拉普拉斯金字塔。

(1)高斯金字塔 (Gaussian Pyramid)

高斯金字塔是一种通过对图像进行高斯模糊处理,然后进行降采样来减少图像分辨率的金字塔。每一层图像都是上一层图像的一半分辨率。高斯金字塔通常用于图像压缩和多分辨率图像分析。

构建过程

  1. 应用高斯模糊:对原始图像使用高斯滤波器,模糊图像。
  2. 降采样:将模糊后的图像尺寸减半,得到高斯金字塔的下一层。

(2)拉普拉斯金字塔(Laplacian Pyramid)

拉普拉斯金字塔是一种基于高斯金字塔构建的图像金字塔,用于捕捉图像中的边缘和细节信息。每一层的拉普拉斯金字塔图像是对应的高斯金字塔层图像与其上一层上采样图像的差值。

构建过程

  1. 创建高斯金字塔:首先构建一个高斯金字塔。
  2. 上采样和求差
    • 从高斯金字塔的低分辨率层开始,将该层图像上采样至高分辨率。
    • 将上采样图像与相应的高分辨率层图像相减,得到拉普拉斯金字塔的图像。
    • 每一层拉普拉斯金字塔的图像代表了原始图像在相应尺度上的细节。

2.代码实现

(1)图像读取

文章使用到的图像,供下载学习使用sherlock2.jpg

可参考[OpenCV] 数字图像处理 C++ 学习------01图像的读取、加载和保存附完整代码(小白入门篇)

cpp 复制代码
	cv::Mat inputimage;
	inputimage = imread("sherlock2.jpg");
	if (inputimage.empty()) {
		printf("could not find the image...\n");
		return;
	}
	namedWindow("input image", cv::WINDOW_AUTOSIZE);
	cv::imshow("input image", inputimage);

(2)图像上采样(PyrUp)和降采样(PyrDown)

降采样是指将图像的分辨率降低至原来的一半。上采样是指将图像的分辨率提高至原来的一倍。

cpp 复制代码
	//降采样
	cv::Mat downsampledImage;
	cv::pyrDown(inputimage, downsampledImage);  // 构建高斯金字塔的下一层
	cv::imshow("Downsampled Image", downsampledImage);
	//上采样
	cv::Mat upsampledImage;
	cv::pyrUp(inputimage, upsampledImage); // 上采样操作
	cv::imshow("Upsampled Image", upsampledImage

上采样结果:

(3)高斯金字塔

pyrDown() 函数简化高斯金字塔的构建过程,自动执行高斯模糊和降采样步骤,直接调用 pyrDown() 就可以构建高斯金字塔的每一层。

高斯金字塔结果:

(4)拉普拉斯金字塔

对原始图像进行降采样和上采样后计算它们的差异,生成了拉普拉斯金字塔图像,用于突出显示图像中的边缘和细节。

cpp 复制代码
	//拉普拉斯金字塔
	cv::Mat laplacianImage;
	cv::pyrDown(inputimage, downsampledImage);
	cv::pyrUp(downsampledImage, upsampledImage, inputimage.size());
	// 计算拉普拉斯金字塔图像
	cv::subtract(inputimage, upsampledImage, laplacianImage);
	cv::imshow("Laplacian Pyramid Image", laplacianImage);

拉普拉斯金字塔结果:

3.完整代码

cpp 复制代码
#include<opencv2/opencv.hpp>
#include<highgui.hpp>

using namespace cv;
using namespace std;

void iamge_Pyramid()
{
	cv::Mat inputimage;
	inputimage = imread("sherlock2.jpg");
	if (inputimage.empty()) {
		printf("could not find the image...\n");
		return;
	}
	namedWindow("input image", cv::WINDOW_AUTOSIZE);
	cv::imshow("input image", inputimage);
	//降采样
	cv::Mat downsampledImage;
	cv::pyrDown(inputimage, downsampledImage);  // 构建高斯金字塔的下一层
	cv::imshow("Downsampled Image", downsampledImage);
	//上采样
	cv::Mat upsampledImage;
	cv::pyrUp(inputimage, upsampledImage); // 上采样操作
	cv::imshow("Upsampled Image", upsampledImage);

	//高斯金字塔
	cv::imshow("Gaussian Pyramid - Downsampled Image", downsampledImage);
	//拉普拉斯金字塔
	cv::Mat laplacianImage;
	cv::pyrDown(inputimage, downsampledImage);
	cv::pyrUp(downsampledImage, upsampledImage, inputimage.size());
	// 计算拉普拉斯金字塔图像
	cv::subtract(inputimage, upsampledImage, laplacianImage);
	cv::imshow("Laplacian Pyramid Image", laplacianImage);

	cv::waitKey(0);
}
int main() 
{
	iamge_Pyramid();
    return 0;
}
相关推荐
jndingxin12 分钟前
OpenCV结构分析与形状描述符(18)比较两个轮廓相似度的函数matchShapes()的使用
人工智能·opencv·计算机视觉
小周的C语言学习笔记33 分钟前
鹏哥C语言33---循环语句 for
c语言·c++·算法
ZH_qaq1 小时前
【洛谷】P11062 【MX-X4-T2】「Jason-1」加法 的题解
c++·算法
9ilk1 小时前
【与C++的邂逅】--- C++的IO流
开发语言·c++
是小满满满满吗1 小时前
C++中的继承
开发语言·c++·python
程序猿练习生1 小时前
C++速通LeetCode简单第16题-买卖股票的最佳时机
开发语言·c++·leetcode
只对您心动1 小时前
【QT】实现TCP服务器,客户端之间的通信
linux·服务器·c语言·开发语言·c++·qt·tcp/ip
MaTF_2 小时前
《Effective C++》第三版——让自己习惯C++
开发语言·c++
Antonio9152 小时前
【高级数据结构】树状数组
数据结构·c++·算法
羊十一3 小时前
C++(C++的文件I/O)
开发语言·c++·cocoa