6

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.

Hameer Abbasi
  • 1,292
  • 1
  • 12
  • 34
  • 4
    How did you define `boolean`? It's not a built-in function, so I substituted `logical` and got a different result altogether. Are you using the same parameters (1.5, 20, 40)? – Emre Jan 03 '13 at 04:16
  • 1
    As @Emre mentioned `logical` is the proper matlab command to cast variables as booleans. However, note that for initializing variables you can also just use `false(size)` rather than `logical(zeros(size))` – Dennis Jaheruddin Jan 03 '13 at 09:40
  • @Emre, I did use exactly the same parameters. I'll try logical, and also Dennis' solution. – Hameer Abbasi Jan 03 '13 at 11:26
  • It didn't work. I got exactly the same result with `false`. Will try `logical(zeros(size))` I didn't define `boolean`, I thought it was built-in. – Hameer Abbasi Jan 03 '13 at 11:32
  • Exactly the same result. I'm using R2011b, if it helps. – Hameer Abbasi Jan 03 '13 at 11:37
  • 1
    Wouldn't it be best not to assume the Wikipedia has it right? I would ask the uploading author by email for his code. You can also find some MATLAB implementations [here](http://en.pudn.com/downloads169/sourcecode/windows/multimedia/detail781617_en.html). – Emre Jan 03 '13 at 19:49
  • Thanks for all your help, @Emre. The Wikipedia user in question has deleted his account, and from the looks of it, this article was one of the only contributions he made. I'll look through the MATLAB implementation there, and try to edit my work to match the logic. – Hameer Abbasi Jan 04 '13 at 03:52
  • 1
    He hasn't deleted his account; he just hasn't written on his user page. You can leave a message on [his talk page](http://cs.wikipedia.org/wiki/Diskuse_s_wikipedistou:Zbysek.nemec) [+[cz](http://en.wikipedia.org/wiki/User_talk:Zbysek.nemec)]. – Emre Jan 04 '13 at 04:31
  • @Emre Ah. Okay. What I find more disturbing, though, is that you get different results with `logical`, while I don't. Could you post them? – Hameer Abbasi Jan 04 '13 at 10:23

1 Answers1

2

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.

WalkingRandomly
  • 4,537
  • 5
  • 34
  • 34