提高matlab代码的运行时间

提高matlab代码的运行时间,matlab,optimization,image-processing,Matlab,Optimization,Image Processing,我编写了一个matlab代码,用于使用Hough变换检测灰度图像中的圆。我希望尽可能减少运行时间 我使用的边缘检测是自定义实现,但是它的运行时间足够快,可以满足我的需要(大约0.06秒)。但是,瓶颈是代码的其余部分(总运行时间约为6.35秒)。顺便说一句,我使用tic/toc来计算运行时间 这是代码,如果有人能看一下,我将非常感激: function [ circles ] = findCircles(img) % set low and high bounds for radii valu

我编写了一个matlab代码,用于使用Hough变换检测灰度图像中的圆。我希望尽可能减少运行时间

我使用的边缘检测是自定义实现,但是它的运行时间足够快,可以满足我的需要(大约0.06秒)。但是,瓶颈是代码的其余部分(总运行时间约为6.35秒)。顺便说一句,我使用tic/toc来计算运行时间

这是代码,如果有人能看一下,我将非常感激:

function [ circles ] = findCircles(img)

 % set low and high bounds for radii values
    minR = 9; 
    [imgRows, imgCols] = size(img);
    maxR = ceil(min(imgRows, imgCols)/2);

    tic

    % run edge detection on image
    edgeImg = edgeDetect(img);    
    % get image size
    [rows, cols] = size(edgeImg); 
    % initialize accumulator
    houghAcc = zeros(rows, cols, maxR);
    % get all edge pixels from image
    edges = find(edgeImg);

    % find number of edge pixels
    edgeNum = size(edges);

    % scan each edge 
    for currEdge = 1 : edgeNum

        % get current edge x and y coordinations
        [edgeY edgeX] =  ind2sub([rows, cols], edges(currEdge));
        % scan each all possible radii
        for r = minR : maxR
            % go over all possible 2*pi*r circle centers
            for ang = 0 : 360
                t = (ang * pi) / 180;
                cX = round(edgeX - r*cos(t));
                cY = round(edgeY - r*sin(t));

                % check if center found is within image boundaries
                if ( cX < cols && cX > 0 && cY < rows && cY > 0 )
                    % found circle with (cX,cY) as center and r as radius
                    houghAcc(cY,cX,r)=houghAcc(cY,cX,r)+1; % increment matching counter

                end
            end
        end
    end

    % initialize circle list
    circles = []; 
    % intialize index for next found circle
    nextCircleIndx = 1;
    % get counter list dimensions
    [sizeX sizeY sizeR] = size(houghAcc);

    % get max counter value from hough counter matrix
    m = max(max(max(houghAcc))); 
    % calculate the minimal pixels that circle should have on perimeter
    t = m * 0.42; 

    % scan each found circle
    for cX = 1 : sizeX
        for cY = 1 : sizeY
            for r = 1 : sizeR

                % threshold values
                if houghAcc(cX, cY, r) > t
                    % circle is dominant enough, add it
                    circles(nextCircleIndx,:) = [cY , cX , r ,houghAcc(cX, cY, r)];
                    % increment index
                    nextCircleIndx = nextCircleIndx + 1;                    
                end

            end

        end
    end

     % sort counters in descending order (according to votes for each
    % circle)
    circles = flipud(sortrows(circles,4));

    % get circle list's size
    [rows cols] = size(circles);

    % scan circle list and check each pair of found circles 
    for i = 1 : rows-1
        % get first circle's details:
        % center
        cX1 = circles(i,1);
        cY1 = circles(i,2);
        % radius
        r1 = circles(i,3);
        %hough counter
        h1 = circles(i,4); 

        for j = i+1 : rows

            %get second circle's details:
            % center
            cX2 = circles(j,1);
            cY2 = circles(j,2);
            % radius
            r2 = circles(j,3);
            %hough counter
            h2 = circles(j,4); 


            % check if circle's actual difference is smaller than minimal
            % radius allowed
            if (cX1 - cX2)*(cX1 - cX2)+ (cY1 - cY2)*(cY1 - cY2) < (min(r1,r2))*(min(r1,r2))  && abs(r1 - r2) < minR
                % both circles are similar, sum their counters and merge
                % them to a circle with their avaraged values
                circles(i,:)=[(cX1+cX2)/2, (cY1+cY2)/2, (r1+r2)/2, h1+h2];
                % remove similar circle
                circles(j,:)=[0,0,0,0]; 
            end
        end

    end

    sortParam = 3; % 1: x-center, 2: y-center, 3: radius, 4: hough counter

    % sort the circles by the sort parameter, in descending order
    circles = flipud(sortrows(circles,sortParam));

    % get number of remained circles (= rows with non-zero values)
    len = length(find(circles~=0))/4;

    % remove duplicate similar circles from previus step
    circles(circles == 0) = [];

    % reshape circle list back to matrix form (previous step converted it
    % to a vector)
    circles = reshape(circles,len,4);

    % get max value according to sort parameter
    m = max(circles(:,sortParam));

    %get size of new circle list (with no duplicate circles)
    [newH newW] = size(circles);

    % thresholding: remove hough counters that are less than 30% from sort
    % parameter
    for  i= 1 : newH
        % check if current circle's sorting parameter's value is smaller
        % than threshold
        if  m - circles(i,sortParam) < m * 0.3 
    %         plot(circles(i,1),circles(i,2),'xr'); % DEBUG - show centers
        else
            % remove current circle
            circles(i,:)=[0,0,0,0];
        end
    end

    % find number of remaining circles after thresholding
    len = length(find(circles~=0))/4;
    % delete rows that match circles removed in thresholding
    circles(circles==0)=[];
    % reshape circle list back to matrix form
    circles=reshape(circles,len,4);

    % convert circle list's values to integers (hough counters are already
    % integers)
    circles = uint8(circles(:,1:3));
    toc
end
function[circles]=findCircles(img)
%设置半径值的下限和上限
minR=9;
[imgRows,imgCols]=大小(img);
maxR=ceil(最小值(imgrowth,imgCols)/2);
抽搐
%对图像进行边缘检测
edgeImg=edgeDetect(img);
%获取图像大小
[行,列]=大小(edgeImg);
%初始化累加器
houghAcc=零(行、列、最大值);
%从图像中获取所有边缘像素
边=查找(边);
%查找边缘像素数
edgeNum=尺寸(边);
%扫描每条边
对于currEdge=1:edgeNum
%获取当前边x和y坐标
[edgeY edgeX]=ind2sub([rows,cols],edges(currendge));
%扫描每个可能的半径
对于r=minR:maxR
%检查所有可能的2*pi*r圆心
对于ang=0:360
t=(ang*pi)/180;
cX=圆形(edgeX-r*cos(t));
cY=圆形(edgeY-r*sin(t));
%检查找到的中心是否在图像边界内
if(cX0&&cY0)
%以(cX,cY)为中心,以r为半径的圆
houghAcc(cY,cX,r)=houghAcc(cY,cX,r)+1;%增量匹配计数器
结束
结束
结束
结束
%初始化循环列表
圆圈=[];
%初始化下一个找到的圆的索引
nextCircleIndx=1;
%获取计数器列表维度
[sizeX sizeY sizeR]=尺寸(houghAcc);
%从hough计数器矩阵获取最大计数器值
m=最大值(最大值(最大值(houghAcc));
%计算圆周长上应有的最小像素
t=m*0.42;
%扫描找到的每个圆圈
对于cX=1:sizeX
对于cY=1:sizeY
对于r=1:sizeR
%阈值
如果houghAcc(cX,cY,r)>t
%圆圈足够占主导地位,添加它
圆(nextCircleIndx,:)=[cY,cX,r,houghAcc(cX,cY,r)];
%增量指数
nextCircleIndx=nextCircleIndx+1;
结束
结束
结束
结束
%按降序排序计数器(根据每个计数器的投票)
%圆圈)
圆圈=flipud(sortrows(圆圈,4));
%获取圆列表的大小
[行cols]=大小(圆);
%扫描圆列表并检查找到的每对圆
对于i=1:rows-1
%获取第一个圆圈的详细信息:
%居中
cX1=圆(i,1);
cY1=圆(i,2);
%半径
r1=圆(i,3);
%霍夫计数器
h1=圆(i,4);
对于j=i+1:行
%获取第二个圆圈的详细信息:
%居中
cX2=圆(j,1);
cY2=圆(j,2);
%半径
r2=圆(j,3);
%霍夫计数器
h2=圆(j,4);
%检查圆的实际差异是否小于最小值
%允许半径
如果(cX1-cX2)*(cX1-cX2)+(cY1-cY2)*(cY1-cY2)<(min(r1,r2))*(min(r1,r2))&abs(r1-r2)

在哪里可以改进此代码?谢谢你的帮助

对于填充
houghAcc
矩阵的第一个
块,我建议进行以下替换:

r = minR : maxR;    
t = ( 0 : 359 ) * pi / 180; % following HighPerformaceMark suggestion
rsin = bsxfun( @times, r', sin(t) ); %'
rcos = bsxfun( @times, r', cos(t) ); %'
[edgeY edgeX] = find( edgeImg );
cX = round( bsxfun( @minus, edgeX, permute( rcos, [3 1 2] ) ) );
cY = round( bsxfun( @minus, edgeY, permute( rsin, [3 1 2] ) ) );
R = permute( repmat( r', [ 1 size(cX,1) size(cX,3) ] ), [2 1 3] ); %' to index accHough
% select valid indices
sel = ( cX > 0 & cY > 0 & cY < rows & cX < cols );
houghAcc = accumarray( {cY(sel(:)), cX(sel(:)), R(sel(:))}, 1, [rows, cols, maxR] );
ind = find( houghAcc > t );
% sort the scores
sc = houghAcc(ind);
[sc si] = sort(  sc , 'descend' );
% convert linear indices to x,y,r
[cX cY r] = ind2sub( size( houghAcc ), ind(si) );
circles = [ cX(:) cY(:) r(:) sc(:) ];

for-for-for-if在算法中出现两次。如果其他人没有帮助我使用
profile
运行它,我将尝试稍后再讨论这个问题,这样您就可以更好地了解代码的大部分时间都花在了什么地方。利润