部分公式和图片来自http://blog.csdn.net/poem_qianmo/article/details/26157633;
以前一直知道金字塔,一层一层的,但是不知道具体应用是干嘛的,今天突然看到算法应用才知道,哦哦,原来大家说的图像分割,图像拼接用的就是这货啊。好吧,那就看看这货是怎么回事吧。
1,高斯金字塔:
这货呢,有高斯在就跑不掉高斯滤波(低通滤波器啊)了,所以啊,就是这货就是对原图进行高斯滤波然后把偶数行偶数列(也就是下采样)得到了原图被滤波裁剪之后的结果。
opencv里面用的就是
pyrDown 原图,结果图,结果图的size,边界模式
其中结果图的size要满足<img src="https://img-blog.csdn.net/20140518183145703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcG9lbV9xaWFubW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
<span style="white-space:pre"> </span>Mat mat_src = imread("bridgit.jpg");
imshow("src",mat_src);
Mat mat_gi,mat_gii;
pyrDown(mat_src,mat_gi,Size(mat_src.cols/2,mat_src.rows/2));
imshow("pyrdown 1",mat_gi);
pyrDown(mat_gi,mat_gii,Size(mat_gi.cols/2,mat_gi.rows/2));
imshow("pyrdown 2",mat_gii);
结果如图:
接着就应该是从小图怎么恢复到大图了吧,就是先对小图扩大到它的2倍,用0填充,然后对这个图进行同样的高斯模糊就得到结果图了。
opencv里面是这样的
<span style="white-space:pre"> </span>pyrUp(mat_gii,mat_gi,Size(mat_gii.cols*2,mat_gii.rows*2));
imshow("pyrup 1",mat_gi);
pyrUp(mat_gi,mat_g,Size(mat_gi.cols*2,mat_gi.rows*2));
imshow("pyrup 2",mat_g);
size必须满足一下条件:
效果图:
我去,结果好模糊啊,完全不是原图好嘛。
这也就说明了pyrup和pyrdown不是一对,哎,名字虽然一对,但是实际上真不是一对啊。
仔细想想就肯定不是原图嘛,因为你下采样的时候就已经把图像原来的信息丢掉了好嘛,上采样的填充填充的是0,还想变回原来的图,异想天开的吧。
所以怎么样才能变回原来的图,怎么填补信息啊?
我们知道高斯滤波是低通滤波器,就是把一些高频跟去掉了,所以就需要在上采样的时候找一些信息来填充,所以就有了拉普拉斯金字塔这货:
下式是拉普拉斯金字塔第i层的数学定义:
式中的表示第i层的图像。而UP()操作是将源图像中位置为(x,y)的像素映射到目标图像的(2x+1,2y+1)位置,即在进行向上取样。符号
表示卷积,
为5x5的高斯内核。
用OpenCV进行拉普拉斯运算:
Mat mat_u1,mat_u0,mat_l1,mat_l0,mat_dst1,mat_dst0;
pyrUp(mat_d2,mat_u1,Size(mat_d2.cols*2,mat_d2.rows*2));
imshow("pyrup 2",mat_u1);
subtract(mat_d1,mat_u1,mat_l1);
imshow("lap 1",mat_l1);
add(mat_u1,mat_l1,mat_dst1);
imshow("up 1",mat_dst1);
pyrUp(mat_d1,mat_u0,Size(mat_d1.cols*2,mat_d1.rows*2));
imshow("pyrup 1",mat_u0);
subtract(mat_src,mat_u0,mat_l0);
imshow("lap 0",mat_l0);
add(mat_u0,mat_l0,mat_dst0);
imshow("up 0",mat_dst0);
效果比直接pyrup好了很多倍啊,但是还是跟原图比有差距啊,毕竟少了信息了。
图像切割金字塔就这样了,下面该看怎么用金字塔来拼接图像了