make a canny edge detector from scratch in matlab

main.m
% Load image and convert to grayscale
img = imread('image.jpg');
gray = rgb2gray(img);

% Smooth the image
kernel = fspecial('gaussian', [5,5], 1);
smoothed = imfilter(gray, kernel);

% Compute gradient magnitude and direction
[Gx, Gy] = imgradientxy(smoothed);
magnitude = sqrt(Gx.^2 + Gy.^2);
direction = atan2d(Gy, Gx);

% Perform non-maximum suppression
suppressed = zeros(size(gray));
for i=2:size(gray,1)-1
    for j=2:size(gray,2)-1
        if (direction(i,j) > -22.5 && direction(i,j) <= 22.5) || ...
           (direction(i,j) <= -157.5 || direction(i,j) > 157.5)
            if (magnitude(i,j) > magnitude(i,j-1) && magnitude(i,j) > magnitude(i,j+1))
                suppressed(i,j) = magnitude(i,j);
            end
        elseif (direction(i,j) > 22.5 && direction(i,j) <= 67.5) || ...
               (direction(i,j) <= -112.5 && direction(i,j) > -157.5)
            if (magnitude(i,j) > magnitude(i-1,j+1) && magnitude(i,j) > magnitude(i+1,j-1))
                suppressed(i,j) = magnitude(i,j);
            end
        elseif (direction(i,j) > 67.5 && direction(i,j) <= 112.5) || ...
               (direction(i,j) <= -67.5 && direction(i,j) > -112.5)
            if (magnitude(i,j) > magnitude(i-1,j) && magnitude(i,j) > magnitude(i+1,j))
                suppressed(i,j) = magnitude(i,j);
            end
        elseif (direction(i,j) > 112.5 && direction(i,j) <= 157.5) || ...
               (direction(i,j) <= -22.5 && direction(i,j) > -67.5)
            if (magnitude(i,j) > magnitude(i-1,j-1) && magnitude(i,j) > magnitude(i+1,j+1))
                suppressed(i,j) = magnitude(i,j);
            end
        end
    end
end

% Double thresholding
high_threshold = 0.2 * max(suppressed(:));
low_threshold = 0.1 * max(suppressed(:));
strong = suppressed > high_threshold;
weak = (suppressed >= low_threshold) & (suppressed <= high_threshold);

% Edge linking
[rows,cols] = size(suppressed);
edge_map = zeros(rows,cols);
for i=2:rows-1
    for j=2:cols-1
        if strong(i,j) && ~edge_map(i,j)
            edge_map(i,j) = 1;
            
            if weak(i-1,j-1)
                edge_map(i-1,j-1) = 1;
            end
            if weak(i-1,j)
                edge_map(i-1,j) = 1;
            end
            if weak(i-1,j+1)
                edge_map(i-1,j+1) = 1;
            end
            if weak(i,j-1)
                edge_map(i,j-1) = 1;
            end
            if weak(i,j+1)
                edge_map(i,j+1) = 1;
            end
            if weak(i+1,j-1)
                edge_map(i+1,j-1) = 1;
            end
            if weak(i+1,j)
                edge_map(i+1,j) = 1;
            end
            if weak(i+1,j+1)
                edge_map(i+1,j+1) = 1;
            end
        end
    end
end

% Output final edge map
imshow(edge_map);
2780 chars
86 lines

This code follows the basic steps of the Canny edge detection algorithm, including smoothing the image, computing gradient magnitude and direction, performing non-maximum suppression, double thresholding, and edge linking. The final output is a binary edge map where pixels with value 1 represent edges and pixels with value 0 represent non-edges.

gistlibby LogSnag