本文主要实现对输入图像的上采样和下采样操作,使用到pyrUP和pyrDown两个函数来对分别对图像进行上采样和下采样。
图像金字塔是一系列图像集合,它们从源图像连续的进行下采样,直到需要的位置才停止操作。
两种常见的图像金子塔如下所述:
1.高斯金字塔:用于下采样图像。
2.拉普拉斯金字塔:用于把下层低分辨率的图像进行上采样重建。
本文用到的是高斯金字塔。
1)高斯金字塔图形如下所示,越往上,图像的分辨率(大小)越小。
2)每层的计数从底层开始,即(i+1),注:Gi+1要比Gi层分辨率小!
3)产生i+1层的操作如下所述:
首先,用高斯核和Gi层进行卷积,高斯核大小为16*16;
然后,移走每个偶数行和列。
4)很容易观测到处理的结果即是前一层的1/4。从G0(原始输入图像)递归这个处理过程,就可以产生整个金字塔。
5)上面所述的处理过程很适合应用到对图像的下采样操作。
如果我们想使图像变的大一些,怎么办呢?
首先,增大图像的每个维度(一般为高度和宽度)为原来的两倍。把新的偶数行和列置零。
然后,用上面使用的高斯核进行卷积操作,记得要乘以4,以此来逼近丢失的像素值。
上面所述的两个处理过程,即对图像的下采样和上采样,本文用pyrUp和pyrDown两个函数来实现。
具体实现代码如下所示:
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <math.h> #include <stdlib.h> #include <stdio.h> using namespace cv; //全局变量 Mat src, dst, tmp; const char* window_name = "Pyramids Demo"; int main( void ) { //函数功能信息 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" ); //测试图像必须是2^(n) src = imread("D:\\lena.bmp"); if( !src.data ) { printf(" No data! -- Exiting the program \n"); return -1; } tmp = src; dst = tmp;//交换图像信息 //创建输出显示窗口 namedWindow( window_name, CV_WINDOW_AUTOSIZE ); imshow( window_name, dst ); //循环操作 for(;;) { int c; c = waitKey(10); if( (char)c == 27 )//按下键盘的"ESC"退出程序 { break; } if( (char)c == 'u' )//按下键盘的"u"进行上采样操作 { //tmp:原图像 ,dst:输出图像,是原图像的两倍, //Size:dst图像的大小,行和列扩大2倍 pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) ); printf( "** Zoom In: Image x 2 \n" ); } else if( (char)c == 'd' )//按下键盘的"d"进行下采样操作 { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) ); printf( "** Zoom Out: Image / 2 \n" ); } //创建输出显示窗口 imshow( window_name, dst ); tmp = dst;//更新temp值为了更好的递归操作 } return 0; }