计算机视觉教程2-5:图像金字塔送她一朵玫瑰(附代码)

举报
Mr.Winter 发表于 2022/03/22 11:57:50 2022/03/22
【摘要】 计算机视觉没那么枯燥,这篇文章用最通俗的语言和最有趣的应用介绍什么是图像金字塔,配套代码加深理解

image.png

1 金字塔

平时你听到、见到的金字塔是什么样的?

这样?

571ec20c19904056a22e5f6b8df40585[0].png

还是这样?

aede65d749144ec6a7b13327fae5d30e[0].png

实际上除了这些,还有图像金字塔

图像金字塔有什么用?为什么要称作图像金字塔?本文带你研究这些问题。

2 什么是图像金字塔?

正如生物视觉系统会处理分层次的尺寸一样,计算机视觉系统实现多分辨率图像处理的基础是图像金字塔

考虑这样一个场景:输入系统一幅图像来检测人脸。由于事先并不知道人脸在这张图片中可能的尺寸,所以需要根据输入生成一个不同大小图像组成的金字塔(应用时常用向量存储),扫描不同层次来检测可能的人脸。

此外,图像金字塔在保持细节的条件下进行图像融合等多尺度编辑操作非常有用。

图像金字塔分为两种:

  • 高斯金字塔
    高斯金字塔是最基本的图像金字塔,用于获得原图像尺度连续的的降采样序列。高斯金字塔共分 O O 组(Octave),每组分为 S S 层(Layer)。组内各层图像分辨率相同但尺度逐层递增;组间图像按隔点降采样取得。
    在这里插入图片描述
  • 拉普拉斯金字塔
    拉普拉斯金字塔通过高斯差分得到残差图像序列,用于图像重建、图像融合、特征点检测等。具体做法如图所示:构造高斯金字塔,每组图像内相邻两层相减得到残差图像序列,从而得到拉普拉斯金字塔。所以高斯金字塔每组有 s + 3 s+3 层,而拉普拉斯金字塔每组只有 s + 2 s+2 层。
    在这里插入图片描述

3 图像金字塔有什么用?

前面已经提到,图像金字塔的作用主要有:

  • 图像重建
  • 图像多尺度特征检测
  • 图像修复
  • 图像融合

下面给出一个基于图像金字塔的图像融合算法。

  1. 选择待融合图像A与B,以及融合掩码M,并重采样使之具有相同大小;
  2. 分别取得A、B的拉普拉斯金字塔,以及M的高斯金字塔;
  3. 使用M的高斯金字塔作为加权,对A、B的每层特征进行融合,得到融合金字塔;
    在这里插入图片描述
  4. 融合金字塔仍为拉普拉斯金字塔,对其图像重建得到融合图像。

上面的图可能有点抽象,看看下面的例子。

在这里插入图片描述

4 OpenCV实战图像金字塔

主函数非常简单易懂

int main()
{
	Mat img_1 = imread("1.jpg", 1);
	Mat img_2 = imread("2.jpg", 1);
	Mat dstImg;
	imgFusion(img_1, img_2, dstImg, 0.2);
	waitKey(0);
	return 0;
}

试试效果

原图
815068bd2f8c48e4bb12f448b80dc252[1].png
a46cdff344364c20a1f3fd12308e6e35[1].png

融合效果图

d3335d96afa64579bcecc59fbea727f5[1].png

是不是毫无违和感?其中关键的融合函数imgFusion()具体是如何实现的呢?

void imgFusion(Mat leftImg, Mat rightImg, Mat& dstImg, float threshold)
{
	vector<Mat> gaussPyrLeft, gaussPyrRight, laplacePyrLeft, laplacePyrRight;		// 声明高斯金字塔数据结构
	vector<Mat> maskGaussPyr;														// 声明掩码的高斯金字塔
	vector<Mat> blendLapPyr;														// 声明融合拉普拉斯金字塔
	Mat imgHighest;																	// 声明图像融合的起点图像
	Mat mask = Mat::zeros(PYRHEIGHT, PYRWIDTH, CV_32FC1);							// 构造掩码,大小与金字塔原图像相同
	mask(Range::all(), Range(mask.cols * threshold, mask.cols)) = 1.0;
	cvtColor(mask, mask, COLOR_GRAY2BGR);											// 将掩码颜色通道拓展,以适配原图像
	buildGaussPyr(mask, maskGaussPyr, 3);											// 建立掩码的高斯金字塔

	resize(leftImg, leftImg, Size(PYRWIDTH, PYRHEIGHT));
	resize(rightImg, rightImg, Size(PYRWIDTH, PYRHEIGHT));

	leftImg.convertTo(leftImg, CV_32F);		//转换成CV_32F, 用于和mask类型匹配,且CV_32F 类型精度高, 有利于计算
	rightImg.convertTo(rightImg, CV_32F);

	// 建立高斯金字塔与拉普拉斯金字塔
	buildGaussPyr(leftImg, gaussPyrLeft, 3);
	buildGaussPyr(rightImg, gaussPyrRight, 3);
	buildLaplacePyr(gaussPyrLeft, laplacePyrLeft, 3);
	buildLaplacePyr(gaussPyrRight, laplacePyrRight, 3);

	// 确定起点图像
	imgHighest = gaussPyrLeft.back().mul(maskGaussPyr.back()) +
		((gaussPyrRight.back()).mul(Scalar(1.0, 1.0, 1.0) - maskGaussPyr.back()));

	// 融合拉普拉斯金字塔
	blendLaplacePyr(laplacePyrLeft, laplacePyrRight, maskGaussPyr, blendLapPyr);

	// 融合图像重建
	dstImg = imgLaplaceBlend(imgHighest, blendLapPyr);
	dstImg.convertTo(dstImg, CV_8UC3);
	imshow("imgProcess::seamOpt_laplace", dstImg);
}

限于篇幅,其中部分函数的实现无法贴完整,全套代码工程文件关注下方公众号回复“CV003”获取,已经给你们打包好了哦~


🚀 计算机视觉基础教程说明

章号                                    内容
  0               色彩空间与数字成像
  1               计算机几何基础
  2               图像增强、滤波、金字塔
  3               图像特征提取
  4               图像特征描述
  5               图像特征匹配
  6               立体视觉
  7               项目实战

🔥 更多精彩专栏

👇配套代码 · 优质体验 · 系统知识 请关注👇


【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。