首页 > 代码库 > OpenCV2马拉松第7圈——图像金字塔
OpenCV2马拉松第7圈——图像金字塔
收入囊中
- 高斯金字塔
- 拉普拉斯金字塔
葵花宝典
图像金字塔是一系列的图像集合,都是从单张图片获得的,连续做下采样(downsample)直到预设停止条件.最常用的是两种,高斯金字塔和拉普拉斯金字塔。[当然还有其他的金字塔,比如小波金字塔]
高斯金字塔
对一张图像不断的模糊之后向下采样,得到不同分辨率的图像,同时每次得到的新的图像宽与高是原来图像的1/2, 最常见就是基于高斯的模糊之后采样,得到的
一系列图像称为高斯金字塔。
原图来自http://blog.csdn.net/jia20003/article/details/9116931
最底层我们成为G0,往上分别是G1,G2...
如何对图片作下采样呢?
- 高斯模糊[用如下卷积,注意要除以256,用上之前的知识,这是一个可分离的滤波,所以只需要2K次计算,不需要K^2]
1 4 6 4 1 4 16 24 16 4 6 24 36 24 6 4 16 24 16 4 1 4 6 4 1 - 去掉所有的偶数行和偶数列
提到下采样,就不得不提上采样(构建拉普拉斯金字塔也会用到)
如何对图片作上采样呢?
我们看看OpenCV是如何做的吧
- 每个维度都扩大两倍并插入0,也就是f(2i,2j) = f(i,j) , f(2i+1,2j+1) = 0
- 再用相同的高斯核进行高斯卷积,结果再乘4
拉普拉斯金字塔
高斯金字塔不同(DoG)又称为拉普拉斯金字塔,给出计算方式前,先加强一下定义
记得在上面我们定义了G0,G1,G2
G0下采样获得G1
G1上采样获得Upsample(G1),注意Upsample(G1)不等于G0,上采样和下采样不是可逆过程,这是因为下采样损失了图片信息
在此,给出计算拉普拉斯金字塔(DOG)的公式:L(i) = G(i) – Upsample(G(i+1))
DOG有很多用处,非常流行的SIFT特征第一步就是DOG
初识API
- C++: void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )
- src – 输入图像
- dst – 输出图像
- dstsize – 输出图像的size
- C++: void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )
- src – 输入图像
- dst – 输出图像
- dstsize – 输出图像的size
- C++: void buildPyramid(InputArray src, OutputArrayOfArrays dst, int maxlevel, int borderType=BORDER_DEFAULT )
- src – 输入图像
- dst – 这是一个存储(maxlevel+1)的向量,dst[0]和源图像一样,dst[1]是第一次下采样
- maxlevel – 指定采样级数,必须为非负数
内部实现是不断call pyrDown()
荷枪实弹
第一个例子就是OpenCV自己的sample,使用PyrDown和PyrUp
#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(int argc,char **argv) { 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" ); src = http://www.mamicode.com/imread(argv[1]);>
下面我们就用buildPyramid和PyrUp来建立DOG(拉普拉斯金字塔)
先看一下我们的源图片
再看一下获得的DOG,请仔细看
代码也非常简单,完全不用解释
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <math.h> #include <stdlib.h> #include <stdio.h> #include <vector> #include <sstream> using namespace cv; using namespace std; Mat src,tmp; vector<Mat>gaussPyrs; vector<Mat>DOG; int maxLevel = 3; int main(int argc,char **argv) { src = http://www.mamicode.com/imread(argv[1]);>举一反三拉普拉斯金字塔也用于图像融合,CVAA的第三章有练习题就是用拉普拉斯金字塔进行融合,addWeighted这个函数在边界上没有过渡,效果不好,而拉普拉斯金字塔则有很好的效果具体请见http://blog.csdn.net/abcjennifer/article/details/7628655计算机视觉讨论群:162501053转载请注明:http://blog.csdn.net/abcd1992719g
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。