Skip to main content

[JAI] Source code for Canny edge finder

11 replies [Last post]
Anonymous

Here's some home-grown source code for a Canny edge finding operator
under JAI. This supercedes the code that I posted on June 13 - this
contribution has a couple of bug fixes. The Canny operator consists of
a chain of OpImages, and this chain is defined in a class called
CannyEdgeFinder, which is a plain old Java class, rather than a JAI one.
This is because my particular application needs to be able to cancel the
processing, and I could not see a simple way of creating "compound" ops
under JAI to behave this way. As with the previous installment, this
code caters for byte images only.

I've read the JAI Joint Copyright Assignment & Patent form, and agree to
its terms.

Enjoy,

Jason.

(I'm not going to print, sign, & post the form, as it's too much of a
PITA this time of night, and somebody close to JAI should tell the Sun
legalese folk that a requirement to do this will stymie contributions
from the outside world, who are not used to filling in forms to
contribute source code to mailing lists or open projects!)

[att1.html]
[canny-src.tar.gz]
---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jason Grant

On Mon, 2005-07-18 at 12:11 -0400, jai-interest@javadesktop.org wrote:

>
> Why is the sector calculation in GradientSectorOpImage adding 270 degrees to the result of Math.atan2() ? and not 180 degrees?

As you can probably gather, I called it 'GradientSector' because it
stores both an edge gradient, and a 'sector' map that records which
quadrant the edge angle falls into. This sector map resides in an image
band, and is used by the non-Maximal suppression. Because the sector
map is really just a computation buffer, I did not expect this OpImage
to be used in a stand-alone way. Instead, it's an implementation of an
intermediate step that is intended to be used for the Canny and Hough
detectors that I contributed.

I also decided to record the edge angle an image band, and this is used
to speed up the Hough OpImage which is O(n3). I give the angle a
different offset according to which sector the Sobel angle falls. The
offsets are chosen to map from the -PI->PI domain of the atan() method,
into a 0->PI domain for the Hough image. Note that the Sobel edge
detector provides the angle of the edge makes with the horizontal,
whereas convention has the Hough angle as measured between the
horizontal and the *normal* to this edge. That's why I introduce an
extra PI/2 phase difference.

> I also noticed that you are calling Math.atan2(f_h, f_v) instead of Math.atan2(f_v, f_h) (i.e (horizontal, vertical) instead of (vertical, horizontal)). Is that the reason for adding 270 deg? It should be equivalent to adding 180 degrees to the result of Math.atan2(f_v, f_h), but somehow the results are better with your implementation. Wondering why….
>

This again just reflects the coordinate systems used.

Out of interest, what are you planning to do with the code? If you're
just using it for Canny detection, you don't need to calculate/record
the angle.

[att1.html]

sunil_su
Offline
Joined: 2005-05-27
Points: 0

I was using it for Canny edge detection and hence only need the sector calculation. Nonmaximal suppression suppresses non maximal points in the direction of the gradient. But your sector calculation seems to be off by 90 degress. For eg. if the atan2(f_h, f_v) is 30 degress, then the gradient is 60 degrees. This should make it fall into sector 1. But by adding 270, it falls into sector 3, which is normal to the direction of the gradient.

Am I missing something here?

Jason Grant

On Thu, 2005-07-21 at 17:15 -0400, jai-interest@javadesktop.org wrote:

> Am I missing something here?

Yes. You're missing the phase correction in the sector routine, which
maps the angle back to (0,2pi) before choosing a sector.

Once again, if you are only using the GradientSector op for Canny work,
you can eliminate this phase shift.

J.

[att1.html]

divyamn
Offline
Joined: 2009-03-04
Points: 0

hii,
can u pls send me java code for denoising and edge detection...
am in need of it very badly.....

pls help me
u can mail to divya_mn07@yahoo.co.in

divyamn
Offline
Joined: 2009-03-04
Points: 0

hii,
can u pls send me java code for denoising and edge detection...
am in need of it very badly.....

pls help me

vz60536
Offline
Joined: 2008-06-05
Points: 0

Where can I get the Source code for Canny edge finder?

Thanks.

wurzi_dev
Offline
Joined: 2007-12-27
Points: 0

Hello Jason!

I'm working on my diploma thesis with the target to extract the motifs of color images. In order to do this I would like to try applying the canny operator you developed. I would be deeply grateful if you could send me the sources to wurzi_dev[at]dev.java.net.

Season's Greetings,
Martin

shrieky
Offline
Joined: 2007-11-25
Points: 0

Hi Jason,
I want to implement the Canny Edge detection in my project. It would be very helpful if you can share the same.
My email id : srikanth1947@gmail.com

Thanks,
Shrieky

Stéphane Wasserhardt

Hello Jason,

This version of your canny edge detector uses a class named "TileCompletionListener" which isn't provided with the source...
So I'm afraid I'm going to use the version you posted earlier... But then I'd like to know what were the bug fixes you did on this version (I don't have enough time to read all the code)
Or if you could send me the TileCompletionListener class, I think it should be ok

Thanks a lot in advance !

Steph
-----Message d'origine-----
De : Jason Grant [mailto:junk@logular.com]
Envoyé : samedi 9 juillet 2005 13:26
À : interest@jai.dev.java.net
Objet : [SPAM] [JAI] Source code for Canny edge finder

Here's some home-grown source code for a Canny edge finding operator under JAI. This supercedes the code that I posted on June 13 - this contribution has a couple of bug fixes. The Canny operator consists of a chain of OpImages, and this chain is defined in a class called CannyEdgeFinder, which is a plain old Java class, rather than a JAI one. This is because my particular application needs to be able to cancel the processing, and I could not see a simple way of creating "compound" ops under JAI to behave this way. As with the previous installment, this code caters for byte images only.

I've read the JAI Joint Copyright Assignment & Patent form, and agree to its terms.

Enjoy,

Jason.

(I'm not going to print, sign, & post the form, as it's too much of a PITA this time of night, and somebody close to JAI should tell the Sun legalese folk that a requirement to do this will stymie contributions from the outside world, who are not used to filling in forms to contribute source code to mailing lists or open projects!)

[att1.html]

sunil_su
Offline
Joined: 2005-05-27
Points: 0

Jason,

A question on you canny edge detector,

Why is the sector calculation in GradientSectorOpImage adding 270 degrees to the result of Math.atan2() ? and not 180 degrees? I also noticed that you are calling Math.atan2(f_h, f_v) instead of Math.atan2(f_v, f_h) (i.e (horizontal, vertical) instead of (vertical, horizontal)). Is that the reason for adding 270 deg? It should be equivalent to adding 180 degrees to the result of Math.atan2(f_v, f_h), but somehow the results are better with your implementation. Wondering why….

Thank you for posting the source code.

Jason Grant

On Mon, 2005-07-18 at 12:11 -0400, jai-interest@javadesktop.org wrote:

>
> Why is the sector calculation in GradientSectorOpImage adding 270 degrees to the result of Math.atan2() ? and not 180 degrees?

As you can probably gather, I called it 'GradientSector' because it
stores both an edge gradient, and a 'sector' map that records which
quadrant the edge angle falls into. This sector map resides in an image
band, and is used by the non-Maximal suppression. Because the sector
map is really just a computation buffer, I did not expect this OpImage
to be used in a stand-alone way. Instead, it's an implementation of an
intermediate step that is intended to be used for the Canny and Hough
detectors that I contributed.

I also decided to record the edge angle an image band, and this is used
to speed up the Hough OpImage which is O(n3). I give the angle a
different offset according to which sector the Sobel angle falls. The
offsets are chosen to map from the -PI->PI domain of the atan() method,
into a 0->PI domain for the Hough image. Note that the Sobel edge
detector provides the angle of the edge makes with the horizontal,
whereas convention has the Hough angle as measured between the
horizontal and the *normal* to this edge. That's why I introduce an
extra PI/2 phase difference.

> I also noticed that you are calling Math.atan2(f_h, f_v) instead of Math.atan2(f_v, f_h) (i.e (horizontal, vertical) instead of (vertical, horizontal)). Is that the reason for adding 270 deg? It should be equivalent to adding 180 degrees to the result of Math.atan2(f_v, f_h), but somehow the results are better with your implementation. Wondering why….
>

This again just reflects the coordinate systems used.

Out of interest, what are you planning to do with the code? If you're
just using it for Canny detection, you don't need to calculate/record
the angle.

[att1.html]