opencv中resize resize 与 金字塔 哪一个速度快

下次自动登录
现在的位置:
& 综合 & 正文
OpenCV图像处理篇之采样金字塔
转载请注明出处:
图像金字塔
图像金字塔是通过将原始图像经过平滑、下采样所生成一系列具有不同分辨率的图像的集合。金字塔结构(Pyramid)适于多分辨率处理的一种图像存储数据结构。
最常用的生成图像金字塔的方法是采用高斯函数平滑图像,每次将分辨率降低为原来的一半,由此得到一个图像序列{ML,ML-1,……,M0},图像金字塔的存储量为N^2*(1+1/4+1/16+...)=(4*N^2)/3。
如上图:最右边为原始图像,从右到左依次为使用高斯平滑1次、2次和3次后的图像,这些图像共同组成了图像金字塔。
图像金字塔这种结构在图像处理中有广泛的用途。最著名的特征匹配算子SIFT就是通过构造图像金字塔来完成的。有关图像金字塔在SIFT特征提取中的应用可参见Rachel Zhang的博文。
#include &iostream&
#include "cv.h"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace
const char *wn = "Pyramids Demo";
int main(int argc, char *argv[])
if (argc & 2) {
cout&&"Usage: ./pyramids "&&
return -1;
Mat src = imread(argv[1]);
if (!src.data) {
cout&&"Error: read image error."&&
return -1;
if ( src.cols & (src.cols-1) ) {
cout&&"Error: input image's column must be 2^n"&&
return -1;
if ( src.rows & (src.rows-1) ) {
cout&&"Error: input image's row must be 2^n"&&
return -1;
cout&&"User Guide:"&&
cout&&"---------------------"&&
-& Zoom out"&&
-& Zoom in"&&
cout&&"ESC -& Exit program"&&
namedWindow(wn, WINDOW_AUTOSIZE);
imshow(wn, src);
int end_while = 0;
while(!end_while) {
c = waitKey(10);
switch (c) {
end_while = 1;
pyrUp(cur, dst, Size(cur.cols*2, cur.rows*2));
imshow(wn, dst);
pyrDown(cur, dst, Size(cur.cols/2, cur.rows/2));
imshow(wn, dst);
使用高斯图像金字塔进行降采样和插值的函数分别是pyrDown和pyrUp,参数依次为原图像、采样结果图像、采样后的图像尺寸。
上述程序中的降采样操作因为都是按2为倍数进行的,因此要求输入图像的长宽都必须是2^n。if ( src.cols & (src.cols-1) )是用来判断原图像的列是否为2^n的语句。请仔细体会这种判断某个数是否是2^n的方法——x*(x-1)返回0表示x是2^n,否则不是。
下面一系列图片展现的是先将原图像通过图像金字塔降采样(会存在数据丢失),再通过金字塔插值恢复图像过程中图像的变化过程。由于降采样过程中存在数据丢失,所以可以看到恢复到原图像大小后的图像比原图像模糊。
图注 原图像
图注 1次降采样后的图像
图注 2次降采样后的图像
图注 2次降采样后,再经过1次图像金字塔插值操作后的图像,大小与1次降采样后图像相同,但变得模糊
图注 2次降采样后,再经过2次图像金字塔插值操作后的图像,大小与原图相同,但变得模糊
&&&&推荐文章:
【上篇】【下篇】opencv 图像金字塔 - 夏鸥易 - 博客园
蜗牛漫步。。。我要一步一步往上爬。。。
图像金字塔被广泛用于各种视觉应用中。图像金字塔是一个图像集合,集合中所有的图像都源于同一个原始图像,而且是通过对原始图像连续降采样活得,直到达到某个中止条件才停止降采样。(当然,降为一个像素肯定是中止条件。)
有两种类型的图像金字塔常常出现在文献和应用中:高斯金字塔用来向下降采样图像,而拉普拉斯金字塔则用来从金字塔低层图像中向上采样重建一个图像。
要从金字塔第&i&层生成第i+1&层,我们先要用高斯核对第i&层进行卷积,然后删除所有偶数行和偶数列。当然,新得到的图像面积会变为源图像的四分之一。按上述过程对输入图像循环执行操作就可产生整个金字塔。
Opencv为我们提供了从金字塔中上一级图像生成下一级图像的方法:cvPyrDown。同样,我们可以通过后面相似的函数(但不是降采样的逆操作)将现有的图像在每个维度上都放大两倍:cvPyrUp。在这种情况下,图像首先在每个维度上都扩大为原来的两倍,新增的行(偶数行)以0填充。然后给指定的滤波器进行卷积(实际上是一个在每一维上都扩大为两倍的过滤器)去估计”丢失“像素的近似值。
我们之前注意到函数cvPyrUp并不是函数cvPyrDown的逆操作。之所以这样是因为cvPyrDown是一个会丢失信息的函数。为了恢复原来(更高的分辨率)的图像,我们需要获得由降采样操作丢失的信息。
图像的下采样
void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );
输出图像, 宽度和高度应是输入图像的一半 ,传入前必须已经完成初始化
卷积滤波器的类型,目前仅支持 CV_GAUSSIAN_5x5
函数 cvPyrDown 使用 Gaussian 金字塔分解对输入图像向下采样。首先它对输入图像用指定滤波器进行卷积,然后通过拒绝偶数的行与列来下采样图像。
图像的上采样
void cvPyrUp( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );
输出图像, 宽度和高度应是输入图像的2倍
卷积滤波器的类型,目前仅支持 CV_GAUSSIAN_5x5
函数 cvPyrUp 使用Gaussian 金字塔分解对输入图像向上采样。首先通过在图像中插入 0 偶数行和偶数列,然后对得到的图像用指定的滤波器进行高斯卷积,其中滤波器乘以4做插值。所以输出图像是输入图像的 4 倍大小。(hunnish: 原理不清楚,尚待探讨)
实际应用如下:
#include &StdAfx.h&
#include &highgui.h&
#include&cv.h&
//superdont
//blog.csdn.net/superdont
int main(int argc,char ** argv)
IplImage * src = cvLoadImage(&guagua.bmp&);
IplImage * result1 = cvCreateImage(
cvSize( src-&width/2, src-&height/2 ),
src-&depth,
src-&nChannels
cvPyrDown( src, result1,CV_GAUSSIAN_5x5);
IplImage * result2 = cvCreateImage(
cvSize( src-&width*2, src-&height*2 ),
src-&depth,
src-&nChannels
cvPyrUp( src, result2,CV_GAUSSIAN_5x5);
cvNamedWindow(&source&,1);
cvShowImage(&source&,src);
cvNamedWindow(
&PyrDown& ,1);
cvShowImage( &PyrDown&, result1);
cvNamedWindow(
&PyrUp& ,1);
cvShowImage( &PyrUp&,result2);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&result1);
cvReleaseImage(&result2);
cvDestroyAllWindows();
阅读(...) 评论()

我要回帖

更多关于 opencv resize函数 的文章

 

随机推荐