Hameer Abbasi
Hameer Abbasi

Reputation: 1314

Can't get clean output in my MATLAB implementation of Canny-Deriche

My code so far is:

function imgg = derichefilter1(x, k, a, b, c)
osize = size(x);
x = double(x);
a = double(a);
b = double(b);
c = double(c);
k = double(k);
y1 = zeros(osize(1),osize(2));
y2 = zeros(osize(1),osize(2));
y1(:,1) = a(1)*x(:,1);
y1(:,2) = a(1)*x(:,2) + a(2)*x(:,1) + b(1)*y1(:,1);
for ii=3:osize(2)
    y1(:,ii) = a(1)*x(:,ii) + a(2)*x(:,ii-1) + b(1)*y1(:,ii-1) + b(2)*y1(:,ii-2);
end

y2(:,osize(2)-1) = a(3)*x(osize(2));
for ii=(osize(2)-2):-1:1
    y2(:,ii) = a(3)*x(:,ii+1) + a(4)*x(:,ii+2) + b(1)*y2(:,ii+1) + b(2)*y2(:,ii+2);
end
imgg = c*(y1+y2);

function imgg = derichefilter2(x, k, a, b, c)
imgg = derichefilter1(x,k,a(1:4),b,c(1));
imgg = (derichefilter1(imgg',k,a(5:8),b,c(2)))';

function [mask magn] = nonmaxsupp(x, y)
magn = sqrt(x.^2 + y.^2);
argu = atan2(y,x);
argu = argu/pi*4;
argu = int32(round(argu));
argu(argu == 4) = 0;
argu(argu < 0) = argu(argu < 0) + 4;
mask = boolean(zeros(size(x)));
for ii = 2:(size(x,1)-1)
    for jj = 2:(size(x,2)-1)
        switch argu(ii,jj)
            case 0
                mask(ii,jj) = (max(magn(ii,jj+1),magn(ii,jj-1)) <= magn(ii,jj));
            case 1
                mask(ii,jj) = (max(magn(ii-1,jj+1),magn(ii+1,jj-1)) <= magn(ii,jj));
            case 2
                mask(ii,jj) = (max(magn(ii-1,jj),magn(ii+1,jj)) <= magn(ii,jj));
            case 3
                mask(ii,jj) = (max(magn(ii+1,jj+1),magn(ii-1,jj-1)) <= magn(ii,jj));
        end
    end
end

function imgg = hystthres(x,Tl,Th)
imgg = (x>Th);
limg = (x>=Tl);
osize = size(x);
nTh = 0;
for ii = 1:osize(1)
    for jj = 1:osize(2)
        if imgg(ii,jj)
            nTh = nTh + 1;
        end
    end
end
c = zeros(1,nTh); r = zeros(1,nTh); nTh=0;
for ii = 1:osize(1)
    for jj = 1:osize(2)
        if imgg(ii,jj)
            nTh = nTh + 1;
            c(nTh) = ii; r(nTh) = jj;
        end
    end
end
imgg = bwselect(limg,r,c,8);

function imgg = derichecomplete(x, alph, Tl, Th)
k = (1 - exp(-alph))^2/(1 + 2*alph*exp(-alph) - exp(-2*alph));
as = zeros(1,8);
as(1) = k;
as(2) = k*exp(-alph)*(alph-1);
as(3) = k*exp(-alph)*(alph+1);
as(4) = -k*exp(-2*alph);
as(5:8)=as(1:4);
b = zeros(1,2);
b(1) = 2*exp(-alph);
b(2) = -exp(-2*alph);
cs = [1,1];
ax = [0,1,-1,0,as(5:8)];
cx = [-(1 - exp(-alph))^2,1];
ay = [ax(5:8),ax(1:4)];
cy = [cx(2) cx(1)];

deriches = derichefilter2(x, k, as, b, cs);
derichex = derichefilter2(deriches, k, ax, b, cx);
derichey = derichefilter2(deriches, k, ay, b, cy);
[mask mag] = nonmaxsupp(derichex, derichey);
mag(~mask) = 0;
imgg = hystthres(mag,Tl,Th);

clc; clear all; close all;
imagepath = input('Enter the image path in single quotes: ');
alph = input('Enter the value of alpha to be used: ');
Tl = input('Enter the value of Tl to be used: ');
Th = input('Enter the value of Th to be used: ');
imgg = imread(imagepath);
szzz = size(size(imgg));
if szzz(2) == 3
    osize = size(imgg);
    hystf = boolean(zeros(osize(1:2)));
    for ii=1:3
        hystf = hystf | derichecomplete(imgg(:,:,ii),alph,Tl,Th);
    end
else    
    hystf = derichecomplete(imgg,alph,Tl,Th);
end
imshow(hystf);

My output on the image on the Canny-Deriche Wikipedia page Image enter image description here

I can't seem to find an error because I followed the instructions there and on the Canny edge detector page to the letter. I've just implemented the algorithm as it is, and still can't seem to produce the same output. The features are thick and edgy, instead of smooth as on the Wikipedia pages.

EDIT: Dropbox link to code/image so you don't have to copy/paste it.

Upvotes: 6

Views: 1234

Answers (1)

WalkingRandomly
WalkingRandomly

Reputation: 4557

I think you are not processing the correct file. I applied your function to the full resolution image http://upload.wikimedia.org/wikipedia/commons/5/5e/Sunflowers_in_July.jpg and the result looked fine

If I apply your function to the 50K preview file, I get the result you show above.

Upvotes: 2

Related Questions