// @TITLE "canny2.cc -- parallel Canny's algorithm" // // canny2 -- 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 taking two weighted averages of // the neighbors of each pixel, and choosing a new value (0 or 1) for // points where a function of those averages exceeds a threshold value. // The technique can be improved, but this is sufficient to demonstate // the parallelism: all pixels are computed in parallel. // // This version is different from canny in that it produces an output that is // suitable for input to atobm, which converts an ascii-represented bitmap // into an X11 bitmap file. The latter is then viewable with xv, etc. // // David Kotz 1994, from Sumit Chawla 1994 // $Id: canny2.cc,v 1.3 95/02/21 18:11:52 dfk CS15 Locker: dfk $ #include #include #include #include "dapple.h" const char BLACK = '#'; const char WHITE = '-'; 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 charMatrix 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 // row-major order, whitespace-separated integers, one row per line cout << edges; return(0); }