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.