DAPPLE Example: canny
Source code:
// canny -- a parallel Canny's-algorithm program for edge finding
// written using the Data-Parallel Programming Library for Education (DAPPLE)
//
// This program detects edges in an image by computing the "slope"
// of the image at each pixel (by finding the X and Y components and then
// computing slope's amplitude). Then it chooses a new value (0 or 1) for
// points where the amplitude exceeds a threshold value.
// The technique can be improved, but this is sufficient to demonstate
// the parallelism: all pixels are computed in parallel.
//
// David Kotz 1994, from Sumit Chawla 1994
// $Id: canny.cc,v 1.3 94/09/29 12:17:57 dfk Exp $
#include
#include
#include
#include "dapple.h"
const int BLACK = 255;
const int WHITE = 0;
const float THRESHOLD = 25.00;
int
main(int argc, char **argv)
{
int w, h; // actual size of image; must be that w == h
cin >> w >> h;
if (w != h) {
cerr << "Image size is " << w << " by " << h <<
"; it must be square." << endl;
exit(1);
}
int N = w; // we'll work with NxN matrices
doubleMatrix image(N,N); // original grayscale image(converted from int)
doubleMatrix X(N,N); // x projection of image
doubleMatrix Y(N,N); // y projection of image
doubleMatrix amplitude(N,N); // amplitude of image
intMatrix edges(N,N); // the edges in the image
// load image; row-major order, whitespace-separated integers
cin >> image;
// project image onto X, ie, using this stencil
// 0.5 1.0 0.5
// 0.0 0.0 0.0
// -0.5 -1.0 -0.5
X = 0.5 * shift(image, 1, 1)
+ 1.0 * shift(image, 1, 0)
+ 0.5 * shift(image, 1, -1)
- 0.5 * shift(image, -1, 1)
- 1.0 * shift(image, -1, 0)
- 0.5 * shift(image, -1, -1);
// project image onto Y, ie, using this stencil
// 0.5 0.0 -0.5
// 1.0 0.0 -1.0
// 0.5 0.0 -0.5
Y = 0.5 * shift(image, 1, 1)
+ 1.0 * shift(image, 0, 1)
+ 0.5 * shift(image, -1, 1)
- 0.5 * shift(image, 1, -1)
- 1.0 * shift(image, 0, -1)
- 0.5 * shift(image, -1, -1);
// compute amplitude at each point
amplitude = apply(sqrt, X * X + Y * Y);
ifp (amplitude > THRESHOLD)
edges = BLACK;
else
edges = WHITE;
// print edge image; start with the dimensions
cout << N << " " << N << endl;
// row-major order, whitespace-separated integers, one row per line
cout << edges;
return(0);
}
Demonstration:
img2ascii canny.data/zebra.img | canny | ascii2img canny.out.img
Canny produces image output that cannot be viewed in Mosaic.