Zeeshan Pirzada
Zeeshan Pirzada

Reputation: 130

How can I improve my sobel operator edge detection?

I'm trying to get into the field of computer vision, and to start I implemented a Sobel filter in MATLAB, which I read about here: http://en.wikipedia.org/wiki/Sobel_operator

Here is the code:

image = double(image);
kernelx = [ -1, 0, 1;
           -2, 0, 2;
          -1, 0, 1];

kernely = [  1, 2, 1;
             0, 0, 0;
            -1, 0, 1];

height = size(image,1);
width = size(image,2);
channel = size(image,3);

for i = 2:height - 1
    for j = 2:width - 1
        for k = 1:channel
            magx = 0;
            magy = 0;
            for a = 1:3
                for b = 1:3
                    magx = magx + (kernelx(a, b) * image(i + a - 2, j + b - 2, k));
                    magy = magy + (kernely(a, b) * image(i + a - 2, j + b - 2, k));
                end;
            end;     
            edges(i,j,k) = sqrt(magx^2 + magy^2); 
        end;
    end;
end; 

Here is an image I tested it on:

This is the result:

I don't know where to go from here, I've tried looking at line thinning or thresholding, what steps should I take to make this run better?

Upvotes: 1

Views: 2318

Answers (2)

Unapiedra
Unapiedra

Reputation: 16238

Results first

Resulting Cat after run over by Sobel

1 Typo in Kernel

As Bharat Singh pointed out, your y-Kernel looks wrong. (Later analysis shows that it changes the results but that isn't the main problem.) If you want you can use your original kernel in my code below to see what the result is. (For posterity: kernely(3,:) = [-1, 0, 1];) Basically, it looks like the input image.

2 Use Convolution to make debugging fast

Before you do anything else, just use the convolution function that is provided by Matlab. Also, to speed things up, use conv2. While you are experimenting, you might want to use parfor instead of the outer for-loop. The convolution is instantaneous on my machine and the parfor version takes minutes.

3 imshow is causing problems

There is an alternative named imagesc, that scales the image automatically. Or you can call imshow(image, []). But the problem in this case is that each channel looks right but the automated mixing of the channels by Matlab doesn't work. (Remember they are not RGB anymore but more like magnitude of the R-channel derivative |dR| etc. )

Check this by looking at each resulting channel individually (imshow(E(:,:,1), [])) or as a euclidean average (see my code). If you run imshow(E, []) you get the blown out highlights. The same happens if you pass it through rgb2gray first.

Code

image = imread('cat.jpg');

image = double(image);
kernelx = [ -1, 0, 1;
           -2, 0, 2;
          -1, 0, 1];

kernely = [  1, 2, 1;
             0, 0, 0;
            -1, -2, -1];

height = size(image,1);
width = size(image,2);
channel = size(image,3);

edges = zeros(height, width, channel);

if exist('chooseSlow', 'var')
    parfor i = 2:height - 1
        for j = 2:width - 1
            for k = 1:channel
                magx = 0;
                magy = 0;
                for a = 1:3
                    for b = 1:3
                        magx = magx + (kernelx(a, b) * image(i + a - 2, j + b - 2, k));
                        magy = magy + (kernely(a, b) * image(i + a - 2, j + b - 2, k));
                    end;
                end;
                edges(i,j,k) = sqrt(magx^2 + magy^2);
            end;
        end;
    end;
end

%% Convolution approach
E = zeros(height, width, channel);
for k=1:channel
    Magx = conv2(image(:,:,k), kernelx, 'same');
    Magy = conv2(image(:,:,k), kernely, 'same');
    E(:,:,k) = sqrt(Magx .^2 + Magy .^2);
end

imshow(sqrt(E(:,:,1).^2 + E(:,:,2).^2 + E(:, :, 3) .^2 ), []);
print('result.png', '-dpng');

Upvotes: 2

Bharat
Bharat

Reputation: 2189

Your kernel in the y direction seems to be incorrect, it should be

[ 1, 2, 1; 0, 0, 0; -1, -2, -1];

Further, if you want to improve edge detection, you can look into Hysteresis, its an easy way to complete some obvious contours in an image which might be missed out

http://en.wikipedia.org/wiki/Canny_edge_detector#Tracing_edges_through_the_image_and_hysteresis_thresholding

Upvotes: 2

Related Questions