Outline.mesa
Copyright Ó 1984, 1992 by Xerox Corporation. All rights reserved.
Maureen Stone November 1, 1984 6:40:25 pm PST
Doug Wyatt, September 5, 1985 2:41:04 pm PDT
Outline: CEDAR DEFINITIONS =
BEGIN
The procedures in this package finds the outlines of images in arrays of pixels. An outline is a sequence of points that form a closed loop. For example, given a scanned image of a character, this package will find the points that lie along the edge of the character.
A client of this package creates a handle and calls one of the Outline* procedures. These procedure find all the outlines in the region of the image defined by startX, startY, endX, endY and return the number of outlines found (nOutlines). The outlines in an image are numbered 0 to nOutlines in the order found. To read the outlines the client calls GetOutline.
Handle: TYPE = REF Rec;
Rec: TYPE = RECORD [
tValue: REAL,  --threshold value for OutLineEdge. Defines black for OutlineBlack*
border: INT, --color of pixels outside the window. Usually "white"
xStart, yStart, xPixels, yPixels: INT, --window on image. Same as a PixelArray
get: PROC[client: REF, x,y: INT] RETURNS[INT], --called to get pixels
newEdge: PROC[client: REF, x0,y0,x1,y1: REAL] RETURNS[abort: BOOLEAN ¬ FALSE], --feedback proc
client: REF, --returned to client in get procs above
data: REF  --private data for the outline procedures
];
The Outline* procedures scan over the client window: xStart, yStart, xPixels, yPixels. The window definition matches that of an Imager PixelArray. (xStart, yStart) is the lower left corner of the lower left pixel. (xPixels, yPixels) are the number of pixels in each dimension in the window. h.border describes the color outside the window and is used to define the outside edge of the image. Most clients will want to make border "white" if the image is "black". This guarentees, for example, that if the image runs right up to the edge of the window, the outline will run along the window boundary for OutlineBlackEdge. If the border is "black" the outline will not close along the window edge.
Each time a contribution to the outline is found newEdge is called to provide feedback and an opportunity to abort. (newEdge may be NIL). The Outline* procedures build the outline in the private data structures in the handle. The data field in the handle is initialized each time an Outline* procedure is called. GetOutline enumerates the data structure. Notice that the efficient client can store the data field of the Handle instead of copying the outline to a new data structure.
OutlineEdge: PROC[h: Handle] RETURNS[nOutlines: INT];
Finds the polygon that describes a contour line at "elevation" h.tValue.
Assumes a multilevel image. You must choose tValue to fall between the pixels. For example, for an image with pixels in the range [0..255] chose a tValue like 128.5. The algorithm will fail if tValue matches a value in the image.
OutlineBlackCenter: PROC[h: Handle] RETURNS[nOutlines: INT];
Finds the polygon down the center of the black pixels.
Assumes a binary image. h.tValue=black.
OutlineBlackEdge: PROC[h: Handle] RETURNS[nOutlines: INT];
Finds the polygon around the outside of the black pixels.
Assumes a binary image. h.tValue=black.
InvalidID: SIGNAL;
GetOutline: PROC [data: REF, newPoint: PROC[x,y: REAL], id: INT];
data should be handle.data. The id is the outline number [0..nOutlines]. Call this procedure in a loop to get all the outlines.
END.