matlab自身提供了图像金字塔接口:impyramid
B = impyramid(A, direction)
direction = 'expand' or 'reduce',分别代表拉普拉斯金字塔和高斯金字塔
经过实际测试,该函数与opencv的pyrDown和pyrUp函数计算得到的结果不一致,经进一步查明,为高斯模糊造成。matlab和opencv,在图像金字塔函数内部的高斯模糊是不一样的。
matlab的impyramid并没有详细说明高斯模糊的参数,但opencv的说明文档对pyrDown和pyrUp函数有详细说明:
pyrDown的实现过程:
第一步:The function performs the downsampling step of the Gaussian pyramid construction. First, it convolves the source image with the kernel:
这是pyrDown的高斯模糊滤波核
第二步:Then, it downsamples the image by rejecting even rows and columns.
pyrUp的实现过程:
第一步:First, it upsamples the source image by injecting even zero rows and columns and
第二步:then convolves the result with the same kernel as in pyrDown() multiplied by 4.
注意滤波核是pyrDown的4倍
还需要注意,opencv的滤波是有多种边界处理方式的,在borderType这一参数中设置,默认为BORDER_DEFAULT
而matlab中的imfilter函数也有这一项选择,不过只有'symmetric'、'replicate'、'circular'三种可选,其中replicate相当于BORDER_REPLICATE,symmetric相当于BORDER_REFLECT,这个边界处理方式也造成了matlab与opencv计算处理的结果不一样
这是用matlab实现的opencv的pyrDown和pyrUp函数,计算结果完全一样:
function [dst,hd,wd]= pyrDown(src)
temp = double(src);
kernel=1/256*[ 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 ];
temp=imfilter(temp,kernel,'replicate'); %效果跟opencv的滤波函数一致
[h,w] = size(src);
hd = floor((h+1)/2);
wd = floor((w+1)/2); %下采样后的大小
down = zeros(hd,wd);
for i=1:hd
for j=1:wd
down(i,j) = temp(i*2-1,j*2-1); %采样奇数行(从1开始计数)
end
end
dst = down;
end
function dst = pyrUp(src,hu,wu)
temp = double(src);
[hd,wd] = size(src);
up = zeros(hu,wu); %期望长宽wu和hu
for i=1:hd
for j=1:wd
up(i*2-1,j*2-1) = temp(i,j); %填充奇数行(从1开始计数),i=1、3、5,即偶数行补零
end
end
kernel=1/64*[ 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 ];
up=imfilter(up,kernel,'symmetric');
dst = up;
end
---------------------------END-------------------------------