matlab实现opencv的pyrDown和pyrUp函数

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:

matlab实现opencv的pyrDown和pyrUp函数_第1张图片

这是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-------------------------------





你可能感兴趣的:(matlab,opencv)