Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 Imageenter 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.

like image 574
Hameer Abbasi Avatar asked Jan 03 '13 02:01

Hameer Abbasi


1 Answers

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.

like image 69
WalkingRandomly Avatar answered Sep 30 '22 06:09

WalkingRandomly