2
votes

I am using the following lines of code for edge detection using canny edge detector :

I=imread('bradd.tif');
figure,imshow(I); 
IDtemp = im2double(I); 
[r c]=size(I);


ID(r,c) = 0;   
IDx(r,c) = 0;          
IDfil(r,c) = 0;         
IDxx(r,c) = 0;          
IDy(r,c) = 0;          
IDyy(r,c) = 0;       
mod(r,c) = 0; 

for i= 1 : r+4
    for j = 1:c+4
        if(i<=2 || j<=2 || i>=r+3 || j>=c+3)
            ID(i,j) = 0;
        else 
            ID(i,j) = IDtemp(i-2,j-2);
        end;
    end
end
%figure,imshow(ID);

filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
for i=1:5
    for j=1:5
        filter(i,j)=filter(i,j)/159;
    end
end
%figure,imshow(filter);
for v = 3 : r
    for u = 3 : c
        sum = 0;
        for i = -2 : 2
            for j = -2 : 2
                sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
            end
        end
        IDx(u,v) = sum;
    end
end
%figure,imshow(IDx);

IDxtemp = IDx;
for i= 1 : r+2
    for j = 1:c+2
        if(i<=1 || j<=1 || i>=r || j>=c)
            IDfil(i,j) = 0;
        else 
            IDfil(i,j) = IDxtemp(i-1,j-1);
        end;
    end
end
%figure,imshow(IDfil);

Mx = [-1 0 1; -2 0 2; -1 0 1]; % Sobel Mask in X-Direction
My = [-1 -2 -1; 0 0 0; 1 2 1]; % Sobel Mask in Y-Direction

for u = 2:r
     for v = 2:c

         sum1 = 0;

        for i=-1:1
            for j=-1:1
                sum1 = sum1 + IDfil(u + i, v + j)* Mx(i + 2,j + 2);
            end
        end
        IDxx(u,v) = sum1;
     end;
end
%figure,imshow(IDxx);
for u = 2:r
     for v = 2:c

         sum2 = 0;

        for i=-1:1
            for j=-1:1
             sum2 = sum2 + IDfil(u + i, v + j)* My(i + 2,j + 2);
            end
        end
        IDyy(u,v) = sum2;
     end
end
%figure,imshow(IDyy);

for u = 1:r
   for v = 1:c
        mod(u,v) = sqrt(IDxx(u,v)^2  +  IDyy(u,v)^2) ;
        %mod(u,v) = sqrt(IDxx(u,v)^2  + IDyy(u,v)^2);
   end
end
%figure,imshow(mod);
modtemp = mod;

for i= 1 : r+2
    for j = 1:c+2
        if(i<=1 || j<=1 || i>=r || j>=c)
            mod(i,j) = 0;
        else 
            mod(i,j) = modtemp(i-1,j-1);
        end;
    end
end
%figure,imshow(mod);

theta(u,v) = 0;  
supimg(u,v) = 0;
ntheta(u,v) = 0;

for u = 2 : r
    for v = 2 : c
        theta(u,v) = atand(IDyy(u,v)/IDxx(u,v)); 

        if ((theta(u,v) > 0 ) && (theta(u,v) < 22.5) || (theta(u,v) > 157.5) && (theta(u,v) < -157.5))
            ntheta(u,v) = 0;
        end

        if ((theta(u,v) > 22.5) && (theta(u,v) < 67.5) || (theta(u,v) < -112.5) && (theta(u,v) > -157.5))
            ntheta(u,v) = 45;
        end

        if ((theta(u,v) > 67.5 && theta(u,v) < 112.5) || (theta(u,v) < -67.5 && theta(u,v) > 112.5))
            ntheta(u,v) = 90;
    end

        if ((theta(u,v) > 112.5 && theta(u,v) <= 157.5) || (theta(u,v) < -22.5 && theta(u,v) > -67.5))
            ntheta(u,v) = 135;
        end
        if (ntheta(u,v) == 0)
            if (mod(u, v) > mod(u, v-1) && mod(u, v) > mod(u, v+1))
                    supimg(u,v) = mod(u,v);
                else supimg(u,v) = 0;
            end
          end


        if (ntheta(u,v) == 45)
            if (mod(u, v) > mod(u+1, v-1) && mod(u, v) > mod(u-1, v+1))
                supimg(u,v) = mod(u,v);

            else supimg(u,v) = 0;
            end
        end


        if (ntheta(u,v) == 90)
            if (mod(u, v) > mod(u-1, v) && mod(u, v) > mod(u+1, v))
                supimg(u,v) = mod(u,v);

            else supimg(u,v) = 0;
            end
        end
        if (ntheta(u,v) == 135)
            if (mod(u, v) > mod(u-1, v-1) && mod(u, v) > mod(u+1, v+1))
                supimg(u,v) = mod(u,v);

            else supimg(u,v) = 0;
            end 
        end


end
end
%figure,imshow(ntheta);

th = 0.2;
tl = 0.1; 
resimg(u,v)= 0;

for u = 2 : r-1
    for v = 2 : c-1
        if(supimg(u,v) > th)
            resimg(u,v) = 1;
        else
            if(supimg(u,v) >= tl && supimg(u,v) <= th )
               resimg(u,v) = 1;
            else
             if (supimg(u,v) < tl)
                resimg(u,v) = 0;
            end
        end
    end

                if (supimg(u-1,v-1) > th || supimg(u,v-1) > th || supimg(u+1,v-1) > th || supimg(u+1,v) > th || supimg(u+1,v+1) > th || supimg(u,v+1) > th || supimg(u-1,v+1) > th || supimg(u-1,v) > th)
                resimg(u,v) = 1;
                else 
                    resimg(u,v) = 0;
                end
    end
    end
figure,imshow(supimg);
figure,imshow(resimg);

However, for some of the images it is working fine, while for others it is showing the following error : Index exceeds matrix dimensions.

Error in canny_edge (line 45)
            sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));

Can someone help me sort out this problem ?? Thanks and Regards.

1

1 Answers

0
votes

Your loop ranges are in the wrong order leading to the error. If you modify your loop ranges to this

for u = 3 : r
    for v = 3 : c
        sum = 0;
        for i = -2 : 2
            for j = -2 : 2
                sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
            end
        end
        IDx(u,v) = sum;
    end
end

the problem is solved.

My guess is that the code worked only for square images with c==r.

Note you are not making use of Matlab's vectorization capability, which allows you to shorten the first steps to:

ID = [zeros(2,c+4) ; [zeros(r,2) IDtemp zeros(r,2)]; zeros(2,c+4)];
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
filter=filter/159;
for u = 1 : r
    for v = 1 : c
        IDx(u,v) = sum(reshape(ID(u+[0:4], v+[0:4]).* filter,25,1));
    end
end

and this last loop can also be collapsed further but that might make readability an issue.

(edit) The loop can (for instance) be replaced with

IDx = conv2(ID, filter,'same');