《OpenCV3编程入门》学习笔记6 图像处理(六)图像金字塔与图片尺寸缩放

6.6 图像金字塔与图片尺寸缩放

6.6.1 图像金字塔

1.图像金字塔是图像中多尺度表达的一种,主要用于图像分割,是一种以多分辨率解释图像的结构,通过梯次向下采样获得分辨率逐步降低的图象集合
2.分类:
  (1)高斯金字塔(Gaussianpyramid):向下采样
  (2)拉普拉斯金字塔(Laplacianpyramid):从金字塔底层图像重建上层未采样图像,在数字图像处理中即是预测残差,可以对图像进行最大程度地还原,配合高斯金字塔一起使用
3.涉及函数
  pyrUp函数和pyrDown函数,2个函数在imgproc的Image Filtering子模块中,pyrUp和pyrDown不互逆

6.6.2 高斯金字塔

1.高斯金字塔通过高斯平滑和亚采样进行向下采样,包含了一系列低通滤波器,截止频率从上一层到下一层以因子2逐渐增加
2.方法
  对金字塔第i层Gi进行高斯内核卷积,然后删除所有偶数行和偶数列,新得到图像Gi+1面积会变为原图像的1/4,可对输入图像迭代产生金字塔
3.pyrDown函数
  向下采样(图像尺寸减半),生成下一级图像,是会丢失信息的函数
4.函数原型:

void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT)

5.参数说明:
(1)输入图像
(2)目标图像
(3)输出图像大小,默认值Size(),默认时由Size((src.cols+1)/2,(src.row+1)/2)计算,需满足:
                 |dstsize.width*2-src.cols|<=2
                 |dstsize.height*2-src.rows|<=2
(4)边界模式
6.调用示例:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;

int main()
{
	//载入原始图
	Mat srcImage = imread("love.jpg");
	Mat dstImageDown;
	//显示原始图
	namedWindow("【原始图】");
	imshow("【原始图】", srcImage);
	//向下取样操作
	pyrDown(srcImage, dstImageDown, Size(srcImage.cols / 2, srcImage.rows / 2));
	//显示效果图
	namedWindow("【向下取样效果图】");
	imshow("【向下取样效果图】", dstImageDown);
	waitKey(0);
	return 0;
}

6.6.3 拉普拉斯金字塔

1.数学定义
                    在这里插入图片描述
式中,Gi表示第i层图像,UP()操作时将原图像中位置为(x,y)的像素映射到目标图像的(2x+1,2y+1)位置,即在向上取样,符号在这里插入图片描述表示卷积,在这里插入图片描述表示5*5的高斯内核
2.方法
  将现有图像每个维度都放大两倍,新增行和列(偶数行和列)以0填充,然后使用先前同样的内核(乘以4)与放大后的图像卷积,来估计“丢失”像素的近似值
3.pyrUp函数:向上采样(图像尺寸加倍),利用函数进行拉普拉斯运算:
                    在这里插入图片描述
4.函数原型:

void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borserType=BORDER_DEFAULT)

5.参数说明
(1)输入图像
(2)目标图像
(3)输出图像大小,默认值Size(),默认时由Size(src.cols*2,src.row*2)计算,需满足:
                |dstsize.width-src.cols*2|<=(dstsize.width mod2)
                |dstsize.height-src.rows*2|<=(dstsize.height mod2)
(4)边界模式
6. 调用示例:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;

int main()
{
	//载入原始图
	Mat srcImage = imread("love.jpg");
	Mat dstImageUp;
	//显示原始图
	namedWindow("【原始图】");
	imshow("【原始图】", srcImage);
	//向上取样操作
	pyrUp(srcImage, dstImageUp, Size(srcImage.cols * 2, srcImage.rows * 2));
	//显示效果图
	namedWindow("【向上取样效果图】");
	imshow("【向上取样效果图】", dstImageUp);
	waitKey(0);
	return 0;
}

6.6.4 尺寸调整函数:resize()函数

    函数resize函数在imgproc模块的Geometric Image Transformations子模块中

1.函数原型

void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)

2.参数说明:
(1)输入图像
(2)目标图像
(3)输出图像大小,等于0时由下式计算图像大小:
            dsize=Size(round(fx*src.cols),round(fy*src.rows))
(4)水平轴的缩放系数,默认0,等于0时由下式计算:
                (double)dsize.width/src.cols
(5)垂直轴的缩放系数,默认值0,等于0时由下式计算:
                (double)dsize.height/src.rows
(6)插值方式,默认为INTER_LINEAR(线性插值),可选插值方式有:
    INTER_NEAREST–最近邻插值
    INTER_LINEAR–线性插值(默认,放大图像,效率高)
    INTER_AREA–区域插值(利用像素区域关系的重采样插值,缩小图像)
    INTER_CUBIC–三次样条插值(超过4*4像素领域的双三次插值,放大图像,效率低)
    INTER_LANCZOS4–Lanczos插值(超过8*8像素领域的Lanczos插值)

3.调用示例:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;

int main()
{
	/*
		//调用方式1
		Mat dstImage = Mat::zeros(512, 512, CV_8UC3);//新建一张512*512尺寸的图片
		Mat srcImage = imread("love.jpg");
		resize(srcImage, dstImage, dstImage.size());//指定dsize=dstImage.size(),fx和fy会被计算不需要额外指定
		//调用方式2
		Mat dstImage;
		Mat srcImage = imread("love.jpg");
		resize(srcImage, dstImage, Size(), 0.5, 0.5);//指定fx和fy
	*/
	//载入原图
	Mat srcImage = imread("love.jpg");
	Mat dstImage1, dstImage2;
	//显示原图
	namedWindow("【原始图】");
	imshow("【原始图】", srcImage);

	//尺寸调整操作
	resize(srcImage, dstImage1, Size(srcImage.cols / 2, srcImage.rows / 2), 0.0, 0.0, 3);
	resize(srcImage, dstImage2, Size(srcImage.cols * 2, srcImage.rows * 2), 0.0, 0.0, 3);
	//显示效果图
	imshow("【效果图1】", dstImage1);
	imshow("【效果图2】", dstImage2);

	waitKey(0);
	return 0;
}

6.6.5 综合示例

/*
效果:
	键盘1、2、3、4控制图片放大与缩小
*/

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

#define WINDOW_NAME "【程序窗口】"
Mat g_srcImage, g_dstImage, g_tmpImage;

//键盘操作说明
static void ShowHelpText()
{
	printf("--------------------------------------------------------------------\n");
	printf("欢迎来到OpenCV图像金字塔和resize示例程序~\n");
	printf("按键操作说明:\n");
	printf("\t\t键盘按键[ESC]-退出程序\n");
	printf("\t\t键盘按键[1]-进行[resize]函数图片放大\n");
	printf("\t\t键盘按键[2]-进行[resize]函数图片缩小\n");
	printf("\t\t键盘按键[3]-进行[pyrUp]函数图片放大\n");
	printf("\t\t键盘按键[4]-进行[pyrDown]函数图片缩小\n");
	printf("--------------------------------------------------------------------\n");
}
int main()
{
	//键盘操作说明
	ShowHelpText();

	//载入原图
	g_srcImage = imread("love.jpg");
	if (!g_srcImage.data)
	{
		printf("载入原图失败~!\n");
		return false;
	}
	//创建显示窗口
	namedWindow(WINDOW_NAME,WINDOW_AUTOSIZE);
	imshow(WINDOW_NAME, g_srcImage);

	//参数赋值
	g_tmpImage = g_srcImage;
	g_dstImage = g_tmpImage;
	int key = 0;

	//轮询获取按键信息
	while (1)
	{
		key = waitKey(9);//读取键值到变量
		//根据key值,做不同操作
		switch (key)
		{
		case 27: //按键ESC
			return 0;
			break;
		case '1':  //按键【1】,调用resize函数
			resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
			printf(">检测到按键【1】被按下,进行【resize】函数的图片放大,图片尺寸*2\n");
			break;
		case '2':  //按键【2】,调用resize函数
			resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
			printf(">检测到按键【2】被按下,进行【resize】函数的图片缩小,图片尺寸/2\n");
			break;
		case '3':  //按键【3】,调用pyrUp函数
			pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
			printf(">检测到按键【3】被按下,进行【pyrUp】函数的图片放大,图片尺寸*2\n");
			break;
		case '4':  //按键【4】,调用pyrDown函数
			pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
			printf(">检测到按键【4】被按下,进行【pyrDown】函数的图片缩小,图片尺寸/2\n");
			break;
		default:
			break;
		}
		imshow(WINDOW_NAME, g_dstImage);
		//将g_dstImage赋给g_tmpImage,方便下一次循环
		g_tmpImage = g_dstImage;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值