目的:
使用OpenCV中的函数 cv::pyrUp 和 cv::pyrDown 对给定的图像下采样和上采样(downsample 和 upsample).
理论
- 一般需要把图像的尺寸调整为和原图不一样的大小。有两种方法:
- Upsize(扩大) the image (zoom in) or
- Downsize(缩小) it (zoom out).
- OpenCV 中存也有一个几何变换函数 cv::resize 。本节将分析在图像视觉中广泛使用的图像金字塔中的使用。
图像金字塔
- 图像金字塔是一组图像的集合--从一个单一的原始图像开始,依次下采样直到达到预期的条件为止
- 有两种常见的图像金字塔类型:
Gaussian pyramid: 用于降采样图像
Laplacian pyramid: 用于从图像金字塔较低层(分辨率较低)重建上采样图像
- 在本教程中,我们将使用高斯金字塔。
高斯金字塔(Gaussian Pyramid)
图像金字塔有一系列的层构成,层越高尺寸越小。
- 每一层从低到顶编号,所以层 (i+1) (denoted as Gi+1 )比层i ( Gi)小.
-
在高斯金字塔中生成层(i+1) ,需要按照如下步骤:
- 对 Gi 用高斯核卷积:
116⎡⎣⎢⎢⎢⎢⎢1464141624164624362464162416414641⎤⎦⎥⎥⎥⎥⎥- 删除每一个偶数行和列.
- 可以注意到结果图像的面积是上一层面积的四分之一.对输入图像G0 (原始图像)迭代这个过程得到整个金字塔。
- 以上处理过程为对一个图像下采样. 如果想让它变大?: 用0来填充列
- First, upsize the image to twice the original in each dimension, wit the new even rows and
- Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the values of the "missing pixels"
- 这两个程序(下采样和上采样)由OpenCV函数实现cv::pyrup和cv::pyrdown, 例子见下面代码
- 备注
- 减少图像的大小,会导致图像信息的丢失.
代码
/**
* @file Pyramids.cpp
* @brief Sample code of image pyramids (pyrDown and pyrUp)
* @author OpenCV team
*/
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
/// Global variables
Mat src, dst, tmp;
const char* window_name = "Pyramids Demo";
/**
* @function main
*/
int main( void )
{
/// General instructions
printf( "\n Zoom In-Out demo \n " );
printf( "------------------ \n" );
printf( " * [u] -> Zoom in \n" );
printf( " * [d] -> Zoom out \n" );
printf( " * [ESC] -> Close program \n \n" );
//![load]
src = imread( "../data/chicky_512.png" ); // Loads the test image
if( src.empty() )
{ printf(" No data! -- Exiting the program \n");
return -1; }
//![load]
tmp = src;
dst = tmp;
//![create_window]
imshow( window_name, dst );
//![create_window]
//![infinite_loop]
for(;;)
{
int c;
c = waitKey(0);
if( (char)c == 27 )
{ break; }
if( (char)c == 'u' )
{
//![pyrup]
pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
//![pyrup]
printf( "** Zoom In: Image x 2 \n" );
}
else if( (char)c == 'd' )
{
//![pyrdown]
pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
//![pyrdown]
printf( "** Zoom Out: Image / 2 \n" );
}
imshow( window_name, dst );
//![update_tmp]
tmp = dst;
//![update_tmp]
}
//![infinite_loop]
return 0;
}
结果
-
图像 chicky_512.jpg 大小为512×512, 下采样不会产生任何错误( 512=29). 原图如下
-
首先,连续两次使用 cv::pyrDown ,通过按键'd'实现.输出如下:
-
注意到由于降采样已经丢失了一些信息. 这个在使用两次 cv::pyrUp 后可以看到 (按键 'u'). 结果如下:
-