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