Friday, May 7, 2010

Edge Detection





downloadEdge Detection Compound

Took a little time to experiment with edge detection in ice.

The main goal was to implement the Canny Edge Detection algorithm (http://en.wikipedia.org/wiki/Canny_edge_detector), but in the end it turned out to be much (MUCH!) more simple and visually oriented that that.

For now it only works on grids (planar projections) and greyscale images. The next goal is to enhance the detection by decomposing rgb channels and comparing colors.


ICE Edge Detection from Fabricio Chamon on Vimeo.

How it works:

The pseudocode for the entire detection process is:

for each particle
  get its neighbours particles
  get neighbour closest pixel brightness on grid
  get all neighbours colors average
  compare with threshold
  if low threshold < average color < high threshold, then set this particle as an edge

On the begining it doubt this would work due to the large margin of error it could produce. But using masks as inputs gave me suitable results.

Compound parameters: With closer low-high ranges you get narrower edges, zeroing out low will give you filled blacks, and totally cranking up high (=1) will give you filled whites. Increasing detection resolution will enhance accuracy, but at the price of decreased performance.

Funny enough, the hardest part of this compound was not the algorithm itself, but how to expose the final edge particle positions as an array per object. The particles considered as edge have an isImageEdge boolean attribute set to true.We can easily get all point positions in a per object context by:

get self > get closest points (no cuttoff distance or max points) > get pointpositions

But now we have to remove from pointposition array the non-edge particles. The next trick is:

if isImageEdge = false, remove the returned array subIndices from pointposition array (the non-edge particles)
if isImageEdge = true, remove -1 from pointposition array (which will do nothing)

This way you can have a filtered per object array returning an attribute validated by another attribute. This is very handy and should be encapsulated in a compound for later use.

that's it, see you next time. =)

1 comment: