MODULE PZBoundary EXPORTS Main; (* Extracts a fragment contour from a ".pgm" image, writes it as a PZLR3Chain.T. *) (* Last edited on 2001-11-01 11:48:50 by stolfi *) IMPORT ParseParams, Process, FileWr, Wr, Fmt; IMPORT OSError, Thread, Stdio, TextWr; IMPORT LR3; IMPORT PZImage, PZLR3Chain; FROM PZImage IMPORT Side; FROM Stdio IMPORT stderr; FROM PZTypes IMPORT NAT, LONG; <* FATAL Wr.Failure, Thread.Alerted, OSError.E *> TYPE Options = RECORD inFile: TEXT; (* Input image name, without ".pgm" *) black: NAT; (* Maximum black level *) grey: NAT; (* grey level *) side: Side; (* Which contour to write *) pixelSize: LONG; (* Pixel size in use units. *) outUnit: LONG; (* Output scale factor. *) outFile: TEXT (* Output float curve name, without ".flc" *) END; PROCEDURE Main() = VAR aFC : REF PZLR3Chain.T; aImage : REF PZImage.T; BEGIN WITH o = GetOptions(), cc = PZBoundaryComments(o) DO Wr.PutText(stderr,"reading input file..."); aImage := PZImage.ReadPGM(o.inFile); Wr.PutText(stderr, Fmt.Int(NUMBER(aImage[0])) & "x" & Fmt.Int(NUMBER(aImage^)) & "\n"); aFC := PZImage.ExtractBoundary(aImage^, o.black, o.grey, o.side); IF o.pixelSize # 1.0d0 THEN FOR i := 0 TO LAST(aFC^) DO aFC[i] := LR3.Scale(o.pixelSize, aFC[i]) END END; WriteCurve(o.outFile, cc, aFC^, o.outUnit) END END Main; PROCEDURE WriteCurve( name: TEXT; cmt: TEXT; READONLY c: PZLR3Chain.T; unit: LONG; ) = BEGIN WITH fileName = name & ".flc" DO Wr.PutText(stderr, "writing file " & fileName & " ...\n"); WITH adjUnit = PZLR3Chain.AdjustUnit(unit, c) DO PZLR3Chain.Write(FileWr.Open(fileName), cmt, c, unit := adjUnit) END END END WriteCurve; PROCEDURE GetOptions(): Options = VAR o: Options; BEGIN WITH pp = NEW(ParseParams.T).init(stderr) DO TRY pp.getKeyword("-inFile"); o.inFile := pp.getNext(); pp.getKeyword("-black"); o.black := pp.getNextInt(0, 254); pp.getKeyword("-grey"); o.grey := pp.getNextInt(0, 255); IF pp.keywordPresent("-pixelSize") THEN o.pixelSize := pp.getNextLongReal(0.1d-10, 0.1d10) ELSE o.pixelSize := 1.0d0 END; IF pp.keywordPresent("-outUnit") THEN o.outUnit := pp.getNextLongReal(0.1d-10, 0.1d10) ELSE o.outUnit := 0.01d0 END; pp.getKeyword("-outFile"); o.outFile := pp.getNext(); IF pp.keywordPresent("-inside") THEN o.side := Side.Inner ELSIF pp.keywordPresent("-outside") THEN o.side := Side.Outer ELSE o.side := Side.Interpolated END; pp.finish(); EXCEPT | ParseParams.Error => Wr.PutText(stderr, "Usage: PZBoundary \\\n"); Wr.PutText(stderr, " -inFile \\\n"); Wr.PutText(stderr, " -black \\\n"); Wr.PutText(stderr, " -grey \\\n"); Wr.PutText(stderr, " [ -pixelSize ] \\\n"); Wr.PutText(stderr, " [ -outUnit ] \\\n"); Wr.PutText(stderr, " -outFile \\\n"); Wr.PutText(stderr, " [ -inside | -outside ]\n"); Process.Exit(1); END; END; RETURN o END GetOptions; PROCEDURE PZBoundaryComments(READONLY o: Options):TEXT= BEGIN WITH wr = NEW(TextWr.T).init() DO Wr.PutText(wr, "PZBoundary\n"); Wr.PutText(wr, " inFile = " & o.inFile & "\n"); Wr.PutText(wr, " black = " & Fmt.Int(o.black) & " grey = " & Fmt.Int(o.grey) & "\n"); Wr.PutText(wr, " pixelSize = " & Fmt.LongReal(o.pixelSize) & "\n"); Wr.PutText(wr, " outUnit = " & Fmt.LongReal(o.outUnit) & "\n"); RETURN(TextWr.ToText(wr)) END (* DO *); END PZBoundaryComments; BEGIN Main() END PZBoundary. (* Copyright © 2001 Universidade Estadual de Campinas (UNICAMP). Authors: Helena C. G. Leitão and Jorge Stolfi. This file can be freely distributed, used, and modified, provided that this copyright and authorship notice is preserved, and that any modified versions are clearly marked as such. This software has NO WARRANTY of correctness or applicability for any purpose. Neither the authors nor their employers chall be held responsible for any losses or damages that may result from its use. *)