图像滤波可分离矩阵速度MATLAB

时间:2014-11-22 20:27:41

标签: matlab image-processing matrix imagefilter

我目前正在进行一项案例研究,研究可分离滤波器与方形滤波器的性能改进。我理解时间复杂度差异背后的数学,但是我遇到了现实世界实现的问题。

所以基本上我所做的就是写一个循环来实现我的滤镜图像功能:

function imOut = FilterImage(imIn, kernel, boundFill, outputSize)


VkernelOffset = floor(size(kernel,1)/2);
HkernelOffset = floor(size(kernel,2)/2);


imIn = padarray(imIn, [VkernelOffset HkernelOffset], boundFill);


imInPadded = padarray(imIn, [VkernelOffset HkernelOffset], boundFill);


imOut = zeros(size(imIn));


kernelVector = reshape(kernel,1, []);
kernelVector3D = repmat(kernelVector, 1, 1, size(imIn,3)); 


for row = 1:size(imIn,1)
    Vwindow = row + size(kernel,1)-1; 
    for column = 1:size(imIn,2)
      Hwindow = column + size(kernel,2)-1;

      imInWindowVector = reshape( ... 
          imInPadded(row:Vwindow, column:Hwindow, :),1,[],size(imIn,3));

      imOut(row,column, :) = sum((imInWindowVector.*kernelVector3D),2);
    end
end


ouputSize = lower(outputSize); 


if strcmp(outputSize, 'same')  
 imOut = imOut((1+VkernelOffset):(size(imOut,1)-VkernelOffset), ...
     (1+HkernelOffset):(size(imOut,2)-HkernelOffset), : );
 elseif strcmp(outputSize, 'valid')
  imOut = imOut((1+VkernelOffset*2):(size(imOut,1)-VkernelOffset*2), ...
      (1+HkernelOffset*2):(size(imOut,2)-HkernelOffset*2), : );
 end
end

我写了另一个脚本,它在740x976灰度图像上执行以下两组命令并记录它们的处理时间:

for n = 1:25
   dim(n) = 6*n + 1;
   h=fspecial('gaussian',dim(n), 4);
   tic;
   Im = FilterImage(I,h,0,'full');
   tM(n) = toc;

   h1 = fspecial('gaussian', [dim(n) 1], 4);
   h2 = fspecial('gaussian', [1 dim(n)], 4);
   tic;
   It = FilterImage(I,h1,0,'full');
   Is = FilterImage(It,h2,0,'full');
   tS(n) = toc;
end

在绘制所需的相应时间后,我得到以下结果:Output Plot

我的问题是,为什么可分离方法慢到大小为49x49的内核矩阵,并且只显示从内核大小55x55向上提高的速度,我的图像过滤器代码有问题?

P.S。图像滤镜代码是为3D图像设计的,以考虑颜色深度,但是对于速度测试,我使用的是使用im2double转换为double的灰度图像。

ps2所以如下所述,为了进行比较,我使用MATLAB的原生conv2函数执行了相同的过程,结果就像你期望的那样,也非常快...... {{0 }}

感谢

1 个答案:

答案 0 :(得分:0)

这似乎是一个优化错误 我改用conv2函数 我们来写一个示例代码:

mOutputImage = conv2((vFilterCoeff.' * vFilterCoeff), mInputImage);
mOutputImageSep = conv2(vFilterCoeff, vFilterCoeff.', mInputImage);

vFilterCoeff(行向矢!!!)的长度越来越大的循环中尝试这些。

更新我们现在的结果。