Skip to main content

[JAI] Should I be basing my new OpImage on UntiledOpImage?

1 reply [Last post]
Anonymous

I'm new to JAI and am trying to write a Canny edge detector.

I have half implemented an AreaOpImage derivative to do the job, but
have just realised that AreaOpImage may not be appropriate - I now need
to verify my understanding of JAI is correct...

With the Canny algorithm (http://www.cee.hw.ac.uk/hipr/html/canny.html),
I need to first perform edge detection, before computing "non maximal
suppression" which involves tracking along the edges. I think that the
edge detection must be completed across the entire image before the
tracking begins, because the tracker should not be allowed to reach into
areas of the image for which edges have not been computed yet. I
suspect I should be using an UntiledOpImage instead for the following
reasons:

1) AreaOpImage doesn't seem to give me the ability to perform a second
pass over the source once the first pass is complete.

2) Tracking is a recursive process that follows lines, so I cannot
implement mapDestRect(), because there is no prior knowledge about how
far the tracker will reach outside of the dest rect.

Is this reasoning in line with JAI's design? (note that I cannot
separate the two steps into different OpImages, because the second step
relies on computed artefacts from the first step)

Thanks,

Jason.
[att1.html]

Reply viewing options

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

On Fri, 27 May 2005, Jason Grant wrote:

> I'm new to JAI and am trying to write a Canny edge detector.
>
> I have half implemented an AreaOpImage derivative to do the job, but
> have just realised that AreaOpImage may not be appropriate - I now need
> to verify my understanding of JAI is correct...

AreaOpImage is intended to support algorithms which in order to compute a
given destination rectangle require a source rectangle which is equal to the
destination rectangle but with non-negative fixed padding on each side.

> With the Canny algorithm (http://www.cee.hw.ac.uk/hipr/html/canny.html),
> I need to first perform edge detection, before computing "non maximal
> suppression" which involves tracking along the edges. I think that the
> edge detection must be completed across the entire image before the
> tracking begins, because the tracker should not be allowed to reach into
> areas of the image for which edges have not been computed yet. I
> suspect I should be using an UntiledOpImage instead for the following
> reasons:
>
> 1) AreaOpImage doesn't seem to give me the ability to perform a second
> pass over the source once the first pass is complete.

Neither does UntiledOpImage. The distinction is in what portion of the
destination is required to compute a given rectangle of the destination. As
mentioned, for AreaOpImage it is a padded version of the destination
rectangle, for UntiledOpImage it is the entire source. Currently
UntiledOpImage is I think used only for the DFT, ErrorDiffusion, and IDFT
operations.

> 2) Tracking is a recursive process that follows lines, so I cannot
> implement mapDestRect(), because there is no prior knowledge about how
> far the tracker will reach outside of the dest rect.

But you are tracking in the edge strength image aren't you, not in the source?

> Is this reasoning in line with JAI's design? (note that I cannot
> separate the two steps into different OpImages, because the second step
> relies on computed artefacts from the first step)

It seems that the real issue at hand is more a generic concept of a recursive
OpImage. This is in fact something on which we did some work a while back as
part of an investigation of adding image analysis capabilities to the API.
The main use case at the time was unsupervised classification in the form of
clustering. In that case one needs to revisit all the pixels in both the
source and the destination for each iteration of the algorithm. Note however
that this does not require that either source or destination be untiled.

The issue that needed to be resolved was how to handle revisiting the
destination data in the context of an OpImage implementation. Also algorithms
of this nature are likely to require calculating the entire destination even
when only one rectangle of it is requested.

Revisiting the destination data could be handled by defining a TileCache
specific to each OpImage instance in which the destination image would be
stored. Forcing computation of the entire image in response to a getTile()
call would handle the other issue. This latter would be easily solved by
implementing within the public getTile() a loop over an internal getTile()
method for all tiles. Naturally as the destination data would be cached that
loop should only be executed on the first invocation.

My guess here is that lacking an intrinsic JAI base class for recursive
operations you should extend OpImage. Given that you cannot determine the
required source area for a given destination rectangle you might want to
conider not cobbling the sources and therefore implementing the computeRect()
variant which accepts a PlanarImage[] parameter instead of a Raster[]
parameter.

Brian

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net