在Matlab中优化循环

时间:2015-08-11 17:02:52

标签: performance matlab for-loop

我在Matlab写了一个“Peak finder”。在这个项目之前我从来没有使用过Matlab或类似的东西,所以我是新的“向量化”我的代码。基本上,该程序需要在视频的每个帧中拍摄分子和绘制圆圈的视频。如果一个分子拥挤,那么它会变成一个红色的圆圈,但如果它没有拥挤则会变成一个绿色的圆圈。

我的问题是其中一些视频有2000帧,我的程序需要大约25秒来处理单帧,这是不切实际的。

使用tic和toc我找到了麻烦制造者:一个for循环,它调用一个包含for循环的函数。

function getPeaks( orgnl_img, processed_img, cut_off, radius )

    % find large peaks peaks by thresholding, i.e. you accept a peak only 
    % if its more than 'threshold' higher than its neighbors
    threshold = 2*std2(orgnl_img);
    peaks = (orgnl_img - processed_img) > threshold;

    % m and n are dimensions of the frame, named peaks
    [m, n] = size(peaks);

    cc_centroids = regionprops(peaks, 'centroid');

    % Pre-allocate arrays
    x_centroid = zeros(1, length(cc_centroids));
    y_centroid = zeros(1, length(cc_centroids));

    for i = 1:length(cc_centroids)
        % Extract the x and y components from cc_centroids struct
        x_centroid(i) = cc_centroids(i).Centroid(1);
        y_centroid(i) = cc_centroids(i).Centroid(2);

        row = int64(x_centroid(i));
        col = int64(y_centroid(i));

        % Assure that script doesnt attempt to exceed frame
        if col-2 > 0 && row-2 > 0 && col+2 < m && row+2 < n
            region_of_interest = orgnl_img(col-2:col+2,row-2:row+2);
            local_intensity = max(region_of_interest(:));

            % Do not plot circle when intensity is 'cut off' or lower
            if local_intensity > cut_off

               dist_bool = findDistance(cc_centroids, x_centroid(i), y_centroid(i), radius);

               if dist_bool == 1
                   color = 'g';
               else
                   color = 'r';
               end
               plotCircle(color, x_centroid(i), y_centroid(i), radius)
            end
        end
    end
end

这是findDistance函数,它包含另一个for循环并确定圆是否重叠:

function dist_bool = findDistance( all_centroids, x_crrnt, y_crrnt, radius )
    x_nearby = zeros(1, length(all_centroids));
    y_nearby = zeros(1, length(all_centroids));
    for i = 1:length(all_centroids)
        if all_centroids(i).Centroid(1) < (x_crrnt+2*radius) &&...
           all_centroids(i).Centroid(1) > (x_crrnt-2*radius) &&...
           all_centroids(i).Centroid(2) < (y_crrnt+2*radius) &&...
           all_centroids(i).Centroid(2) > (y_crrnt-2*radius)

            x_nearby(i) = all_centroids(i).Centroid(1);
            y_nearby(i) = all_centroids(i).Centroid(2);
            pts_of_interest = [x_nearby(i),y_nearby(i);x_crrnt,y_crrnt];
            dist = pdist(pts_of_interest);
            if dist == 0 || dist > 2*radius
                dist_bool = 1;
            else
                dist_bool = 0;
                break
            end
        end
    end
end

我认为这里必须做很多改进。我很感激任何建议。

谢谢! :)

更新:以下是探查器结果。代码的第一部分是“getPeaks”函数

http://i.stack.imgur.com/VaLdH.png

保持来自情节圈功能:

function plotCircle( color, x_centroid, y_centroid, radius )
    hold on;
    th = 0:pi/50:2*pi;
    xunit = radius * cos(th) + x_centroid;
    yunit = radius * sin(th) + y_centroid;
    plot(xunit, yunit, color);
    hold off;
end

0 个答案:

没有答案
相关问题