6 图像金字塔与图像尺寸缩放
opencv提供尺寸缩放的方法
- resize函数
- pyrUp(),pyrDOwn()函数,对图像进行向上采样和向下采样
6.1 关于图像金字塔
图像金字塔主要用于图像分割
- 高斯金字塔:向下采样,主要的图像金字塔
- 拉普拉斯金字塔:用来从金字塔底层图像重建上层未采样的图像
- 区别:高斯金字塔用来向下采样图像,拉普拉斯金字塔用来从底层图像向上采样,重建一个图像。
向上就是图像尺寸加倍,向下就是图像尺寸减半
6.2 高斯金字塔
6.2.1 对图像的向下取样
为了获取层级未
的金字塔图像
(1):对图像
进行高斯内核卷积
(2):将所有偶数行和列去除
结果图像减少为原来图像的四分之一
6.2.2 对图像的向上取样
(1):将图像在每个方向上扩大为原来的两倍,新增的行和列以0填充
(2):使用先前同样的内核(乘以4)与放大的图像卷积,获取新增像素的近似值
6.3 拉普拉斯金字塔
数学定义
6.4 尺寸调整:resize()函数
此函数将源图像精确地转换为指定尺寸的目标函数图像,函数原型
void resize(InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR)
第三个参数:Size类型的dsize,输出图像的大小,如果等于零,由公式决定
第四个参数:fx表示沿水平轴的缩放系数,默认值为0,当等于0的时候
- 第五个参数:fy表示,沿垂直轴的缩放系数,默认值为0,
- 第六个参数,int类型的interpolation,用于指定插值的方式。
- INTER_NEAREST最近邻插值
- INTER_LINEAR线性插值
- INTER_AREA区域插值
- INTER_CUBIC三次样条插值
- INTER_LANCZOS4 lanczos插值
6.5 图像金字塔API函数
6.5.1向上采样:pyrUp()函数
void pyrUp(InputArray src, OutputArray dst,const Size & dstsize = Size(),int borderType = BODER_DEFAULT)
- 第三个参数 默认值为Size(src.cols*2,src.rows*2)
6.5.2 pyrDown()函数
void pyrDown(InputArray src, OutputArray dst,const Size & dstsize=Size(),int borderType = BORDER_DEFAULT)
- 第三个参数:Size (src.cols/2,src,rows/2)满足的条件
6.6 综合示例
//头文件和命名空间
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
//宏定义
#define WINDOW_NAME "【程序窗口】"
//全局变量
Mat g_srcImage, g_dstImage, g_tmpImage;
//main函数
int main()
{
//载入图像
g_srcImage = imread("1.jpg");
if (!g_srcImage.data)
{
printf("读取srcImage错误~!\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 'q':
return 0;
break;
//图像放大的相关方法
case 'a':
pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
printf(">检测到按键[A]被按下,开始进行基于[pyrUp]函数的图像放大:图片尺寸×2\n");
break;
case 'w':
resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
printf(">检测到按键[w]被按下,开始进行基于[resize]函数的图像放大:图片尺寸×2\n");
case '1':
resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
printf(">检测到按键[1]被按下,开始进行基于[resize]函数的图像放大:图片尺寸×2\n");
break;
case '3':
pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
printf(">检测到按键[3]被按下,开始进行基于[pyrUp]函数的图像放大:图片尺寸×2\n");
break;
//缩小操作
case 'd':
pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
printf(">检测到按键[d]被按下,开始进行基于[pyrDown]函数的图像缩小:图片尺寸/2\n");
break;
case 's':
resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
printf(">检测到按键[s]被按下,开始进行基于[resize]函数的图像缩小:图片尺寸/2\n");
break;
case '2':
resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
printf(">检测到按键[2]被按下,开始进行基于[resize]函数的图像缩小:图片尺寸/2\n");
break;
case '4':
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_tmpImage = g_dstImage;
}
return 0;
}