【小白】Open-CV 学习笔记 - 6.6 图像金字塔于图片尺寸缩放

图像金字塔

  • 图像金字塔是图像中多尺度表达的一种,最主要用于图像分割,是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔式一系列以金字塔形状排列的,分辨率逐步降低且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到到达某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。层级越高图像越小,分辨率越低。

在这里插入图片描述

通常有两种类型的图像金字塔,分别是:

  • 数字金字塔(Gaussuan pyramin)-用来向下采样,主要的图像金字塔,主要用来向下采样图像
  • 拉普拉斯金字塔(Laplaican pyramid)-用来从金字塔底层图像重建上层未采样的还原,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用,是从金字塔底层图像中向上采样,重建一个图像。

要从金字塔的第i层生成第i+1层(将第i层表示为Gi),先要用高斯核对Gi进行卷积,然后删除所有偶数行和列,新得到的图像面积会变为源图像的1/4.按上述过程对输入图像G0执行操作就可以得到整个金字塔。

当图像金字塔的上层移动时,尺寸和分辨率会降低。在OpenCV中,从金字塔上一层图像生成下一级图像时可以使用PryDown,而通过PryUp将现有的图像在每个维度上放大两倍。

注意:PryDown和PryUp函数互逆的,PryUp不是降采样的逆操作。图像首先在每个维度上扩大为原来的两倍,新增的行(偶数行)以0填充,然后给指定的滤波器进行卷积(实际上是在每个维度都扩大为原来两倍的过滤器)去估计“丢失”像素的近似值。

1.高斯金字塔

  • 高斯金字塔是通过高斯平滑和亚采样获得一些采样图像,即是第K层高斯金字塔通过平滑、亚采样就可以获得第K+1层高斯图像。高斯金字塔包括一些列的低通滤波器,其截止频率从上一层到下一层以因子2逐渐增加,所以高斯金字塔可以跨越很大的频率范围。
    在这里插入图片描述

a.对图像向下采样
为了获得第G(i+1)的金字塔图像,采取如下方法:

  1. 对图像G(i)进行高斯内核卷积
  2. 将所有偶数列和偶数行去除

得到的图像即为G(i+1)的图像,很明显G(i+1)只有源图像的四分之一,通过对输入图像G(i)(原始图像)不停的迭代上述步骤就会得到整个金字塔,即向下采样会丢失图像的信息,缩小了图像

b.对图像的向上采样
如果想放大图像,则需要通过向上取样操作得到

  1. 将图像在每个方向上扩大为原来的两倍,新增的行和列以0填充
  2. 使用先前同样的内核(乘以4)与放大后的图像卷积,获得“新增像素”的近似值。

得到的图像即为放大后的图像,但是与源图像想必会发现比较模糊,因为在缩放中已经丢失了一些信息。如果想在缩放过程中减少信息的丢失,这些数据就形成了拉普拉斯金字塔。

2.拉普拉斯金字塔

第i层的拉普拉斯金字塔的数学定义为:
L(i) = G(i) -UP(G(i+1))&g

式中的G(i)表示第i层的图像,UP()操作是将源图像中位置为(x,y)的像素映射到目标图像的(2X+1,2Y+1)位置,即在进行向上取样,&表示卷积,g为5*5的高斯内核.
使用OpenCV中函数直接进行拉普拉斯运算: L(i) = G(i) -PryUP(G(i+1))

图像金字塔的一个重要应用就是图像分割

3.尺寸调整:resize()函数

resize()函数是OpenCV中专门用来调整图像大小的函数
此函数将源图像精确的转换为指定尺寸的目标图像。如果源图像中设置了ROI(Region Of Internet,感兴趣区域),那么resize()函数会对源图像的ROI区域进行调整图像尺寸的操作,来输出到目标图像中。若目标中已经设置了ROI区域,不难理解resize()函数将会对源图像进行尺寸调整并填充到目标图像的ROI中。

C++:void resize(InputArray src,OutputArray dst,Size dsize,double fx = 0,double fy = 0,int interpolation = INTER_LINEAR)
很多时候不用考虑第二个参数dst的初始图像尺寸和类型(即直接定义一个Mat类型的对象,不用对其初始化),因为其尺寸和类型可以由src,dsize,fx,fy这几个参数来确定。

  • 参数一:输入图像,即源图像
  • 参数二:输出图像,当其非零时,有着dsize的尺寸,或者由src.size()计算出来
  • 参数三:输出图像的大小,如果为0,由下式计算
    dsize = Size(round(fxsrc.cols),round(fysrc.rows))
    其中dsize,fx,fy都不能为0
  • 参数四:沿水平轴的缩放系数,有默认值0,当其不为0时,由下式进行计算:
    (double)dsize.width/src.cols
  • 参数五:沿垂直轴的缩放系数,有默认值0,当其不为0时,由下式进行计算:
    (double)dsize.height/src.rows
  • 参数六:用于指定插值模式,默认为INTER_LINEAR
    在这里插入图片描述
    若要缩小图像,推荐使用CV_INTER_AREA来插值,若要放大图像,推荐使用CV_INTER_CUBIC(效率不高)或者CV_INTER_LINEAR(效率高)

resize()函数调用示例:

// resize.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
 
int _tmain(int argc, _TCHAR* argv[])
{
    //载入源图像
    Mat srcImage = imread("1.jpg");
	Mat tempImage,dstImage1,dstImage2;//临时变量和目标图的定义
	tempImage = srcImage;//将原始图复制临时变量
 
	imshow("[源图像]",srcImage);
 
	//进行尺寸调整
	resize(tempImage,dstImage1,Size(tempImage.cols/2,tempImage.rows/2),(0,0),(0,0),3);
	resize(tempImage,dstImage2,Size(tempImage.cols*2,tempImage.rows*2),(0,0),(0,0),3);
 
	imshow("[效果图一]",dstImage1);
	imshow("[效果图二]",dstImage2);
 
	waitKey(0);
	return 0;
}

在这里插入图片描述

4.向上采样:PryUp()函数

PryUp()函数的作用是向上采样并模糊一张图像,说白了就是放大一张图片

C++:void pyrUp(InputArray src,OutputArray dst,const Size& dstsize = Size(),
		int borderType = BORDER_DEFAULT)
  • 参数二:输出图像,和输入图像有一样的尺寸和类型

  • 参数三:输出图像的大小,有默认值Size(),即默认情况下,由Size(src.cols2,src.rows2)来计算, 且一直需要满足下列条件:

      			|dstsize.width - src.cols*2| <= (dstsize.width mod 2)
      			|dstsize.height - src.rows*2| <= (dstsize.height mod 2)
    
  • 参数四:边界模式,一般不用理睬

首先通过插入为零的行和列,对源图像进行向上采样操作,然后将结果与pyrDown()乘以4的内核做卷积,示例如下:

// pyrUp.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
 
int _tmain(int argc, _TCHAR* argv[])
{
	//载入图像
    Mat srcImage = imread("1.jpg");
 
	Mat tmpImage,dstImage;
	tmpImage = srcImage;
 
	imshow("[源图像]",srcImage);
	pyrUp(tmpImage,dstImage,Size(tmpImage.cols*2,tmpImage.rows*2));
	imshow("[效果图]",dstImage);
 
	waitKey(0);
	return 0;
}

在这里插入图片描述

5.向下采样:pyrDown()函数

pyrDown()函数的作用是向下采样并模糊一张照片,就是缩小一张图片

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

  • 参数二:输出图像,尺寸和类型和源图像一致

  • 参数三:输出图像的大小,有默认值Size(),即默认情况下,由Size Size((src.cols+1)/2,(src.rows+1)/2)来进行计算,且一直需要满足下列条件:

      |dstsize.width*2 - src.cols| <= 2
      |dstsize.height *2- src.rows| <= 2
    

该pryDown函数执行了高斯金字塔建造的向下采样的步骤,首先将源图像与如下内核做卷积:
在这里插入图片描述
接着通过对偶数行和偶数列做插值来进行向下采样操作,示例如下:

// pyrUp.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
 
int _tmain(int argc, _TCHAR* argv[])
{
	//载入图像
    Mat srcImage = imread("1.jpg");
 
	Mat tmpImage,dstImage;
	tmpImage = srcImage;
 
	imshow("[源图像]",srcImage);
	//pyrUp(tmpImage,dstImage,Size(tmpImage.cols*2,tmpImage.rows*2));
	pyrDown(tmpImage,dstImage,Size(tmpImage.cols/2,tmpImage.rows/2));
	imshow("[效果图]",dstImage);
 
	waitKey(0);
	return 0;
}

在这里插入图片描述

发布了34 篇原创文章 · 获赞 8 · 访问量 1884

猜你喜欢

转载自blog.csdn.net/weixin_43583163/article/details/97180045
今日推荐