如何让我的代码运行得更快?

时间:2015-03-04 14:20:59

标签: matlab image-processing

我正在研究一段代码,它通过在每个像素周围取一个像素的圆形样本来模糊图像,找到它们的平均值,然后将其应用到中心像素。它可以工作,但需要很长时间,特别是对于大图像和大半径。

有人可以给我一些关于如何提高速度的技巧吗?

function [] = immean(IMAGE, r)

%Find the maximum width, nx, and maximum height, ny, of the image - so that
%it can be used to end the for-loop at the appropriate positions.

[nx, ny] = size(IMAGE);

%Create a completely black image of the same size as the subject image,
%into which the appropriate pixel values can be fed.

average = uint8(zeros(size(IMAGE)));

%Loop through all the pixels of the image.

for x = 1:nx
  for y = 1:ny

     %This next code takes a square sample of pixels, with dimensions of 
     %r x r.
     %First, set the boundaries of this square, from which the circular
     %sample of pixels will be taken.

     if x-r <= 0
         startx = 1;
     else
         startx = x-r;
     end

     if x+r > nx
         endx = nx;
     else
         endx = x+r;
     end

     if y-r <= 0
         starty = 1;
     else
         starty = y-r;
     end

     if y+r > ny
         endy = ny;
     else
         endy = y+r;
     end

     %Loop through this square sample and, if the pixel is within the
     %range of the circle, add its intensity to the total.

     total = 0;
     pixelcount = 0;

     for xp = startx : endx

       for yp = starty : endy  

             if (x-xp)^2 + (y-yp)^2 <= r^2
               total = total + uint32(IMAGE(xp, yp));
               pixelcount = pixelcount + 1;
             end
       end
     end

     mean = total / pixelcount;
     average(x,y) = mean;

   end
end

imshow(average)

我尝试过改变uint32之类的东西但是没有用。除此之外,我是一个初学者,所以我不确定在这种情况下最好的技巧是什么。谢谢你的时间。

1 个答案:

答案 0 :(得分:3)

MATLAB中的循环非常慢。通常,您应该始终在可能的情况下对代码进行矢量化。这是其中一个案例。循环每个像素是非常缓慢的。

MATLAB有一个函数 imfilter ,基本上可以满足您的需要。由于您只是采用平均强度,因此简单的过滤功能可以非常快速地完成此操作。您可以将滤波器系数定义为矩阵:

% Define a 2D Filter with radius r:
d = 2*r+1;
h = zeros(d);

% Now make it a "circular" filter (keeping it square would be much easier 
% and probably look the same but whatever):
[x, y] = meshgrid(1:d,1:d);
distance = sqrt((x-(r+1)).^2 + (y-(r+1)).^2);
h(distance<=r) = 1;
h = h / sum(h(:))

% Now pump it into imfilter and youre done:
average = imfilter(uint32(IMAGE), h);

此外,还有一大堆MATLAB图像处理工具,所以要搜索一下,你可能会找到有用的工具,无论你做什么,都不需要重新发明轮子。我没有在我面前有一张图片来测试这张图片但请告诉我它是否有效。