opencv——上采样与降采样

图像金字塔

在这里插入图片描述
这个也可以看做金字塔,如果我们把一个小方格当成一个二值图像的像素,那么我们可以从最底层变到最高层,也可以从最高层变到最底层。
那如果这是一个图像的话,从上往下,我们就实现了图像的放大,从下往上就实现了图像的缩小。

这就想金字塔一样,是四棱锥

一个图像金字塔就是一系列的图像组成。最下方是尺寸最大,最上方是尺寸最小。

为什么要使用图像金字塔

几何变换同样能放大缩小(双线性差值、双立方差值)。

我们要通过图像金字塔来产生一系列不同分辨率的图像,然后在不同的尺度空间来寻找图像对应的特征。因为我们不知道我们输入的图像是什么情况。

图像的金字塔变换会保证图像的特征一直存在

我们可以利用这样的四棱锥进行进行图像的缩放,我们将这个四棱锥称之为:图像金字塔

而图像的放大与缩小分别称之为上采样和降采样或下采样

上采样与降采样

上采样就是放大图像,通过放大图像,我们可以增加图像的像素,从而可以得到更高的分辨率。

降采样就是缩小图像,通过缩小图像,我们可以减少图像的像素,一方面,我们可以生成对应图像的缩略图,另一方面,我们可以减少图像的大小,节约内存。

但是我们通过上采样的得到的图,和经过缩小的图像的原图还是有区别的,因为我们很难真正获得图像的原始位置的像素,所以通过上采样得到的图,可能会看着不是那么清晰,那么流畅,图像质量不是那么的好。

上采样与降采样不仅能改变图像的清晰度(分辨率),也能改变图像的大小

接下来我们着重讲两个图像金字塔:高斯金字塔和拉普拉斯金字塔

高斯金字塔

高斯金字塔是从底向上,用于对图像进行降采样。
高斯金字塔对原图像删除偶数行与列,即得到降采样之后上一层的图片。所以经过一次高斯金字塔,图像的行列变为原来的1/2 。

具体的步骤分为两步:

  • 1.进行高斯模糊

  • 2.删除当前层的偶数行与列。
    即可得到上一层的图像,这样上一层跟下一层相比,都只有它的1/4大小。

高斯不同

做了高斯金字塔后,要得到每层中的图像特征。我们就可以通过高斯不同或拉普拉斯不同。

把同一张图像在不同的参数下做高斯模糊之后的结果相减,得到的输出图像。称为高斯不同(Difference of Gaussian-DOG)。

高斯不同是图像的内在特征,在灰度图像增强、角点检测中经常用到。

拉普拉斯金字塔

拉普拉斯金字塔很高斯金字塔不同,是用其上层的图像,获得其下层的图像

  • 我们可以通过高斯金字塔进行图像的降采样
  • 可以使用拉普拉斯金字塔进行图像的上采样

图像的金字塔变换会保证图像的特征一直存在

相关API

示例

pyrUp(Mat src, Mat dst, Size(src.cols*2, src.rows*2)) 
//生成的图像是原图在宽与高各放大两倍
pyrDown(Mat src, Mat dst, Size(src.cols/2, src.rows/2))
//生成的图像是原图在宽与高各缩小1/2

上采样

void pyrUp( 
    InputArray src, 
    OutputArray dst,                         
    const Size& dstsize = Size(), 
    int borderType = BORDER_DEFAULT 
);
  • (1)InputArray类型的src ,输入图像

  • (2)OutputArray类型的dst ,输出图像,图像的大小是规定的(根据参数3)和输入图像有相同的类型。

  • (3)Size类型的指针dstsize ,设定的输出图像大小

  • (4)int类型的borderType ,像素外推方法,请参见cv::BorderTypes(仅支持BORDER_DEFAULT)。

降采样

void pyrDown( 
    InputArray src, 
    OutputArray dst,                         
    const Size& dstsize = Size(), 
    int borderType = BORDER_DEFAULT 
);
  • (1)InputArray类型的src ,输入图像。

  • (2)OutputArray类型的dst ,输出图像,图像的大小是规定的(根据参数3)和输入图像有相同的类型。

  • (3)Size类型的指针dstsize ,设定的输出图像大小。

  • (4)int类型的borderType ,像素外推方法,请参见cv::BorderTypes(仅支持BORDER_DEFAULT)。

上采样函数和降采样函数的图像一般在使用过程中,我们只设置前三个参数。

上采样与降采样代码实现

代码

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    
    
	Mat img, src;
	img = imread("C:/Users/86176/Pictures/pics/lena(1).tiff");
	if (!img.data)
	{
    
    
		cout << "could not load image !;"
			return -1;
	}
	imshow("show img", img);
	pyrUp(img, src, Size(img.cols * 2, img.rows * 2));
	imshow("output up image", src);
	pyrDown(img, src, Size(img.cols / 2, img.rows / 2));
	imshow("output down image", src);

	waitKey(0);
	return 0;
}

效果

在这里插入图片描述

先降采样再上采样代码实现

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    
    
	Mat img;
	img = imread("C:/Users/86176/Pictures/pics/lena(1).tiff");
	if (!img.data)
	{
    
    
		cout << "could not load image !";
		return -1;
	}
	imshow("show img", img);

	pyrDown(img, img, Size(img.cols / 2, img.rows / 2));
	pyrUp(img, img, Size(img.cols * 2, img.rows * 2));
	imshow("output down image", img);

	waitKey(0);
	return 0;
}

在这里插入图片描述
结果比之前模糊,可以达到一个图像压缩的效果。

高斯不同代码实现

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    
    
	Mat src;
	src = imread("C:/Users/86176/Pictures/pics/lena(1).tiff");
	if (!src.data)
	{
    
    
		cout << "could not load image !";
		return -1;
	}
	imshow("show img", src);

	//dog
	Mat gray, img1, img2, dogimg, dst;
	cvtColor(src, gray, CV_BGR2GRAY);
	GaussianBlur(gray, img1, Size(3,3),0,0);
	GaussianBlur(img1, img2, Size(3,3),0,0);
	
	subtract(img1, img2, dogimg, Mat());
	imshow("DOG img", dogimg);
	//将dog图像映射到0~255,否则像素值小,看不清
	normalize(dogimg, dst, 255, 0, NORM_MINMAX);
	//第五个参数的含义,找出原图最大最小值差值▲,将输入图像每个像素减去最小值除以▲再乘最大值
	imshow("DOG img dst", dst);
	waitKey(0);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_28258885/article/details/112769618