Image File System Reference Manual Version 8.2.6 April 5, 2014 Wesley Snyder

Image File System Reference Manual
Version 8.2.6 April 5, 2014
Wesley Snyder
2
Acknowledgements
Based on suggestions by Wesley Snyder of North Carolina State University and Joe
Erkes of General Electrics Corporate Research and Development Center, the staff of Communication Unlimited, Inc. designed and coded IFS version 1 during the fall of 1986. Mark
Lanzo designed and implemented most of versions 1-4, although other members of the CUI
staff contributed heavily, including Katie Boone, Mark Yarboro, Gary McCauley, Bennett
Groshong, and Paul Hemler. Katie Boone is responsible for version 5, and Rajeev Ramanath contributed heavily to the creation of Version 6. Version 7 never really got listed
as a separate version. Version 8 incorporated 64 bit computers, and compatibility with
openCV, and was written mostly by Wesley Snyder and Ben Riggan. IFS is a trademark
of Communication Unlimited, Inc. IFS is jointly owned by CUI and North Carolina State
University.
Contents
1 The IFS system
1.0.1 New with version 8.1 . . . . . . . . . . .
1.0.2 New with Version 8 . . . . . . . . . . .
1.0.3 New with Version 6 . . . . . . . . . . .
1.0.4 New with Version 5 . . . . . . . . . . .
1.1 Using IFS . . . . . . . . . . . . . . . . . . . . .
1.1.1 Program Compilation and Linking . . .
1.2 Referencing IFS images . . . . . . . . . . . . .
1.2.1 Naming conventions in IFS . . . . . . .
1.3 Error handling in IFS . . . . . . . . . . . . . .
1.3.1 Image validation in IFS . . . . . . . . .
1.3.2 Header Files . . . . . . . . . . . . . . .
1.3.3 Coordinate systems and array storage in
1.4 IFS FUNCTION LISTING . . . . . . . . . . .
1.4.1 bilininterp . . . . . . . . . . . . . . . . .
1.4.2 ifsalc . . . . . . . . . . . . . . . . . . . .
1.4.3 ifscigp read from complex or real image
1.4.4 ifscigp3d . . . . . . . . . . . . . . . . . .
1.4.5 ifscipp . . . . . . . . . . . . . . . . . . .
1.4.6 ifscipp3d . . . . . . . . . . . . . . . . . .
1.4.7 ifscfgp . . . . . . . . . . . . . . . . . . .
1.4.8 ifscfgp3d . . . . . . . . . . . . . . . . . .
1.4.9 ifscfpp . . . . . . . . . . . . . . . . . . .
1.4.10 ifscfpp3d . . . . . . . . . . . . . . . . .
1.4.11 Ifsclose . . . . . . . . . . . . . . . . . .
1.4.12 ifscreate . . . . . . . . . . . . . . . . . .
1.4.13 ifs2ipl . . . . . . . . . . . . . . . . . . .
1.4.14 ipl2ifs . . . . . . . . . . . . . . . . . . .
1.4.15 ifsCVpin . . . . . . . . . . . . . . . . . .
1.4.16 ifsCVpot . . . . . . . . . . . . . . . . .
3
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
IFS
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
10
10
10
11
11
12
13
13
14
18
19
20
21
21
22
23
24
25
26
27
28
29
30
31
33
33
33
34
4
CONTENTS
1.5
1.6
1.7
1.4.17 ifsCVPopup . . . . . . . . . . . . . . . . . . .
1.4.18 IFSDISPLAY . . . . . . . . . . . . . . . . . .
1.4.19 Building ifsCV and IFSDisplay with openCV
1.4.20 ifsdimen . . . . . . . . . . . . . . . . . . . . .
1.4.21 ifsexwin . . . . . . . . . . . . . . . . . . . . .
1.4.22 ifsexwin3d . . . . . . . . . . . . . . . . . . . .
1.4.23 ifsfgp . . . . . . . . . . . . . . . . . . . . . .
1.4.24 ifsfgp3d . . . . . . . . . . . . . . . . . . . . .
1.4.25 ifsfpp3d . . . . . . . . . . . . . . . . . . . . .
1.4.26 ifsfpp . . . . . . . . . . . . . . . . . . . . . .
1.4.27 ifsfree . . . . . . . . . . . . . . . . . . . . . .
1.4.28 ifsGetFN . . . . . . . . . . . . . . . . . . . .
1.4.29 ifsGetImg . . . . . . . . . . . . . . . . . . . .
1.4.30 ifsigp . . . . . . . . . . . . . . . . . . . . . . .
1.4.31 ifsipp . . . . . . . . . . . . . . . . . . . . . .
1.4.32 ifsmkh . . . . . . . . . . . . . . . . . . . . . .
1.4.33 ifsopen . . . . . . . . . . . . . . . . . . . . . .
1.4.34 ifspin . . . . . . . . . . . . . . . . . . . . . .
1.4.35 ifspot . . . . . . . . . . . . . . . . . . . . . .
1.4.36 ifsPrsFN . . . . . . . . . . . . . . . . . . . . .
1.4.37 ifsPutImg . . . . . . . . . . . . . . . . . . . .
1.4.38 ifsRdHdr . . . . . . . . . . . . . . . . . . . .
1.4.39 ifsRdImg . . . . . . . . . . . . . . . . . . . .
1.4.40 ifssiz . . . . . . . . . . . . . . . . . . . . . . .
1.4.41 ifsslice . . . . . . . . . . . . . . . . . . . . . .
1.4.42 ifsversion . . . . . . . . . . . . . . . . . . . .
1.4.43 ifsWrImg . . . . . . . . . . . . . . . . . . . .
IFS Error Codes . . . . . . . . . . . . . . . . . . . .
IFS Data Types . . . . . . . . . . . . . . . . . . . . .
The structure of an IFS image . . . . . . . . . . . .
1.7.1 The image header fields . . . . . . . . . . . .
1.7.2 The dimension sub-header fields . . . . . . .
2 The FLIP library
2.1 Example Program Using
2.2 Matrix Operations . . .
2.2.1 dmatrix . . . . .
2.2.2 matrix . . . . . .
2.2.3 dvector . . . . .
2.2.4 vector . . . . . .
2.2.5 ivector . . . . . .
the FLIP functions
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
34
36
37
38
39
40
41
42
43
44
45
47
48
49
51
53
54
55
56
57
58
59
60
61
62
63
64
64
65
66
67
70
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
73
74
74
75
75
75
75
CONTENTS
2.3
2.4
2.5
2.2.6 free ivector . . . . . . . .
2.2.7 free dvector . . . . . . . .
2.2.8 free vector . . . . . . . . .
2.2.9 transpose . . . . . . . . .
2.2.10 ifsmatmult . . . . . . . .
2.2.11 ifsinverse . . . . . . . . .
2.2.12 jacobi . . . . . . . . . . .
Arithmetic Operations on Images
2.3.1 flabsolute . . . . . . . . .
2.3.2 fladds . . . . . . . . . . .
2.3.3 fladdv . . . . . . . . . . .
2.3.4 flclip . . . . . . . . . . . .
2.3.5 flcp . . . . . . . . . . . .
2.3.6 fldivs . . . . . . . . . . . .
2.3.7 fldivv . . . . . . . . . . .
2.3.8 flexp . . . . . . . . . . . .
2.3.9 flln . . . . . . . . . . . . .
2.3.10 flmults . . . . . . . . . . .
2.3.11 flmultv . . . . . . . . . .
2.3.12 flneg . . . . . . . . . . . .
2.3.13 flnorm . . . . . . . . . . .
2.3.14 flrec . . . . . . . . . . . .
2.3.15 flsq . . . . . . . . . . . . .
2.3.16 flsqrt . . . . . . . . . . . .
2.3.17 flsubs . . . . . . . . . . .
2.3.18 flsubv . . . . . . . . . . .
2.3.19 flthresh . . . . . . . . . .
2.3.20 flthresh2 . . . . . . . . . .
Image Manipulation Functions .
2.4.1 flone border . . . . . . . .
2.4.2 flpad . . . . . . . . . . . .
2.4.3 flplanar . . . . . . . . . .
2.4.4 flrotate . . . . . . . . . .
2.4.5 flshx . . . . . . . . . . . .
2.4.6 flshxy . . . . . . . . . . .
2.4.7 flshy . . . . . . . . . . . .
2.4.8 flzero border . . . . . . .
Derivative Operators . . . . . .
2.5.1 flDoG . . . . . . . . . . .
2.5.2 flGabor . . . . . . . . . .
2.5.3 fldx . . . . . . . . . . . .
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
76
76
76
76
76
77
77
77
77
77
78
78
78
78
78
79
79
79
79
79
79
80
80
80
80
80
80
81
81
81
81
81
81
82
82
82
82
83
83
84
85
6
CONTENTS
2.6
2.7
2.5.4 fldx back . . . . . . . . . . . . . . . . . . . . . . .
2.5.5 fldx forw . . . . . . . . . . . . . . . . . . . . . . .
2.5.6 fldxx . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.7 fldxy . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.8 fldxz . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.9 fldy . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.10 fldy back . . . . . . . . . . . . . . . . . . . . . . .
2.5.11 fldy forw . . . . . . . . . . . . . . . . . . . . . . .
2.5.12 fldyy . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.13 fldyz . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.14 fldz . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.15 fldzz . . . . . . . . . . . . . . . . . . . . . . . . . .
Running the FLIP functions from the command line . . .
2.6.1 flpg1: single input FLIP functions . . . . . . . . .
2.6.2 der1: take a derivative of an image . . . . . . . . .
2.6.3 ifsDoG:Apply a derivative of Gaussian kernel to an
Image Manipulation . . . . . . . . . . . . . . . . . . . . .
2.7.1 ifsadd . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.2 ifsany2any . . . . . . . . . . . . . . . . . . . . . . .
3 Image Processing Subroutines
3.1 Geometric functions . . . . .
3.1.1 chainHull 2D . . . . .
3.1.2 compute curvature . .
3.1.3 InsideTriangle . . . . .
3.1.4 InterpolateTriangle . .
3.1.5 cubic splines . . . . .
3.1.6 Resampling Curves . .
3.1.7 Operations on FIFO’s
3.1.8 MinimumRegion . . .
3.1.9 Watersheds . . . . . .
3.1.10 ifs ccl . . . . . . . . .
3.1.11 ifscfft2d . . . . . . . .
3.1.12 ifsc2imag . . . . . . .
3.1.13 ifsc2mag . . . . . . . .
3.1.14 ifsc2phase . . . . . . .
3.1.15 ifsc2real . . . . . . . .
3.1.16 ifsInsert2Dinto3D . . .
3.1.17 ifsmult . . . . . . . . .
3.1.18 ifsrecip . . . . . . . . .
3.1.19 ifssub . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
ifs image
. . . . . .
. . . . . .
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
85
86
86
86
86
86
87
87
87
88
88
88
88
89
89
90
90
90
90
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
93
93
94
94
97
98
100
101
101
101
105
106
107
108
109
110
111
112
113
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
114
114
114
115
115
116
116
4 Image Synthesis Programs
4.1 Qsyn-synthesize range images . . . . . . . . . .
4.2 3dsyn-synthesize density images . . . . . . . . .
4.3 Matte - synthesize luminance images . . . . . .
4.4 Tomosim - simulate tomographic X-ray source .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
117
117
123
133
134
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
ifs image
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
135
135
135
135
136
137
137
137
137
137
137
137
138
138
139
139
139
139
139
139
139
139
140
140
140
140
141
3.2
3.3
3.1.20 ifsvidscale . . . . . . . .
Functions to modify images . .
3.2.1 ifscolormap . . . . . . .
3.2.2 Lower Complete Images
3.2.3 zoomupdown . . . . . .
Random number generators . .
3.3.1 gaussrand . . . . . . . .
7
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5 Programs for processing images
5.1 add . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 addhdr . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 atoi . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4 any2any . . . . . . . . . . . . . . . . . . . . . . . .
5.5 c2imag . . . . . . . . . . . . . . . . . . . . . . . . .
5.6 c2mag . . . . . . . . . . . . . . . . . . . . . . . . .
5.7 c2phase . . . . . . . . . . . . . . . . . . . . . . . .
5.8 c2real . . . . . . . . . . . . . . . . . . . . . . . . .
5.9 compmag . . . . . . . . . . . . . . . . . . . . . . .
5.10 ChooseFrame . . . . . . . . . . . . . . . . . . . . .
5.11 gauss add Gaussian-distributed noise to an image .
5.12 ifsDoG Apply a derivative of Gaussian kernel to an
5.13 itoa . . . . . . . . . . . . . . . . . . . . . . . . . .
5.14 mkdoc . . . . . . . . . . . . . . . . . . . . . . . . .
5.15 mult . . . . . . . . . . . . . . . . . . . . . . . . . .
5.16 profile . . . . . . . . . . . . . . . . . . . . . . . . .
5.17 prthdr . . . . . . . . . . . . . . . . . . . . . . . . .
5.18 rmvhdr . . . . . . . . . . . . . . . . . . . . . . . .
5.19 subsample . . . . . . . . . . . . . . . . . . . . . . .
5.20 recip . . . . . . . . . . . . . . . . . . . . . . . . . .
5.21 sub . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.22 triangulate . . . . . . . . . . . . . . . . . . . . . .
5.22.1 Input File Format . . . . . . . . . . . . . .
5.22.2 Output File Format . . . . . . . . . . . . .
5.23 vidscale . . . . . . . . . . . . . . . . . . . . . . . .
5.24 window . . . . . . . . . . . . . . . . . . . . . . . .
8
CONTENTS
5.25 zoomupdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
6 Programs for Analyzing Images
6.1 Harris-Laplace . . . . . . . . . . . . . . . . . . .
6.2 PCON - Piecewise-constant image noise removal
6.3 PLIN - Piecewise-linear image noise removal . . .
6.4 WaterSheds . . . . . . . . . . . . . . . . . . . . .
6.5 ccl Connected-component Labeling . . . . . . . .
6.6 resample curve . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
143
143
143
146
148
149
151
7 Programs for Viewing IFS images
7.1 ColorMap . . . . . . . . . . . . . . . . . .
7.2 Eigenimages . . . . . . . . . . . . . . . . .
7.3 ifsview – view ifs images . . . . . . . . . .
7.4 makecolor . . . . . . . . . . . . . . . . . .
7.5 PlayMovie- play a 3D ifs image as a movie
7.6 Plotcontour . . . . . . . . . . . . . . . . .
7.7 C2LaTeX-convert source code to LaTeX .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
153
153
154
154
156
156
157
157
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Chapter 1
The IFS system
The IFS Image File System is a set of subroutines, and programs based on those subroutines, used to manipulate images, from within C or C++ programs. An image just refers
to any array of data. The term came into use because IFS was originally written to manipulate 2-dimensional pictures, such as ones obtained from a standard camera. However,
IFS is not restricted to 2-dimensional images, and is capable of handling arrays of arbitrary
dimensionality. In the current release of IFS, most of the image manipulating routines are
designed specifically for 2- or 3-dimensional data. Later releases of IFS will have enhanced
multidimensional routines. At the simplest level, IFS is a simple system to use, and hides
from the user the implementation details of basic data manipulation functions, such as
allocating space for data arrays, performing I/O, and manipulating images with different
data formats. When used in this way, IFS provides a development tool for program writing, and is not designed to for high execution speed. Use of the standard IFS image access
functions such as ifsigp is in fact quite slow in some operations. It is efficient when the aim
is to write and test programs quickly and easily. However, for the sophisticated user, IFS
does provide access to pointers and data types which allow very speed- efficient software
to be written while retaining the IFS image structure. The FLIP (floating point image
processing) library was written in this way, to optimize computer speed.
1.0.1
New with version 8.1
There is no longer a libiptools.a All functions except flip are in libifs.a There is now a
function which will rotate images about their center, flrotate. In the flip library, however,
it will accept inputs which are data types other than float. It does floats and u8bit with
pointers, so it’s pretty fast.
9
10
CHAPTER 1. THE IFS SYSTEM
1.0.2
New with Version 8
Several changes to ifs were mandated by the changes in technology which produced a move
to 64-bit machines. These include
• Complete support for 32-bit and 64 bit machines. This has been tested on Unix
(macintosh) and Linux, but not yet on Windows.
• New interface with OpenCV. OpenCV provides many attractive features, such as the
ability to easily convert bmp, jpg, and other data types, but lacks many of the ifs
capabilities, including the ability to manipulate images with any data type and any
number of dimensions. Version 8 supports this with a new version of any2any which
pretty much will convert any data type to any data type (there are some exceptions
of course). The new OpenCV interface also provides a new image viewing capability
which smoothly handles two- and three-dimensional images and color images.
1.0.3
New with Version 6
• Support for all processing platforms. Versions of IFS release 6 run on Intel computers
under the Microsoft Windows operating system.
• IFS Win32 has been tested under windows 2000 and windows XP. It has not been
tested (and will probably not work) under Windows 3.1
• Release 6 also runs under RedHat Linux, Enterprise. It has been run under RedHat
Fedora, but has not been tested thoroughly.
• Release 6 runs on the SUN platforms under Solaris. Release 6 runs on the Macintosh
under OS-X. It does not run under Mac OS 9.
• Compression By default, all files written by IFS 6 are compressed. They are automatically uncompressed on read. It is possible for the application program to set a
flag in the header telling the write subroutine to not compress the file. Uncompressed
files can be read by IFS 5, but compressed files can only be read by IFS 6.
• New, enhanced display capabilities
1.0.4
New with Version 5
• Support for X-windows. IFS images may now be displayed on any X-windows device.
The graphics support automatically determines the dynamic range of the graphics
device many X-windows devices are binary, for example ,and either thresholds or
dithers, at the users command.
1.1. USING IFS
11
• CPU independent code. Various computers use different conventions for storage
of bytes within a word, necessitating byte-swapping when one machine reads a file
written on another. Furthermore, depending on the computer, byte swapping may
be required on 16 bit or 32 bit boundaries, or both. Finally, there are at least two
different conventions for floating point data, DEC and IEEE,which must still be
corrected after byte swapping. IFS Version 5 automatically determines what type
of machine it is running on and determines what type of machine wrote the input
file. Should the input file be incompatible, the IFS file read routine automatically
performs all data conversions.
1.1
1.1.1
Using IFS
Program Compilation and Linking
In order to use IFS, the user needs to link his/her programs to the IFS library at compilation
time. To specify these libraries in a Unix environment, one would use the switches -lifs on
the cc or ld command. For example, a typical command to compile a program would look
like:
cc -g test.c -o test -lifs
The compiler directive
-lifs
actually tells the loader to look in /usr/lib or /usr/local/lib for a file named libifs.a. Not
all computers have libifs.a installed in the /usr directory, so the user may need to change
this command. Instead of using
-lifs
simply use the entire path the the library file. For example, it might be
cc whatever.c
/myhomedirectory/ifs/ifslbiraries/libifs.a
To actually make use of the IFS functions, the users program also needs to include a header
file or two to define various structures used by the IFS routines. All programs which use
IFS should include the files stdio.h and ifs.h. Most IFS routines will return error codes
through an external global variable called ifserr; if the user plans to examine these error
codes he/she should also include the header file ifserr.h. This file defines a set of symbolic
constants which one may use rather than using actual values for codes. It is not wise to
use actual values in place of these constants when writing programs as the deffnitions for
the constants may change from one release of IFS to the next.
12
CHAPTER 1. THE IFS SYSTEM
#include<stdio.h> #include<ifs.h>
main() {
IFSIMG img1,img2; /*Declare pointers to headers */
int len[3]; /*len is an array of dimensions, used by ifscreate*/
int threshold;/*threshold is an int here */ int row,col;/*counters */
int v; img1=ifspin("infile.ifs");/*read in file by this name */
len[0]=2;/*image to be created is two dimensional */
len[1]=128;/*image has 128 columns */
len[2]=128;/*image has 128 rows */
img2=ifscreate("u8bit" ,len, IFS_CR_ALL,0) ;/*image is unsigned 8bit */
threshold=55;/*set some value to threshold */
for(row=0;row< 128;row++) for(col=0;col< 128;col++)
{
v=ifsigp(img1,row,col);/*read a pixel as an int*/
if(v<threshold)
ifsipp(img2,row, col ,255); else ifsipp(img2, row, col, 0);
} ifspot(img2,"img2.ifs"); /*write image 2 to disk */
}
Figure 1.1: An example ifs program
1.2
Referencing IFS images
All IFS images include a header which contains various items of information about the
image, such as the number of points in the image, the number of dimensions for the image,
and the data format. Also associated with the image is the actual data for the image. The
image header includes a pointer to the image data in memory. The user manipulates an
image by calling some function in the IFS library; one of the arguments to the function
will be the address of the header for the image. The functions will automatically figure
out where the data is and how to access it from the information in the header. In addition
to handling the work of accessing data in images, the IFS routines automatically take care
of allocating of space in memory to store data and headers. Everything is totally dynamic
in operation; there are no fixed-dimension arrays needed. This relieves the user of the
difficulties involved with accessing data in arrays, when using C, when the arrays are not
of some fixed size. The header structure for an image is defined in the file ifs.h, and is
known by the name IFSHDR. To manipulate an image, the user merely needs to declare a
pointer to an image header structure as
IFSHDR *yourimage;
or, equivalently,
1.3. ERROR HANDLING IN IFS
13
IFSIMG yourimage;
Then, the user simply calls some IFS function to create a new image, and sets the
pointer to the value returned from that function. Some typical programs are given in the
examples in 1.1 through ??.
1.2.1
Naming conventions in IFS
Almost all of the IFS functions have names which begin with the letters ifs, so users should
have no problems avoiding conflicts when naming their own functions. Also, all external
variables or defined constants also begin with the letters“ifs” or “IFS”. Originally, all IFS
routines had names which were limited to 6 characters in an effort to improve compatibility
between different compilers. Unfortunately, with three of the letters already being fixed
as “ifs”, this doesnt leave much left to create meaningful function names with. Hence,
many IFS functions have rather cryptic names. Later versions of IFS have relaxed this
restriction, so that newer functions have longer and more descriptive names.
Starting with release 3.0 of IFS, all of the IFS functions also have version numbers
built into them. These version numbers are actually printable strings which are globally
accessible. These strings usually contain the functions name, a version number, and the
date of the last modification to the function. Other items of information may occasionally
also be contained in the string. If an IFS function has a name ifsXXXX, where XXXX
is just some stem naming the function, then the string which gives its version number
will have the name ifsvXXXX. For instance, if a user wanted to know what version of the
function ifscreate was in his IFSlibrary, he could include the statements
extern char *ifsv_create; printf("version is \%d \n",ifsv_create);
somewhere within her program.
1.3
Error handling in IFS
IFS provides various levels of error checking. When an error occurs, an IFS function usually
returns some sort of error flag. IFS also has two external global variables which relate to
error handling. The first one is known as ifserr, and is set to error codes which the user may
examine to help determine what went wrong. The second one is IFSSLV for IFS Severity
Level, which affects the action IFS takes upon detecting an error. Both of these variables
are declared as extern int variables in the header file ifs.h, so it is not necessary for the
user to declare them.
The various error codes which may be returned are defined in the header file ifserr.h,
which the user should make sure to include in his/her program if he/she plans on using
ifserr. These error codes are described in detail in Section 1.5. Scrutinizing the file ifserr.h
may also prove useful.
14
CHAPTER 1. THE IFS SYSTEM
The error codes are indicated by individual bits in ifserr, so it is actually possible for
several error flags to be set simultaneously. Also,some error codes are actually combinations of other codes. For instance, the codes IFSENOOPEN and IFSENOTIMAGE are
two possible errors which may occur when trying to read or write IFS images. If the user
checks for the condition IFSEIOERR, she has automatically tested for both of the errors
IFSENOOPEN and IFSENOTIMAGE. The way to test for such error codes is with the bitwise logical AND operator, rather than with a comparison. I.e.: if(ifserr&IFSE IO ERR)...
is preferable to:
if(ifserr == IFSE IO ERR...
because in this way, more than one bit may be tested, or just a single bit.
The second global variable, IFSSLV, allows the user to specify what action to take
when an error occurs. Currently, there are three possible courses of action to take upon an
error;these are chosen by setting IFSSLV to some severity level code. The three severity
levels are represented by the constants IFSQUIET, IFSWARN, and IFSFATAL, which are
defined in ifs.h. These affect the action taken upon the occurrence of an error as follows:
• IFSQUIET Do not print out any error messages to the user. The function just returns
an error code to the calling routine. The user must make sure to watch out for this
code, and act accordingly. If the error is not handled, the program will probably
crash.
• IFSWARN If an error occurs, print out some message describing the error to stderr.
The routine also returns the appropriate error code. This allows the user to know
what is going on, but still allows the program to trap errors. IFSWARN is probably
the recommended severity level for most applications, and is the default value for
IFSSLV.
• IFSFATAL If an error occurs, print out an error message, and abort the program.
This is not an exceedingly user-friendly option, but is probably better than the perennial Unix favorite “buserror:core dumped”.
1.3.1
Image validation in IFS
Most IFS functions will double-check the header of an image before attempting to perform
some operation on the image. This is done to verify that the argument the user passed to
the function legitimately points to an IFS image, and does not just represent some random
value. The most likely source for such an error would be insufficient error checking in a
users program, when the severity level variable IFSSLV was set to some value other than
IFSFATAL. For instance, a section of code such as
img=ifsmkh(nrows,ncols,ubyte");
ifsipp(img,10,20,255);
1.3. ERROR HANDLING IN IFS
15
#include <stdio.h>
#include <ifs.h>
main() {
IFSIMG img1,img2; /*Declare pointers to headers */
int *len; /*len is an array of dimensions, used by ifscreate*/
int frame,row,col; /*counters */
float threshold,v; /*threshold is a float here */
img1 = ifspin("infile.ifs"); /*read in file by this name */
len = ifssiz(img1); /*get dimensions of input image */
/*ifssiz returns a pointer to an array of dimensions*/
img2 = ifscreate(img1->ifsdt, len, IFS_CR_ALL,0); /*output image is to be*/
/*same type as input */
threshold = 55; /*set some value to threshold */
/* check for one, two or three dimensions*/
switch(len[0]
{
case 1: /*1dsignal*/
{
for(col=0;col<len[1];col++)
v=ifsfgp(img1,0,col);/* read a pixel as a float*/
if(v<threshold) ifsfpp(img2,0,col,255.0);/* write a float */
/* if img2 not float, will be converted*/
else ifsfpp(img2,0,col,0.0);
}
break;
case 2:/*2dpicture*/ for(row=0;row<len[2];row++)
for(col=0;col<len[1];col++) {
v=ifsfgp(img1,row,col);/*read a pixel as a float*/
if(v<threshold)
ifsfpp(img2,row,col,255.0);/* store a float */
else ifsfpp(img2,row,col,0.0);
} break;
Figure 1.2: First portion of example, see Figure 1.3 for remainder
16
CHAPTER 1. THE IFS SYSTEM
case3:/*3dvolume*/
for(frame=0;frame<len[3];frame++)
for(row=0;row<len[2];row++)
for(col=0;col<len[1];col++)
{
v=ifsfgp3d(img1,frame,row,col);/*read a pixel as a float */ if(v<threshold
ifsfpp3d(img2, frame, row, col, 255.0); else
ifsfpp3d(img2,frame,row,col,0.0);
}
break;
default: printf(" Sorry I cant do 4 or more dimensions\n");
}
ifspot(img2,"img2.ifs"); /*write image2 to disk */
}
Figure 1.3: Example IFS program to threshold an image using number of dimensions, size
of dimen-sions, and data type determined by the input image
(Although the example above uses ifsmkh, it is now recommended that ifscreate should be
used instead.)
which attempts to create an image and set the pixel at location 10,20 to a value of 255
could be a potential source for an error, if ifsmkh had been incapable of creating the image
as requested. It would then have returned the value NULL, which would be passed to the
function ifsipp. If ifsipp did not check the header, it would blindly attempt to use NULL
as a pointer to an image header, which would probably crash the users program.
The problem with this error checking is that it takes time to perform. If an image was
100 by 100 pixels in size, and the routine ifsipp was used to set the value of each pixel
in the image, then the header would end up being checked 10000 times! For a program
which accesses an image heavily, this header checking overhead takes a significant amount
of time. Timing analyses on sample programs have shown that it is possible for 30 % of
the CPU time used by a program to be spent in the header checking operation.
The user may disable the header checking operation in some IFS routines. This, of
course, places upon the programmer the responsibility to perform more extensive error
checking operations, if robust code is desired. If the user sets the external integer variable
IFSCHK to zero, then certain routines will cease to check image headers. Header checking
can be reenabled by setting IFSCHK to any non-zero value. Note that not all of the IFS
routines are affected by IFSCHK. Generally, only those routines which are called with
high frequency, and for which the header checking represents a significant fraction of the
execution time for that function, will be affected by this variable. Incidentally, it is not
necessary for the users program to declare IFSCHK. As with IFSSLV and ifserr, this is
1.3. ERROR HANDLING IN IFS
17
#include <stdio.h>
#include <ifs.h> main()
{
IFSIMG img1,img2; /*Declare pointers to headers*/
int len[3]; /*len is an array of dimensions, used by ifscreate*/
int size; /*number of bytes in image*/
int threshold; /*threshold is an int here*/
register int count; /*number of pixels in image*/
register unsigned char *ptri,*ptro;
img1=ifspin (""); /*read in file; prompt user for name*/
len[0]=2; /*image to be created is two dimensional*/
len[1]=ifsdimen(img1,0); /*get columns of input*/
len[2]=ifsdimen(img1,1); /*get rows of input*/
img2=ifscreate("u8bit",len,IFS_CR_ALL,0); /*image is unsigned 8 bit*/
threshold=55; /*set some value to threshold*/
ptri = (unsigned char *) img1->ifsptr; /*get address of input data*/
ptro=(unsigned char *) img2->ifsptr; /*get address of output data*/
size= len[1] * len[2]; /*compute number of pixels*/
for(count=0;count<size;count++)
{
if(*ptri++ >= threshold) *ptro = 255; else
*ptro=0; ptro++; }
ifspot(img2,""); /*write image2 to disk, prompt user for filename */
}
Figure 1.4: Example: A more sophisticated version of an IFS program to threshold an
image using two dimensions, size of dimensions d and defined data type of unsigned char
on both files. Pointers are used for speed.
18
CHAPTER 1. THE IFS SYSTEM
#include <stdio.h>
#include <ifs.h>
#include <ifserr.h> /*optional*/
int main()
{
IFSHDR *img1,*img2; /*Declare pointers to headers*/
. . .
img1=ifsmkh(128,128,"char"); /*make a 128*128 2-d image*/
/* Space for data & header are automatically allocated */
....manipulateimage1
.....
img2 = ifs_exwin(img1,10,10,100,75); /*e1x2tract a sub-image*/
/*of the original image, img1, and call it img2*/
ifspot(img1,"img1.ifs"); /*writeimage1todisk */
}
declared in the header file ifs.h.
1.3.2
Header Files
The ifs user will find it convenient to include one or more of several header files, as listed
below:
ifs.h This is the main header file. Most programs which use ifs will need this file. It defines
the ifs header, and the types of many of the ifs functions.
ifstypes.h This file is useful if the user wishes to determine the data type of an image. It
defines things like IFSA U8BIT, as in the example below:
#include <ifsltypes.h>
...
if (img->dtype == IFST_32FLT)
...
which checks if the data type of image img is 32 bit float.
ifserr.h See section ??
ifsmatrix.h Defines the values returned by the matrix operation functions. See section
2.2.2
1.3. ERROR HANDLING IN IFS
1.3.3
19
Coordinate systems and array storage in IFS
IFS stores arrays in the same manner that C normally does. As with C, the indices for
arrays start with zero rather than one. For example, if you create an image with 30 rows
and 20 columns, then valid row indices for that function range from 0 to 29, and column
indices may go from 0 to 19. One common source of confusion is the usage of the terms
row and column to denote array subscripts when working with 2-dimensional arrays. It is
quite typical for a users program to viewthe coordinate system in terms of an x and a y
axis. The intent in IFS is that the column axis represents the horizontal axis, and the row
axis is the vertical. Hence the width of the image is equivalent to the number of columns
in the image, and height is the number of rows. It is common usage that the x axis is the
horizontal axis, hence a column coordinate is synonymous with an x coordinate. If this
is the coordinate system you normally use, beware of the temptation to write code of the
form:
int x,y; ... for ( x=0; x<width; x++) for( y=0;y<height; y++){ ifsipp(img, x, y, value); ... }
The correct code in this case should be:
int x,y; ... for(x=0;x<width;x++) for(y=0;y<height;y++){ ifsipp(img,y,x,value); ...}
Unfortunately, people have a tendency to write coordinate pairs as (x, y) or (row,column),
but these two are not synonymous if you interpret x, y, row,and column in the manner
described above.
A second problem occurs when displaying images on graphics output devices. There is
no set standard as to where the origin of the coordinate system is among graphics displays.
It is probably most common that the origin is in the upper left corner of the display, and
moving in the positive direction along the column axis moves you to the right, and moving
in the positive direction along the row axis moves you downwards. Some devices place
the origin in the lower left corner of the screen, and moving in the positive row direction
moves you towards the top of the display. The positive column direction still usually is
to the right. This also corresponds to the way most people label axes when hand-drawing
a graph. The net affect here is that images displayed in this coordinate system will be
upside-down as compared to the first type of system. To further confound the issue, many
programs which plot on printers reverse the meaning of the x and y axes, so that images
plotted in this manner are rotated by 90 degrees in one direction or another.
The point of these warnings about display coordinate systems is that IFS knows nothing
about the nature of the users display mechanism. There is no specific “up”, “down”, “left”,
or “right”. The user should not be too surprised if an image appears flipped or rotated
from what was expected.
20
1.4
CHAPTER 1. THE IFS SYSTEM
IFS FUNCTION LISTING
This section lists all of the functions in the IFS library, in alphabetical order. The convention used to describe the syntax for the function is:
return_value=function_name(arg1,arg2,....);
type of return_value; type of arg1; type of arg2;....
where “type of” denotes a C variable type (such as “int”, “float”, “char* ”, or “IFSHDR*”,
or other TYPEDEFs or STRUCTs). For instance, the sample description
p=ifsalc(numbytes); char *p; int numbytes;
indicates that the function ifsalc returns a pointer to a character, and that it takes one
argument, which is an integer.
1.4. IFS FUNCTION LISTING
1.4.1
21
bilininterp
//====================bilininterp================
Function to perform bilinear interpolation to find the best estimate of a pixel brightness
using the four surrounding pixels.
arguments: an ifs image, frame, row, column values
Returns the estimate.
POTENTIAL BUG: does not check if this pixel is next to the end of the image
note, this version does not interpolate in the frame direction
set frame = 0 to interpolate a 2D image
This function is part of the iptools function library, so you need to load libiptools.a in
addition to ifs.a
float bilininterp(IFSIMG inimage, int frame,float row, float col);
1.4.2
ifsalc
ifsalc – allocate storage (memory)
cptr=ifsalc(NumBytes); char *cptr; int NumBytes;
Ifalc is an IFS function used to allocate storage in main memory such as for storing arrays
and image headers. The storage will be initialized to all zeroes. It is essentially just a
call to the system function calloc; the only difference being that ifsalc performs a small
amount of error checking. If the system cannot allocate the requested amount of storage,
then ifsalc will return the value NULL, and the external variable ifserr will be set to the
value IFSENOMEM. If the external variable IFSSLV is not set to the value IFSQUIET,
then ifsalc will write an error message to stderr if it cant allocate the requested space. If
IFSSLV is set to IFSFATAL, then ifsalc will also abort your program upon an error.
22
CHAPTER 1. THE IFS SYSTEM
1.4.3
ifscigp read from complex or real image
ifscigp – get pixel value from a 2-d (possibly complex) image Usage:
val = int ifscigp(ptri,row,col) IFSHDR *ptri; /*pointer to image header structure */
int row, col, val; /*coordinates - in pixels - of pixel to examine.*/
Ifscigp returns - as an int - the value of the pixel at a specified coordinate in a 2-d image.
If image is complex format, returns the imaginary portion of the number. Known Bugs,
Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in an int for example, a large number in a float or complex
image ,then results are undefined. Maybe you get garbage, maybe your program
aborts on an overflow type of error.
1.4. IFS FUNCTION LISTING
1.4.4
23
ifscigp3d
ifscigp3d – get pixel value from a 3d-dimage Usage:
val = int ifscigp3d(ptri,frame,row,col);
IFSHDR *ptri; /*pointer to image header structure*/
int frame, row, col; /*coordinates in pixels of pixel to examine.*/
Ifscigp3d returns as an integer the value of the pixel at a specified coordinate in a 3-d
image. If image is complex format, returns the imaginary portion of the number assuming
it can be converted to an int. Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in an int for example, a large number in a float or complex
image then results are undefined. Maybe you get garbage, maybe your program
aborts on an overflow type of error.
24
CHAPTER 1. THE IFS SYSTEM
1.4.5
ifscipp
IFS library:
libifs.a
ifscipp: set pixel value in a 2-d image usage:
status = ifscipp(ptri,x,y,val);
IFSHDR *ptri; /*pointer to image headers tructure*/
int x,y; /*coordinates -- in pixels -- of pixel to examine.*/
int val;
int status; /*return status*/
Returns: IFSSUCCESS or IFSFAILURE
Ifscipp sets the value of the pixel at a specified coordinate in a 2-d image, where the
input is an int. If image is complex format, stuffs the imaginary portion of the number,
and DOES NOT set the real part to zero.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in an int for example, a large number in a float or complex
image then results are undefined. Maybe you get garbage, maybe your program
aborts on an overflow type of error.
1.4. IFS FUNCTION LISTING
1.4.6
25
ifscipp3d
ifscipp3d: set pixel in a 3-d image usage:
status = ifscipp3d(ptri, frame, row, col, val);
IFSHDR *ptri; int frame, row, col; /*coordinates in pixels of pixel to examine.*/
int status; /*return status*/
Returns: IFSSUCCESS or IFSFAILURE
Ifscipp sets the value of the pixel at a specified coordinate in a 2-d image, where the
input is a int. If image is complex format, stuffs the imaginary portion of the number, and
DOES NOT set the real part to zero.
Known bugs, special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the value stored wont fit in the output image datatype, then results are undefined.
Maybe you get garbage, maybe your program aborts on an overflow type of error.
26
CHAPTER 1. THE IFS SYSTEM
1.4.7
ifscfgp
ifscfgp: get value of a pixel in a 2-d image. usage:
val - double ifscfgp(ptri,row,col); IFSHDR *ptri;
int row,col; /*coordinates (in pixels) of pixel to examine.*/
Ifscfgp returns (as a float) the value of the pixel at a specified coordinate in a 2-d image.
If image is complex format, returns the imaginary portion of the number. Known bugs,
special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in a double results are undefined. Maybe you get garbage,
maybe your program aborts on an overflow type of error. There could be possible
round off errors.
1.4. IFS FUNCTION LISTING
1.4.8
27
ifscfgp3d
ifscfgp3d: get value of a pixel in a 3-d image usage:
val = (double) ifscfgp3d(ptri,frame,row,col); IFSHDR *ptri;
int frame, row, col; /*coordinates (in pixels) of pixel to examine.*/
ifscfgp3d returns (as a double) the value of the pixel at a specified coordinate in a 3-d
image. If image is complex format, returns the imaginary portion of the number.
Known bugs, special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in a double results are undefined. Maybe you get garbage,
maybe your program aborts on an overflow type of error. There could be possible
round off errors.
28
CHAPTER 1. THE IFS SYSTEM
1.4.9
ifscfpp
ifscfpp: set value of a pixel in a 2-d image. usage:
status = ifscfpp(ptri, x, y, val);
IFSHDR *ptri;
int x,y; /*coordinates (in pixels) of pixel to examine.*/
double val; /*the value to stuff.*/
int status;
Returns: IFSSUCCESS or IFSFAILURE
Ifscfpp sets the value of the pixel at a specified coordinate in a 2-d image, where the
input is a float. If image is complex format, stuffs the imaginary portion of the number.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the value stored wont fit in the output image datatype, then results are undefined.
Maybe you get garbage, maybe your program aborts on an overflow
1.4. IFS FUNCTION LISTING
1.4.10
29
ifscfpp3d
ifscfpp3d: sets the value of a pixel in a 3-d image (This is a completely new version of
ifsfpp which handles 3-d images.) usage:
status = ifscfpp3d(ptri, frame, row, col, val);
IFSHDR *ptri;
int frame, row, col; /*coordinates (in pixels) of pixel to examine.*/
double val; /*the value to stuff.*/
int status;
Returns: IFSSUCCESS or IFSFAILURE I fscfpp3d sets the value of the pixel at a
specified coordinate in a 3-d image, where the input is a float. If image is complex format,
stuffs the imaginary portion of the number.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the value stuffed wont fit in the output image datatype, then results are undefined.
Maybe you get garbage, maybe your program aborts on an overflow type of error.
30
1.4.11
CHAPTER 1. THE IFS SYSTEM
Ifsclose
ifsclose: close an open file Usage:
rc = ifsClose(File);
FILE *File;
int rc;
Ifsclose, an ifs internal function seldom used by typical programmers, is identical to the
standard I/O library function fclose, except that it will avoid closing File if File corresponds
to stdin, stdout, or stderr. If File is NULL, ifsclose returns -1, else it just returns whatever
value fclose would return. Ifsclose is supplied as a complement to ifsOpen since the latter
function may return stdin or stdout in some circumstances, and the user typically does not
want to close these files.
1.4. IFS FUNCTION LISTING
1.4.12
31
ifscreate
ifscreate: create an IFS image Usage:
img = ifscreate(type, len, flags, structsize);
IFSHDR *img;
char *type;
int len[];
int flags;
int structsize;
Ifscreate is used to create a new IFS image or image header. Space for the header is
automatically allocated, and a pointer to the header is returned. Various fields in the header
structure will be set to default values. Space for the actual data may also be allocated,
depending on the value of the flags variable. If space for the data array is allocated, it will
be filled with zeros. If the image can not be created, ifscreate returns the value NULL,
and the external variable ifserr will be set to some error code, as given in the #include
file ifserr.h . The image as created will not have any tail structure associated with it. The
arguments to ifscreate are:
type The data format for individual pixels, such as byte or double. The valid data types
are listed in a later section of this manual. If the data type is not recognized by
IFS, then ifscreate will return NULL, and ifserr will be set to the code IFSE BAD
DTYPE.
len An n+1-length integer array the first element (len[0]) gives the number of dimensions
for the image, the remaining elements give the length for each dimension of the
image being created. This is in exactly the same format as the arrays returned by
the function ifssiz. The lengths are given in terms of ascending rank for the image.
Images are stored in standard C storage order: the column or x index changes most
rapidly when scanning through memory, hence this dimension has rank 1. The row
or y index has rank 2, the frame or z index has rank 3, and so on. I.e., the second
element of the array (len[1]) gives the number of columns of the image, len[2] is the
number of rows, etc.
flags The various bits of this argument determine precisely what is and is not allocated
when generating the image. If flags = IFS CR ALL or IFS CR DATA, then storage
space for the image is allocated, as well as storage for the image header. In this case
the field img->ifsptr points to the data storage. If flags = IFS CR HDR then only
space for the image header is allocated. The field img->ifsptr will be set to NULL.
The user must supply an array to store the image in, and set img->ifsptr to point to
this array. Note: versions 4.0, 5.0, and 6 of ifscreate will ALWAYS allocate space for
32
CHAPTER 1. THE IFS SYSTEM
the image header; the flag IFS CR HDR is not really examined, and is only intended
for possible future expansion. All that is really checked is the IFS CR DATA bit.
The flag IFS CR ALL is the combination of IFS CR DATA and IFS CR HDR and is
probably the best flag to use if one wants data space allocated.
structsize This argument is only needed if type is struct, in which case it gives the size of
a single data element (structure) in bytes. If type is not struct this argument should
be set to 0.
Example of using ifscreate with a data type of struct:
/* Create a 2-d image with 20 rows and 30 columns */ /* and a 1-d array of 10 structures
#include <ifs.h>
main()
{ IFSHDR * img, * strimg;
int lengths[3]; IFSHDR * ifscreate();
typedef struct { int red; int green; int blue; } RGB; . . . /* create 2D byte array */
lengths[0] = 2; /* Image will be 2D */
lengths[1] = 30; /* Number of columns (width; x-dimension) */
lengths[2] = 20; /* Number of rows (height; y-dimension) */
img = ifscreate("ubyte", lengths, IFS_CR_ALL);
if (img == NULL) { /* error processing code */
} . . . /* create 1D structure array */ lengths[0] = 1;
lengths[1] = 10;
strimg = ifscreate("struct",lengths,IFS_CR_ALL,sizeof(RGB)); . .
.
1.4. IFS FUNCTION LISTING
33
Routines which are compatible with openCV
In order to make use of the capabilities of openCV, and still retain the usefulness of IFS,
several new functions are available to go between the two formats. openCV uses an image
format called IPL, which is very similar to ifs in many ways. Most openCV functions do
not support all the data formats that ipl supports, and ipl does not support some of the
data types that ifs supports. In particular, the data types complex short, and complex are
supported by ifs, but not by ipl.
1.4.13
ifs2ipl
Converts an ifs image to an ipl-format image of the same data type. It returns a pointer
to an ipl image
IplImage *ifs2ipl(IFSIMG inputimage);
Note that the old image is NOT deleted, but a new image is created using memory
allocation. This is a potential memory leak unless the user is careful. If the old ifs image
is no longer needed, it can be deleted using
ifsfree(oldimage,IFS_FR_ALL);
which will delete the image, and the header and the tail (if there is a tail).
1.4.14
ipl2ifs
Converts an ipl image to an ifs-format image. It returns a pointer to an ifs image
IFSIMG ipl2ifs(IplImage
*inputimage);
Note that the old image is NOT deleted, but a new image is created using memory
allocation. This is a potential memory leak unless the user is careful. If the old image is
no longer needed, it can be deleted using
cvReleaseImage(&imagepointer);
1.4.15
ifsCVpin
Reads an image from the disk. If it is an ifs image already, The ifs format will be retained
in memory. If it is
• Windows bitmaps - BMP, DIB,
34
CHAPTER 1. THE IFS SYSTEM
• JPEG files - JPEG, JPG, JPE,
• Portable Network Graphics - PNG,
• Portable image format - PBM, PGM, PPM,
• Sun rasters - SR, RAS, or
• TIFF files - TIFF, TIF
it will be converted to ifs and stored in ifs format in memory.
IFSIMG ifsCVpin(char *filename);
1.4.16
ifsCVpot
Writes an ifs image to disk. If the target file name has the extension “ifs”, it will be written
retaining the original ifs format. If the target is any of the other image types, the image
MUST be unsigned char, since that is the only format supported by the ipl write software.
int ifsCVpot (IFSIMG imagepointer, char *filename);
1.4.17
ifsCVPopup
This will pop up a window on the user’s screen with an image in it. ifsCVPopup is also
usable as a general-purpose image viewing program. If you don’t want to use it as a subroutine (and have to deal with linking to openCV), you can get the same functionality
using the program ifsview.
IplImage *ifsCVPopup(IFSIMG imagepointer, int colorflag,int ignoreflag, int scaleflag );
The colorflag, if 1, means that a 3D, 3frame image should be interpreted as color rather
than as a 3 frame image. example use, put up an image, wait for a user interaction, and
close the screen window. The window is named “img1”. The ignore flag argument only
affects contrast enhancement. If it is greater than zero, than any pixel of that brightness
will not enter the calculation of contrast stretching. This is useful if you want to look at
an image containing artificially added graphics with a special brightness, like 255.
The scaleflag only affects 3D images. if scaleflag is one, each frame will be video scaled
independenlty, if zero, the entire image will brightness scaled the same.
IFSIMG iggle;
IplImage *oggle;
oggle = ifsCVPopup(iggle,0,-1);// put up the image, don’t ignore anything
1.4. IFS FUNCTION LISTING
35
cvReleaseImage(&oggle);// free the memory used by the temporary creation of
an image to display
cvWaitKey(0);//wait for the user to hit a key in the display window
cvDestroyWindow("img1"); //close the window on the screen
Note the ampersand in the call to cvReleaseImage. Yes, it is a pointer to a pointer. The
pointer itself will be freed as well as the image. The image will stay on the screen until the
user closes it, or the program exits.
CAUTION: When the file is converted from ifs to ipl, the temporary ipl image is not
deleted, since the use may want it. This is a potential memory leak if the user does not
delete the temporary image after she is finished displaying it. As illustrated above, IPL
images can be freed using
cvReleaseImage( &imagepointer);
Using a poped-up Image:
Once you have called ifsCVPopup, you have a variety of options:
• LOUPE As soon as the image pops up, and you move the mouse over it, another
image will pop up which is a zoomed1 version of the original image, zoomed about
where the mouse is. We will refer to this second image as the “loupe” image, as in a
jewler’s loupe. As you move the mouse, the second image will move around also.
• Stopping the tracking A right click on the original image will freeze the loupe image. A
second right click will turn tracking back on. On the mac, a right click is accomplished
by hitting the trackpad with two fingers simultaneously.
• Additional zoom With the pointer on the original image, you can use right and left
arrow keys to increase or decrease zooming (respectively). Note that you will not see
the result of the zoom until you move the mouse again, which will refresh the loupe
image. Note: some versions of Linux are not compatible with each other as far as
the code used to represent an arrow key. For that reason, the following alternative
keys may be used:
– i uparrow
– m downarrow
– j leftarrow
– k rightarrow
– return key return to the calling program
1
Well, it is in the scale of the original image. If the original image is 4000 × 4000, the loupe image will
seem significantly zoomed. However, it is is 512 × 512, no zoom will be apparent
36
CHAPTER 1. THE IFS SYSTEM
• Image values – original image Clicking on the original image will return the brightness
at the point of the click, or if color, will return the R,G,B values.
• Image values – loupe image To look at points in great detail, first move the mouse
to get to where you want to be in the original image. Then right click to turn off
tracking. Move the pointer to the loupe image, and click on any point. The brightness
or color of that point will be returned.
• Exploring 3D images With the mouse on the original image (tracking can be on or
off), the up and down arrow will display different frames of the 3D image. Remember
that these values don’t show up in the loupe image until you move the mouse.
• Enhancing contrast The lower-case c key will toggle contrast enhancement on or off.
When on, the loupe image will be displayed with enhanced contrast.
• Returning If you hit control C, you will be returned to the top (system) level. If you
hit return, you will be returned to whatever program call the ifsCVPopup function.
If that program was ifsview, it will, in turn, return you to the system.
Should you simply wish to display an image and obtain information about it, use the
program ifsview, which is just a wrapper around ifsCVPopup, and that way, you won’t
need to mess with linking openCV, which can be a painful hassle.
1.4.18
IFSDISPLAY
The module IFSDISPLAY in the directory iptools contains two important subroutines that
allow you to display images. int CreateIFSDisplayWindow and WriteToIFSDisplayWindow. The first of these creates a window into which you can put an ifs image and display
it. The second allow you to rewrite what is in that display window.
Usage:
int CreateIFSDisplayWindow(IFSIMG img,float zoom);
Zoom is a scale factor, which can be used to make the displayed image larger. The integer
returned is an index allowing the user to display more than one image at the same time.
A maximum of ten images may be simultaneously displayed.
int WriteToIFSDisplayWindow(int whichwindow,IFSIMG img,int frame,float zoom);
This function allows the user to overwrite the contents of a particular screen. The dimensions of the new image must match those of the original.
1.4. IFS FUNCTION LISTING
1.4.19
37
Building ifsCV and IFSDisplay with openCV
You can compile and load the openCV routines listed above using the same operations that
you used to build ifs, except you need to tell the linker to load the CV subroutines. Here
is a compile example that will do this in xcode. (add this item to the build instructions)
OTHER_LDFLAGS = -lcxcore /Users/wes/src/ifs/MacX/ifslib/libifs.a -lcvaux -lhighgui -lcv
If you are using a makefile, the compile command would be something like
cc -o myprogram -lxcore Users/wes/src/ifs/MacX/ifslib/libifs.a -lcvaux -lhighgui -lcv
This assumes, of course, that the openCV libraries were installed in the standard places
(/usr/local/lib), and have the standard names (libhighgui.a rather than libhighgui.2.3.a)
If you didn’t install them there, you will need to use the full path name, instead of the
shortened path, and if the version number is included with the library file names, you will
need to use it. It’s simpler to just use ifsview.
38
1.4.20
CHAPTER 1. THE IFS SYSTEM
ifsdimen
ifsdimen: get size of dimensionUsage:
len = ifsdimen(image, n);
int len;
IFSHDR*image;
int n;
Ifsdimen returns the length (number of elements) of the nth dimension of image. It also
may be used to get the total number of elements or bytes required by the data section of an
image. The argument n is the rank of the dimension being queried, i.e., ifsdimen(img,0) is
the number of columns, ifsdimen(img,1) is the number of rows, and so on. If n is specified
as -1, ifsdimen returns the total number of elements in the image (the product of all the
individual dimension lengths). If n is specified as -2, ifsdimen returns the total number of
bytes occupied by the image data, i.e., the total number of elements times the size in bytes
for a single element. If there is some error, ifsdimen returns zero and sets the external
variable ifserr appropriately. Possible error conditions are IFSE BAD HEADER or IFSE
NULL HEADER for invalid images, or IFSE WRONG NDIM if n is invalid (such as asking
for the number of frames for a 2D image).
1.4. IFS FUNCTION LISTING
1.4.21
39
ifsexwin
ifsexwin: Extract a window from an image Usage:
new = ifsexwin(old, r1, c1, r2, c2); IFSHDR *new, *old; int r1, c1, r2, c2;
Ifsexwin is used to create a new image which is a subimage of some old image The old
image must be a two-dimensional image. The arguments r1,c1 and r2,c2 give the row and
column positions of the corners of a box which defines the region to be extracted. These
corners must be on opposite ends of a diagonal for the window It does not matter which
corners are chosen for each point, as long as as they are on opposite ends of a box diagonal.
The region extracted includes the area of the bounding box itself, ie, is inclusive of the
rows r1, r2 and columns c1, c2. Ifsexwin returns a pointer to the newly created image, or
NULL if some error occurred. In the latter case, the external variable ifserr will be set to
indicate the nature of the error. Possibilities are:
• IFSE BAD HDR If the pointer old does not point to a valid IFS image.
• IFSE NO MEM If space couldnt be allocated for the new image.
• IFSE WRONG NDIM If the original image is not two-dimensional.
• IFSE BAD POS If either of the box coordinates is outside the image dimensions.
The dimensionality of windowed image is consistent. That is, a 1-d/2-d slice ( a 3-d image
one voxel thick in one or more dimensions) returns with a header consistent with the actual
dimensionality.)
40
1.4.22
CHAPTER 1. THE IFS SYSTEM
ifsexwin3d
ifsexwin3d: Extract a window from an image usage:
newimg = ifsexwin3d(oldimg,f1,r1,c1,f2,r2,c2)
where f1,r1,c1 and f2,r2,c2 are the coordinates (frame,row,col) of one corner of the box
and the opposite (diagonal) corner. It doesnt matter which corners are chosen.The box
which is extracted includes the bordering surface (i.e, coordinates are f1,r1,c1 to f2,r2,c2
INCLUSIVE). Returns: This function returns NULL if an error occurs, and returns an
error code thru the external variable ifserr. External variables: ifserr, IFSSLV Ifsexwin3d
extracts a piece (window) out of a 3-d IFS image, to make a new IFS image. The data
type of the new image is identical to that of the old one. The dimensionality of windowed
image is consistent. That is, a 1-d/2-d slice ( a 3-d image one voxel thick in one or more
dimensions) returns with a header consistent with the actual dimensionality.
1.4. IFS FUNCTION LISTING
1.4.23
41
ifsfgp
ifsfgp: get pixel from a 2-D image Usage:
value = ifsfgp(img, row, col);
double value;
int row,col;
IFSHDR *img;
Ifsfgp is used to get the value of some pixel in a 2-dimensional image. The value returned
is of type double, regardless of what the data format of the image is. Otherwise, ifsfgp is
identical to the function ifsigp, in all respects. See the documentation for ifsigp for more
details.
42
CHAPTER 1. THE IFS SYSTEM
1.4.24
ifsfgp3d
ifsfgp3d: gets the value of a pixel in a 3-d image (A generic multidimensional fgp can be
attempted thru variable parameter passing, but that would make the code unportable.)
usage:
val = ifsfgp3d(ptri, frame, row, col);
IFSHDR *ptri; /*pointer to image header structure*/
int frame, row, col; /*coordinates (in pixels) of pixel to examine.*/
double val;
Ifsfgp3d returns (as a double) the value of the pixel at a specified coordinate in a 3-d
image. If image is complex format, returns the real portion of the number.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the pixel value wont fit in a double then results are undefined. Maybe you get
garbage, maybe your program aborts on an overflow type of error. Round off error
can occur in conversions. e.g. int to double typecasting.
1.4. IFS FUNCTION LISTING
1.4.25
43
ifsfpp3d
ifsfpp3d: set the value of a pixel in a 3-d image usage:
status = ifsfpp3d(ptri, frame, row, col, val);
\index{ifsfpp3d}\index{put pixel}
IFSHDR *ptri; /*pointer to image header structure*/
int frame, row, col; /*coordinates (in pixels) of pixel to examine.*/
double val; /*the value to stuff*/
int status;
Returns: IFSSUCCESS or IFSFAILURE
Ifsfpp3d sets the value of the pixel at a specified coordinate in a 3-d image, where the
input is a float. If image is “complex” format, stuffs the real portion of the number.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the value stuffed wont fit in the output image data type, then results are undefined.
Maybe you get garbage, maybe your program aborts on an overflow type of error.
44
CHAPTER 1. THE IFS SYSTEM
1.4.26
ifsfpp
ifsfpp: put pixel value into a 2-D image status = ifsfpp(img, row, col, value); int status;
double value; int row, col; IFSHDR *img; Ifsfpp3d sets the value of the pixel at a specified
coordinate in a 3-d image, where the input is a float. If image is complex format, stuffs
the real portion of the number.
Known Bugs, Special notes:
• This routine does not check to see if the specified coordinates actually are in bounds.
• If the value stuffed wont fit in the output image datatype, then results are undefined.
Maybe you get garbage, maybe your program aborts on an overflow type of error.
1.4. IFS FUNCTION LISTING
1.4.27
45
ifsfree
ifsfree: delete and deallocate an IFS image img = ifsfree(img,flags); IFSHDR *img; int
flags; Ifsfree is used to get rid of an IFS image which is no longer in use. The space for
the header and/or data is deallocated, and returned to the operating system for other use.
Basically, ifsfree just consists of several calls to the system function cfree. The arguments
to ifsfree are:
• img A pointer to the image header structure.
• flags A set of flags which indicates exactly what is to be deallocated. Possibilities for
the flags are:
– IFS FR DATA If this flag is set, then ifsfree will deallocate the space allocated
for the storage of the actual image data (if there is any), and the header field
img->ifsptr will be set to NULL to show that the header no longer has any data
associated with it. If there is no data associated with the header, then this flag
has no effect. This will not cause any errors.
– IFS FR HDR If this flag is set, then ifsfree will deallocate the space allotted for
the image header. The data space is left intact. This is usually only going to
be used if the user supplied his own data area for the image (perhaps a static
array or somesuch).
– IFS FR ALL If this flag is specified, then ifsfree will free up everything image
header and data. IFS FR ALL is just the combination of IFS FR DATA and IFS
FR HDR. This is probably the normal flag to set when calling ifsfree . Ifsfree
returns a pointer to the image header as it should be AFTER the desired things
have been deallocated. If only the IFS
– FR DATA flag was specified, then ifsfree returns the original pointer value img,
with the field img->ifsptr now set to NULL to show that the data array has
been deleted. If the header structure was freed, then ifsfree returns NULL to
indicate that the pointer is no longer valid. Hence it is good practice to assign
the return value from ifsfree back to the original pointer value img. It is not an
error to simply say ifsfree(img,IFS FR ALL) rather than img = ifsfree(img,IFS
FR ALL) to get rid of an image, but the latter usage is preferable in that it will
make it more obvious to any subsequent routines called (erroneously) with the
argument img. Ifsfree will also return the value NULL if an error occurred. In
this case, the external variable ifserr will be set to the appropriate error code.
Possible error conditions are:
• IFSE NULL HDR This indicates that you passed the pointer NULL for the argument
img.
46
CHAPTER 1. THE IFS SYSTEM
• IFSE BAD HDR This indicates that the pointer img does not reference a valid IFS
image structure. Note that the error IFSE NULL HDR is actually a subclass of the
error IFSE BAD HDR, so if you test the value (ifserr & IFSE BAD HDR), you will
automatically also pick up errors of the type
• IFSE NULL HDR.
BUGS (features):
Trying to deallocate something which was not originally obtained using some standard
system memory-allocation function (e.g, calloc, or the IFS routines ifsalc or ifscreate)
will cause grave errors usually a program crash. This is a problem of the system
allocate/deallocate routines and not ifsfree.
1.4. IFS FUNCTION LISTING
1.4.28
47
ifsGetFN
ifsGetFN: read in a filename and expand it
Usage:
FileName = ifsGetFN(Prompt,Input);
char *FileName;
char *Prompt;
FILE *Input;
IfsGetFN will read in a string from the file Input (typically stdin), and expand it using the
function ifsPrsFN. It returns a pointer to the name it read, or NULL if it failed. Space
for the filename is dynamically allocated and may be freed (using cfree) when the user
is through with it. If Input is a terminal, and Prompt is not NULL, then Prompt will
be printed before the filename is read in. IfsGetFN normally delimits filenames with any
control character or whitespace character and strips off any leading whitespace characters
supplied in the name. Any character (including whitespace characters) may be put in a
filename by prefixing it with a backslash n. This applies to leading whitespace characters
as well as whitespace characters in the middle or end of the name.
48
1.4.29
CHAPTER 1. THE IFS SYSTEM
ifsGetImg
ifsGetImg: open a file and read an IFS image from it
Usage:
img = ifsGetImg(FileName, Prompt, ReadTail);
IFSHDR *img;
char *FileName;
char *Prompt;
int ReadTail;
IfsGetImg reads an IFS image from some file FileName. If ReadTail is false (zero), then any
tail information associated with the image will not be read in. It returns a pointer to the
new image header, or NULL if it failed, in which case the external integer variables ifserr
and column can be examined to determine the nature of the error. Space for the header,
data, and tail is allocated dynamically, each may be freed (using cfree or ifsfree) when the
user is through with it. If FileName is NULL, then the input image is read from stdin.
If FileName is a null string (that is, FileName = ), then a filename will be read in from
stdin using the routine ifsGetFN. In this case, if Prompt isnt NULL and stdin corresponds
to a terminal, then the string Prompt will be printed on the terminal (actually, to stderr)
before reading a name. If stdin is not attached to a terminal, such as when input is being
piped in from another program, then the printing of the prompt string is suppressed. If a
filename is read in from stdin, and it is (a single dash), then the image itself will be read
from stdin. Filenames are expanded using ifsPrsFN, so they may contain such things as
environment variable names and login id constructs.
IfsGetImg works by opening the specified file and then calling ifsRdImg to do the actual
work of getting the image. It then closes the file when its done (unless it read from stdin).
Note that calling ifsGetImg with Filename = NULL is essentially the same as calling
ifsRdImg directly. The complimentary routine to ifsGetImg is ifsPutImg.
1.4. IFS FUNCTION LISTING
1.4.30
49
ifsigp
ifsigp: get pixel from a 2-D image
Usage:
value = ifsigp(img,row,col);
int value;
int row,col;
IFSHDR *img;
Ifsigp is used to get the value of some pixel in a 2-dimensional image. The value returned is
of type int, regardless of what the data format of the image is. Ifsigp performs all necessary
type conversions. If the value of the pixel in the image will not fit into an int data type,
then the value that is returned will be meaningless. If the image data format is one of the
complex forms, then ifsigp returns the real part of the specified data point. If some sort
of error occurs, then ifsigp will return zero, and the external variable ifserr will be set to
indicate the nature of the error.
The arguments to ifsigp are:
• img A pointer to the image header structure. This should refer to a 2-dimensional
image. If the image has 3 or more dimensions, then ifsigp will access the first frame
of the data (ie, all indices besides the first two will simply be treated as zero).
• row,col The coordinates of the point to be examined. Note that row, col may also be
regarded as a y, x pair. Beware that row corresponds to the y index, not the x index
. The following error codes (defined in the #include file <ifserr.h >) may be returned by
ifsigp :
• IFSE BAD HEADER: The pointer img does not point to an actual IFS image.
• IFSE BAD DTYPE: The image is of some data type that ifsigp does not recognize.
Usually this indicates that your header has been damaged, and the field img ! ifsdt
is mangled, or the image data type is struct. It could also occur if someone added a
new data type to that understood by IFS, and forgot to modify ifsigp accordingly.
BUGS (features): Ifsigp does not verify that the image passed to it corresponds to a
2-dimensional image.
The indices row, col may (depends on severity level setting) not checked to verify that
they lie inside the image dimensions. Ifsigp does not check to make sure that the data
pointer img-/textgreaterifsptr is not NULL. Previous versions of IFS did not allow this
data pointer to be NULL, so it was not previously necessary to check for this.
Results when numeric overflow occur (as is possible when converting a floating point
number into an integer) are undefined.
50
CHAPTER 1. THE IFS SYSTEM
Any of the above issues could cause an abrupt and unpleasant termination of your
program, generally with the infamous “bus error: core dumped” message under UNIX
systems. Of course, such a crash would be indicative of some prior error in the users
program not having been caught.
1.4. IFS FUNCTION LISTING
1.4.31
51
ifsipp
ifsipp: put pixel value into a 2-D image
status = ifsipp(img,row,col,value);
int status;
int value;
int row,col;
IFSHDR *img;
Ifsipp is used to set the value of some pixel in a 2-dimensional image. The argument value
is automatically converted from an integer into whatever data format the image is in. If
the image is of type complex, then ifsipp sets the real part of the datum to value, and the
imaginary portion to zero.
Ifsipp returns the value IFS SUCCESS if it succeeded, otherwise it returns the value
IFS FAILURE and sets the external variable ifserr to the appropriate error code.
The arguments to ifsipp are:
• img A pointer to the image header structure. This should refer to a 2-dimensional
image. If the image has 3 or more dimensions, then ifsipp will access the first frame
of the data (ie, all indices besides the first two will simply be treated as zero). row,col
The coordinates of the point to be examined. Note that row, col may also be regarded
as a y, x pair. Beware that row corresponds to the y index, not the x index.
• value The actual data value to be put into the image. Note that if the datum
represents some value that can not be represented in the data format of the image
itself (such as trying to place the value 500 into a ubyte image), a meaningless value
will end up being put into the image.
The following error codes (defined in the #include file ifserr.h ) may be set by ifsipp (in
the variable ifserr):
• IFSE BAD HEADER: The pointer img does not point to an actual IFS image.
• IFSE BAD DTYPE: The image is of some data type that ifsipp does not recognize.
Usually this indicates that your header has been damaged, and the field img->ifsdt is
mangled, or that the image data type is “struct”. It could also occur if someone added
a new data type to that understood by IFS, and forgot to modify ifsipp accordingly.
BUGS (features):
• Ifsipp does not verify that the image passed to it corresponds to a 2-dimensional
image.
• The indices row, col are not checked to verify that they lie inside the image dimensions.
52
CHAPTER 1. THE IFS SYSTEM
• Ifsipp does not check to make sure that the data pointer img-/textgreaterifsptr is not
NULL. Previous versions of IFS did not allow this data pointer to be NULL, so it
was not previously necessary to check for this. Any of the above issues could cause
an abrupt and unpleasant termination of your program, generally with the infamous
“bus error: core dumped” message under UNIX systems. These problems will not
occur however, unless the users program contains some other sort of error.
1.4. IFS FUNCTION LISTING
1.4.32
53
ifsmkh
ifsmkh: Create a two-dimensional IFS image THIS FUNCTION IS OBSOLETE STARTING WITH RELEASE 3.0 OF IFS THE FUNCTION ifscreate SHOULD BE USED INSTEAD
54
1.4.33
CHAPTER 1. THE IFS SYSTEM
ifsopen
ifsopen: open a file for reading or writing.
Usage:
File = ifsOpen(FileName,Mode,Prompt,NumRetries);
FILE *File; char *FileName;
char *Mode;
char *Prompt;
int NumRetries;
Ifsopen opens up a file FileName for reading or writing, and returns a pointer to the open
file descriptor (stream in Unix terminology).
Ifsopen is used by ifspin, and the usual user does not (normally) need it.
If the file can not be opened or some other error occurs, then ifsopen will return NULL.
The argument Mode is the same as the mode argument to the standard i/o library function
fopen, i.e. r or w for read or write access, (on Windows - based compilers, one sometimes
must use “rb” and “wb”. If FileName is NULL, then ifsopen just returns stdin or stdout
as is appropriate for the specified Mode.
If FileName is a null string (FileName = “”), then ifsopen will read the name of the
file to be opened from stdin. If stdin is attached to a terminal, then the string Prompt
will be printed before getting the filename (unless Prompt is NULL). FileName is read
using the function ifsGetFN, and expanded using ifsPrsFN, so it may contain the names
of environment variables or constructs of the form login id to represent some users home
directory name. If the name read in is a single dash, then ifsopen will return stdin or
stdout, according to the argument Mode.
If a filename is being read interactively (when FileName = “”, stdin is connected to a
terminal, and Prompt is not NULL), then the user is allowed NumRetries mistakes before
ifsopen will give up and return NULL. For instance, if ifsopen tries to open a non-existent
file for reading, it will print a message to the user and ask for a new name. After several
failures it will give up. This is to prevent such things as runaway shell scripts from sitting
in a perpetual error loop.
1.4. IFS FUNCTION LISTING
1.4.34
55
ifspin
ifspin: read in an image from disk
img = ifspin(filename);
IFSHDR *img;
char *filename;
Ifspin is used to read an IFS image from the specified file filename. All necessary storage
space for the image and its data is automatically allocated. The “tail” information for the
file is not read in. If the user wants the tail information read in, he should use the newer
function ifsGetImg. If filename points to a null string, then ifspin will prompt the user to
specify some filename. Any filename (whether or not read interactively) will be translated
using the function ifsPrsFN, which will substitute for environment variables and names of
users home directories specified in the C- shell shorthand form of user/filename. If filename
is NULL, then input will be read from stdin. Also, if a user is prompted for a filename,
if she specifies a single dash, the input will be read from stdin. The printing of a prompt
string will be suppressed if stdin is not attached to a terminal. Ifspin returns a pointer
to the new image, or NULL if some sort of error occurs. In the latter case, the external
variable ifserr will be set to indicate the nature of the error. Possibilities are:
• IFSE NO OPEN if the specified file cant be opened (usually meaning that it doesnt
exist.
• IFSE IO ERR if some sort of I/O error occurred (usually meaning the file does not
contain a valid IFS image). The standard system I/O library variable errno may
contain additional information about the nature of the error. Note that IFSE NO
OPEN is a subclass of the IFSE IO ERR error, so one can check for both automatically
by using a construct of the form “if (ifserr & IFSE IO ERR) action to take();”
• FSE NO MEM if it isnt possible to allocate storage to put the image into. IFSE
BAD NAME if some error occurred when translating the file name.
BUGS/NOTES:
Ifspin is an obsolete function. Under version 4 of IFS, this just remaps its arguments
and calls ifsGetImg. Even though it is obsolete, it is easier to use than ifsGetImg, many
programs use it all the time.
56
CHAPTER 1. THE IFS SYSTEM
1.4.35
ifspot
ifspot: write an image to disk Usage:
status = ifspot(img,filename);
int status;
IFSHDR *img;
char *filename;
Ifspot is used to write an IFS image to the specified file filename. If filename points to a
null string, then ifspot will prompt the user to specify some filename, and read a filename
from stdin. If filename is NULL, then ifspot will write the image to stdout. Also, if ifspot
reads a filename from stdin, and the filename is -, then ifspot will write to stdout. If stdin
is not connected to a terminal (e.g, input is being piped in from another program), then
the printing of a prompt will be suppressed.
The filename is translated using ifsPrsFN, so it may contain environment variables
(beginning with a leading “$”) and the names of users home directories specified in the
C-shell shorthand form of “user/ filename”.
Ifspot returns the value IFS SUCCESS if it succeeded, or IFS FAILURE if some sort
of error occurred. In the latter case, the external variable ifserr will be set to indicate the
nature of the error. Possibilities are:
• IFSE BAD HEADER if img doesnt point to a valid image.
• IFSE NOT IMAGE if there is no data associated with the header, i.e., the field
img->ifsptr is set to NULL.
• IFSE NO OPEN if the specified file cant be opened (usually meaning that the name
is invalid or that the user doesnt have write permission in the directory in which she
is trying to put the image.
• IFSE IO ERR if some sort of I/O error occurred. The standard system I/O library
variable errno may contain additional information about the nature of the error. Note
that IFSE NO OPEN is a subclass of the IFSE IO ERR error, so one can check for
both automatically by using a construct of the form if (ifserr & IFSE IO ERR) action
to take();
• IFSE BAD NAME if some error occurred while translating the name.
BUGS/NOTES:
• The function of ifspot has been superceded by the newer function ifsPutImg. Starting
with version 4 of IFS, ifspot is just a dummy routine which remaps its arguments
and calls if- sPutImg. Ifspot, however is convenient and supported
• Ifspot does not write out any tail information associated with the image.
1.4. IFS FUNCTION LISTING
1.4.36
57
ifsPrsFN
ifsPrsFN: expand a filename
NewName = ifsPrsFN(Name,rc);
char *NewName; char *Name;
int *rc;
This function is very useful for programmers writing systems like ifs. The ifs user is also
welcome to use it.
IfsPrsFN scans a string Name looking for references to environment variables or abbreviations for a users home directory of the form user such as is provided by the Unix
C-shell. It returns a pointer to the expanded name, or NULL if it failed. The space for
the expanded name is allocated using calloc, so it may be cfreeed when the user is through
with it. A status code is returned through the pointer rc. This code will be 0 if it was
successful, 1 if the expansion failed (such as by reference to an unset environment variable),
or 2 if the routine had an internal error (such as a failure in a call to calloc).
Environment variables are specified by prefixing the name with a dollar sign $. The name
of the environment variable may contain any alphanumeric character, and is terminated
by the first non-alphanumeric character found. The name may be enclosed in braces to
isolate it from other characters, such as when the user desires the first character after
the environment variable name to be an alphanumeric. Also, if the name is enclosed in
braces, almost any printable character can be part of the variable name rather than just
alphanumerics. Environment variable substitution is done on a strict left to right basis. A
reference to some users home directory may be specified in the same manner as that allowed
by the Unix C-shell. If the first character in a filename begins with a tilde character, then
the word immediately following the tilde (where word is terminated by the first character
which is not alphanumeric or underscore) is taken to be the name of some users login id;
the name of the users home directory is substituted for the login id construct. Examples
Assume the following environment variables and login ids:
$i ifs $file output $J john /usr/users/myhome john /usr/users/alpha Then the following
names expand as:
NAME myfile$i myfile.$i /myfile john/$file.$i $J/$file.$i $ibase $ibase EXPANSION
myfileifs myfile.ifs /usr/users/myhome/myfile /usr/users/alpha/output.ifs /usr/users/alpha/output.ifs no expansion unless environment variable ibase set ifsbase (braces isolate i
from base)
58
1.4.37
CHAPTER 1. THE IFS SYSTEM
ifsPutImg
ifsPutImg: open a file and write an IFS image to it
Usage:
rc = ifsPutImg(Image, FileName, Prompt, WriteTail);
int rc;
IFSHDR *Image;
char *FileName;
char *Prompt;
int WriteTail;
IfsPutImg writes an IFS image to some file FileName. If WriteTail is false (zero), then any
tail information associated with the image will not be written to the new file. IfsPutImg
returns IFS SUCCESS if all went well, or IFS FAILURE if something went wrong, in
which case the external integer variables ifserr and column can be examined to determine
the nature of the error. If FileName is NULL, then the image is written to stdout. If
FileName is a null string (that is, FileName = “”), then a filename will be read in from
stdin using the routine ifsGetFN. In this case, if Prompt isnt NULL and stdin corresponds
to a terminal, then the string Prompt will be printed on the terminal (actually, to stderr)
before reading a name. If stdin is not attached to a terminal, such as when input is being
piped in from another program, then the printing of the prompt string is suppressed. If a
filename is read in from stdin, and it is a single dash, then the image itself will be written
to stdout. Filenames are expanded using ifsPrsFN, so they may contain such things as
environment variable names and login id constructs. IfsPutImg works by opening the
specified file and then calling ifsWrImg to do the actual work of storing the image. It then
closes the file when its done (unless it wrote to stdout). Note that calling ifsPutImg with
Filename = NULL is essentially the same as calling ifsWrImg directly.
The complimentary routine to ifsPutImg is ifsGetImg.
1.4. IFS FUNCTION LISTING
1.4.38
59
ifsRdHdr
ifsRdHdr: read an IFS image header from an open file
Usage:
hdr = ifsRdHdr(file);
IFSHDR *hdr;
FILE *file;
IfsRdHdr reads an image header from a previously opened file. It does not read in any
data or tail information for the file. It returns a pointer to the new image header, or NULL
if it failed, in which case the external integer variables ifserr and column can be examined
to determine the nature of the error. Space for the header is allocated dynamically, and
may be freed (using cfree) when the user through with it.
After the header is read, the file pointer is positioned so that the next character read
from the file will the first byte of the data stored in the file. Hence, ifsRdHdr does scan
past any padding at the end of the header.
There is no complimentary routine for writing headers to open files in this version of
IFS. Writing a header to a file without writing any data would not make sense Accordingly,
there is a function ifsWrImg, but not an ifsWrHdr.
60
1.4.39
CHAPTER 1. THE IFS SYSTEM
ifsRdImg
ifsRdImg: read an IFS image from an open file
img = ifsRdImg(File,ReadTail); I
FSHDR *img;
FILE *File;
int ReadTail;
IfsRdImg reads an image from a previously opened file. If ReadTail is false (zero), then
any tail information associated with the image will not be read in. It returns a pointer to
the new image header, or NULL if it failed, in which case the external integer variables
ifserr and column can be examined to determine the nature of the error. Space for the
header, data, and tail is allocated dynamically, each may be freed (using cfree or ifsfree)
when the user is through with it.
IfsRdImg will always read the entirety of an image file (including tail informa- tion
and any padding after it), discarding the tail if it is not wanted, and the file read position
will be set so that the next read request will start with the first byte after the end of
the image. If File corresponds to a disk file, this just means the read pointer will point
to the end-of- file (unless some garbage has been concate- nated to to the of the image
file). If File does not correspond to a disk file, such as when piping is being used and File
is stdin, this means the file read pointer is positioned so that subsequent read requests
(including read, scanf, getchar, another call to ifsRdImg, etc.) will properly read new data
rather than reading padding characters left over from the end of the first image file. The
complementary routine to ifsRdImg is ifsWrImg.
1.4. IFS FUNCTION LISTING
1.4.40
61
ifssiz
ifssiz: Get size (lengths of all dimensions) of an IFS image
Usage:
dlength = ifssiz(image);
int *dlength;
IFSHDR *image;
Ifssiz is used to determine the lengths of each dimension of an IFS image. It returns a
pointer to an integer array, the various elements of which indicate the lengths of each
dimension of the image, and also how many dimensions the array defined as. The array
will have N+1 elements, where N is the number of dimensions of the image. The first
element of the array (element number zero) gives the number of dimensions for the image.
Subsequent elements of the array give the length each dimension, where the dimensions are
in order of ascending rank; i.e., element one gives the number of pixels per line (number of
columns) for the image, element two gives the number of lines (rows), element three is the
number of frames, and so forth.
The space for the array returned by ifssiz is automatically allocated using standard system calls (e.g., calloc), and as such may be released back to the system with the appropriate
calls (free, cfree) when the user is through with the array.
CAUTION – Potential Memory Leak: a popular programming error is to use ifssiz
inside a loop without a free, and then wonder why the program is growing. For this reason,
most programmers prefer ifsdimen to perform the same function.
If there is some error in ifssiz, then the external variable ifserr will be set to some error
code as defined in the file ifserr.h ( most likely IFSE BAD HEADER or IFSE NO MEM.)
Example usage:
int nrows, ncols, ndims, * dimlength;
IFSHDR * image2d; ...
make or read in image pointed to by image2d ...
dimlength = ifssiz(image2d);
ndims = dimlength[0];
if (ndims != 2) { /* Exit with nasty error messages ... */ }
ncols = dimlength[1];
nrows = dimlength[2];
cfree( (char *) dimlength );
62
1.4.41
CHAPTER 1. THE IFS SYSTEM
ifsslice
ifsslice: take a complete slice of a two-d or three-d image Usage:
newimg = ifsslice(oldimg, string, value);
where string is a char pointer pointing to a string. The following are legitimate strings
“frame”, “f”, “row”, “r”, “column”, “col”, “c”.
Passing any one of these strings will inform the function that the slice should be taken
with that particular dimension (row,col or frame) held constant at the integer parameter
value. i.e, if the string is frame and the value = 10, then a 2-d slice of the 3-d image at
frame=10 is returned. Similarly for row and col slices. This is a generic slice program
for 2-d and 3-d images. Using ifsslice on 1-d images will return with a copy of the image
pointer and a warning. Similarly, a text string of frame on a 2-d image returns a copy of
the image pointer and a warning.
Returns:
This function returns NULL if an error occurs, and returns an error code through the
external variable ifserr. External variables: ifserr, IFSSLV Special routines used: ifscfree,
ifsdie, ifswarn, ifsexwin, ifsexwin3d, ifssiz Ifsslice extracts a complete slice of a two-d or
three-d image from the constituent image. The datatype of the sliced new image is exactly
that of the old image. Note that the slice is complete in all dimensions except in one
dimension.
1.4. IFS FUNCTION LISTING
1.4.42
63
ifsversion
ifsversion: display version numbers Usage
ifsversion(file);
FILE *file;
Ifsversion will write the version numbers of all the IFSfunctions it knows about to the
specified file. Typically, file will be stdout or stderr. For each function ifsversion knows
about, it will print the name of the function, its version number, and the date it was last
modified. In rare cases there may be some additional information printed.
64
1.4.43
CHAPTER 1. THE IFS SYSTEM
ifsWrImg
ifsWrImg: write an IFS image to an open file
rc = ifsWrImg(Image,File,WriteTail);
int rc;
IFSHDR *Image;
FILE *File;
int WriteTail;
IfsWrImg writes an IFS image to some opened file File. If WriteTail is false (zero), then any
tail information associated with the image will not be written to the new file. IfsWrImg
returns IFS SUCCESS if all went well, or IFS FAILURE if something went wrong, in
which case the external integer variables ifserr and column can be examined to determine
the nature of the error. The complimentary routine to ifsWrImg is ifsRdImg.
1.5
IFS Error Codes
This section describes the various error flags which may be set (in the global variable ifserr)
when an error occurs in an IFS routine. These are defined in the #include file ifserr.h Each
error is represented by a bit or set of bits in ifserr; hence it is best to test for specific bits
rather than using a standard comparison (==). Note that all of the IFS error codes have
names which are of the form IFSE xxxxxx, where xxxxxx is the actual name for the error.
IFSE ERROR This is a combination of all possible errors. It is to be -1, i.e., all bits
of the variable ifserr are set. Hence, all other error codes are subclasses of this code. IFS
routines do not generally return this code. It generally indicates that either (a) an error was
too complex for IFS to figure out, or (b) it was such a rare error that it was not considered
important enough to define a separate code for the error. IFSE BAD HEADER or IFSE
BAD HDR The pointer you passed to a function does not correspond to a valid header for
an IFS image. Most IFS routines double-check image headers before doing anything, and
will exit with IFSE BAD HEADER set if the header is not valid.
IFSE NULL HEADER or IFSE NULL HDR The value NULL was passed to some IFS
routine where you should have passed a pointer to an image header. The most likely cause
of this is calling a routine to get or put a pixel in an image, when you havent yet created
(or read in) the image. This error is a subclass of the error IFSE BAD HEADER. IFSE
NO OPEN A file could not be opened for I/O activities. Usually this indicates that the file
does not exist (on reads), or that the user does not have access permission for the specified
file or directory. IFSE NO OPEN is a subclass of the error IFSE IO ERR.
IFSE NOT IMAGE An error occurred when attempting to read an image header from
a file. This usually means the file is too small to possibly be an IFS image. An image
header alone occupies at least 1 block, where a block is normally to be 512 bytes. IFSE
NOT IMAGE is 55 a subclass of the error IFSE IO ERR. IFSE BAD NAME A filename
1.6. IFS DATA TYPES
65
is considered invalid. This is normally set within routines such as ifsPrsFN when a name
expansion fails (such as by reference to a file fred/ file.ifs when user fred doesnt exit). IFSE
BAD NAME is a subclass of the error IFSE IO ERR.
IFSE IO ERR Some sort of error occurred while performing I/O. The system global
variable errno may contain additional information about the error. Common causes are
(a) encountering an unexpected EOF, (b) inability to write output due to a full disk or
users disk quotas exceeded, (c) inability to open a file.
IFSE BAD DTYPE The datatype (short, int, float, etc.) is invalid or unrecognized by
a particular routine. Usually this will only occur if you pass an invalid argument to an
image creation routine (e.g., ifsmkh or ifscreate). It might also occur on routines which
read or write data in images if the image header has been corrupted, or if the function is
not capable of working on an image of a particular data type (for instance, it would make
little sense to pass a complex format image to a histogram routine). IFSE BAD POS Some
coordinate (array index) is illegal for the specified operation, such as trying to access a
pixel in column 30 of an image which is only 20 columns wide. Note that the routines
which read or write single pixels currently do NOT check to see if coordinates are within
bounds. This is a flaw with IFS which will probably be fixed at a later time.
IFSE WRONG NDIM The routine called does not work with images of the dimensionality of the image being used. An example would be trying to extract a window (2D
subimage) from a 1-dimensional array.
IFSE NOT SUPPORTED The specified function is not currently allowed. Usually this
indicates a function which is not yet implemented, but which is intended to be implemented.
In rare cases it may indicate that a function is obsolete (a separate error code may later
be for this).
1.6
IFS Data Types
This section describes the various data types that IFS version 5 understands. IFS has
a certain basic set of names it recognizes for data types, and which it actually puts into
image headers; in addition, it recognizes a number of synonyms for data types which
it automatically remaps into the real data type. Some of these synonyms are machine
dependent, for instance, a type of int may map to 16bit on one machine and 32bit on another
machine. The final authority on data types and synonyms is the header file ifstypes.h which
contains a table relating synonyms to the proper data type. Note that the data types ARE
case sensitive. The possible data types are:
• 8bit Signed byte. Synonyms are byte, char, i1, and I1.
• u8bit Unsigned byte. Synonyms are ubyte, uchar, u1, and U1.
• 16bit Signed 16 bit integer. Synonyms are short, i2, and I2.
66
CHAPTER 1. THE IFS SYSTEM
• u16bit Unsigned 16 bit integer. Synonyms are ushort, u2, and U2.
• 32bit Signed 32 bit integer. Synonyms are int, long, i4, and I4.
• u32bit Unsigned 32 bit integer. Synonyms are uint, ulong, u4, and U4 (this data
type is not supported by many compilers)
• 32flt 32 bit floating point number. Synonyms are float, real, real*4, r4, and R4.
• 64flt 64 bit floating point number. Synonyms are double, real*8, r8, and R8.
• 32cmp Complex number consisting of two 32flt numbers (real and imaginary parts).
Synonyms are complex, complex*4, c4, and C4.
• 64cmp Complex number consisting of two 64flt numbers (real and imaginary parts).
Synonyms are complex*8, c8, and C8.
• struct Arbitrary user defined structure. Although IFS will read and write such images, it supplies no intrinsic routines to manipulate such images.
1.7
The structure of an IFS image
An IFS image, whether it is in a disk file or in program memory, is stored as a set of three
distinct pieces. When written to disk, each piece will begin on a block boundary, where
the size of a block is given by the constant BLOCKSIZE, which is de ned the #include file
ifs.h. Hence, there may be garbage bytes between one section and the next.
The first piece is a header for the image. This header contains all sorts of information
relevant to the processing of the image, along with information intended solely for the users
benefit. Sample items in the header include the number of dimensions the image has, how
long each dimension is, who the creator of the image is, and so on.
The second entity in an image is the actual image data. The data is just stored in one
long linear array, in exactly the same way that any C program stores arrays. The user can
directly access this data if he/she so desires, although the usual way to get at the data is
to use various IFS routines such as ifsigp and ifsipp.
The third part of the image is the tail. The tail is just a block of data at the end of the
file which IFS places no particular interpretation upon. It is up to the users programs to
manipulate and understand the contents of the tail. An sample usage for the tail might be
to store the text of a spoken message for which the data block was the digitized message.
In most cases, it is not necessary for the user to directly alter any of the information in the
image header as the IFS routines themselves will fill in the header with all the information
needed to process the image, and all of the user information fields will be set to default
values which are fine for most applications. However, at times it is desirable to alter fields
in the header, which requires that the user know what the fields in the header are, and how
1.7. THE STRUCTURE OF AN IFS IMAGE
67
they are used. The header actually consists of several C structures. These structures are
defined in the #include file ifs.h. The header actually consists of two types of structures.
The first structure is the main image header structure, and contains most of the relevant
information about the image, such as the number of dimensions, the format of the data,
etc. This structure is the so called IFSHDR structure which one refers to when one declares
an image pointer variable in a program (e.g: IFSHDR * img1, * img2;).
Along with the IFSHDR structure exists a variable number of dimension sub- headers.
There is one of these sub-headers for each dimension of the image, e.g., a 2-d image would
have two sub- headers. The main piece of information in these subheaders is how long
each dimension is. This structure goes by the name IFSDIM. The IFSDIM structures
come directly after the the main header structure, both in the in-core images and the disk
images. Hence, given a pointer to the main header structure, and the sizes of the headers,
one can easily generate pointers to any of the dimension headers. The macro ifsgetdim
(defined in ifs.h) may be used for this:
IFSDIM * dim; IFSHDR * img; dim = ifsgetdim(img,2);
will return a pointer to the third dimension sub-header (the first sub-header has number
of zero).
1.7.1
The image header fields
• char ifsmgc[4] This is the magic number field in the header. This field is used by the
various routines as a way of verifying the validity of the header passed to them. If
this field does not contain a special magic number (really, a character string rather
than a number), then the IFS routines will assume that an invalid pointer was sent
to them. The user should never alter this field.
• int ifsbb This is the number of bytes in a physical block, when images are stored on
disk. This value is set to the constant BLOCKSIZE, which is defined in ifs.h. For
all systems to date, the blocksize is 512. When images are written to disk files, the
header always starts at block 0, and the data always begins at the start of the next
block after the header, i.e, there may be a small amount of wasted space between the
end of the header and the start of the data, if the header does not completely ll the
last block it occupies.
• int ifssoh This is the block number of the first block of the header. This is always
set to zero, at least for the time being. int ifssod This is the number of the block at
which the data starts. The user can position directly to the start of the data array
by using fseek to position an I/O pointer to the ifssod*ifsbb byte of the le. Of course,
this only works for disk files.
68
CHAPTER 1. THE IFS SYSTEM
• int ifssot This is the block number of the start of the tail for the le. If this field
is negative, it indicates that there is no tail present; taking the absolute value of it
would give the block number at which the tail would be if it existed. char * ifstail
This is a pointer to the image tail, for an in-core image. If there is no tail, this is set
to NULL.
• int ifstsz This gives the size of the tail in bytes. If there is no tail, this is just zero.
char ifsfc[8] This is the file class field. This is not used by UNIX installations of IFS,
and is intended for systems running operating systems other than UNIX.
• char ifsct[8] This is the file class type field. This also is not used and is for non-UNIX
systems.
• char ifsunm[32] This field is used to store the name of the owner of the file, as a
null terminated character string. Note that since one byte must be reserved for the
terminating null, that the effective username length is 31 characters. The user can
put anything here she wants. When a user creates a new image, this field is filled in
with his/her login id.
• char ifscdt[32] This is a character string giving the time and date at which the image
was created. This is automatically filled in when a user creates a new image, but the
user can change it if she so desires. As with the name field, there can be up to 31
characters, plus the terminating null character.
• char ifscpg[32] This is a character string giving the name of the program which created
the image. When a user first creates an image, this field is normally lled with the
name of the subroutine which actually created the image (e.g.: ifscreate).
• char ifsver[8] This is a character string giving the version of the program which created
the image. E.g., V 1.00 or Ver 1A or something in that vein. Certain routines such
as ifscreate will stuff their version number in here.
• char ifsrs1[40] This is just space reserved for future expansion.
• char ifsdts[16] This is a character string giving the units of data for the pixels in the
image, e.g., for an intensity image, this field might contain lumens. One must make
sure not to use names for units which exceed 15 characters. The default for this field
is just pixels.
• float ifsdsc This field gives a scaling factor for the data in the image. This can be used
along with the data offset (defined below) to convert values in the image array to
some other scale. This might be used for example, if an image is taken and digitized
using some measuring instrument, and later it is found that the instrument was off
center (a data offset) or suffered from some sort of compression (scaling) problem.
1.7. THE STRUCTURE OF AN IFS IMAGE
69
The default for this field is 1.0. float ifsdo This field gives an offset which should
be applied to the data in an image. I.e., the real value for a point in the image
array should be calculated as realvalue = storedvalueif sdsc + if sdof Note that the
routines which get values from the image array (such as ifsfgp) do NOT apply the
scaling factors. The default for this field is 0.0.
• char ifsdt[16] This is a character string which tells what number format the pixels in
the image are stored in, such as u8bit or 32flt.
• char comp This byte denotes the type of compression that is used. Right now, the
only values are the integers one and zero, where one means use compression and zero
means no compression. A program can use this by executing img-¿comp = 0: /*
suppress compression */ before the execution of the ifs write file command.
• int dtype This is a numeric encoding of the ifsdt field which has been added to the
header structure with version four of IFS. This has been added to increase the speed
at which certain routines work.
• int ifsbpd This is the number of bytes which are needed to store a single pixel value,
i.e., its the sizeof whatever data type is used for the image. Of course, this field can
be deduced from the ifsdt field.
• int ifsdims This gives the number of dimensions for the image. This refers to the
number of indices needed to get at values in the image array, i.e, the pixels themselves
dont count as a dimension. For instance, an image which has 10 rows and 20 columns
is a 2-d image. Some other nomenclatures might refer to this as a 3-d image, where
the third axis is the pixel measurement axis (range, brightness, or whatever).
• char * ifsptr This is a pointer which gives the address of the of the first data element
in the data array, for in-memory images. When fies are written to disk, the value
NULL is written for this field. This is normally automatically set to the correct value
when an image is read in, although the user can alter it to point to some other array.
• int * ifsdln This is a pointer to an array which is used when calculating the address of
any arbitrary point of the image. This array has ifsdims elements. The first element
is just set to 1, the next element is the number of columns in the image, the next
element is the number of rows times the number of columns, the fourth element is
numcols * numrows * numframes, and so on. If the user has an N dimensional image,
and the N-length vector V gives the coordinate of some point in the image (i.e., V
= [ col, row, frame, cube... ]), then the dot-product of V and ifsdln will give you an
offset which may be added to the starting address of the image to find the desired
element, assuming the starting address is an appropriately declared pointer. If the
starting address is declared as a char * (such as with the header field ifsptr) then the
70
CHAPTER 1. THE IFS SYSTEM
offset must be scaled by the data size (ifsbpd). This may sound confusing, but really
just represents the usual way that a set of indices are converted to absolute memory
addresses for an array, whether by IFS or the C language itself. Note: the array itself
is not written to disk when an image is stored. It is created when an image is read in
(such as by ifsRdImg, ifspin, etc.) using information in the dimension sub-headers.
• char * userptr This field is not used at present.
• char ifsrs3[4] More reserved space.
1.7.2
The dimension sub-header fields
For each dimension of the image, there will be a structure of the following form tacked on
after the end of the main header structure. The user can obtain a pointer to one of these
structures using the ifsgetdim macro, or can calculate their positions manually using the
size of the main header and subheaders. The dimension sub-header fields are:
• int ifslen The length (number of elements) of this dimension.
• int ifsrnk The rank of this dimension. The rank of the dimension defines the order in
which the dimensions are actually stored in memory. The dimension with the lowest
rank is the dimension which changes most rapidly. Hence, the dimension with rank
1 is equivalent to columns, the rank 2 dimension is rows, the rank 3 dimension is
frames, and so on. Note that images are stored in row-major order (as with all C
arrays), which is contrary to the way some languages store arrays Fortran for instance
stores in column- major form. Also note that the first dimension subheader after the
main header is not necessarily the header for the lowest rank (columns) although the
IFS routines do by convention store the dimension subheaders in order of ascending
rank, this is not a requirement.
• char ifsdir[8] The direction of this dimension. This is for images for which lines are
not always stored in a top to bottom, left to right form. For instance, some camera
systems scan from left to right on one line, then go from right to left on the next
line, and store the data in the same form. This would be known as forward-backward
alter storage. Other possibilities include forward (normal),backward, and backwardforward alter. Currently, IFS does NOT recognize this field, and treats all images
as being stored in forward format. This is only for possible future expansion. The
string fwd is placed in this field.
• char ifsxun[8] This is a character string which gives the units for this dimension e.g.,
inches or mils. Make sure not to use names exceeding 7 characters. The default for
this field is pixels.
1.7. THE STRUCTURE OF AN IFS IMAGE
71
• float ifsdsc The scaling factor to apply to this dimension, analogous to the scaling
factor which exists in the main header.
• float ifsdof The scaling offset for this dimension.
• char rs4[32] Reserved space.
72
CHAPTER 1. THE IFS SYSTEM
Chapter 2
The FLIP library
FLIP Floating Point Image Processing Library This library assumes input in the
form of a floating point ifs image. Outputs will be floating point images as well. The
library is designed to optimize computation speed, while providing the programmer with
easy-to-use tools. If all the inputs are not float, the function returns -1. If the
input dimensions are not compatible, the function returns -2. Note that no
error messages are printed, so the user must check the value returned.
NOTE: to build programs which use many of the flip functions, you will need the math
library. Thus, build using the -lm switch which invokes the math library.
You can call many of the FLIP functions from the command line. See section 2.6.
2.1
Example Program Using the FLIP functions
In this section, we suppose that the user must write a program which computes an expression using derivatives and transcendantal functions. That is, at every pixel, compute
r = exp(−
(fx )2 + (fy )2
)
2τ 2
(2.1)
where fx denotes the partial derivative with respect to x and τ is a constant.
#include <ifs.h>
#include <flip.h>
int main(int argc, char *argv[])
{
IFSIMG inimg,outimg,temp1,temp2;
int len[3];
inimg=ifspin(argv[1]); // read the file specified by the first argument
len = ifssiz(inimg)
; // get the sizes of the dimensions
outimg=ifscreate("float",len,IFS_CR_ALL,0);
73
74
CHAPTER 2. THE FLIP LIBRARY
temp1=ifscreate("float",len,IFS_CR_ALL,0);
temp2=ifscreate("float",len,IFS_CR_ALL,0);
temp3=ifscreate("float",len,IFS_CR_ALL,0);
fldx(inimg,temp1);
flmultv(temp1,temp1,temp1); // square the value
fldy(inimg,temp2);
flmultv(temp2,temp2,temp2); // square the value
fladdv(temp1,temp2,temp3); // add them
fldivs(temp3,temp3,-(2.0 * tau)); // divide
flexp(temp3,outimg);
ifspot(outimg,argv[2]);
free(ifssiz);
ifsfree(outimg,iFS_FR_ALL); // doesn’t need to be done since the program is exiting here
// but this is good practice
ifsfree(inimg,iFS_FR_ALL);
ifsfree(temp1,iFS_FR_ALL);
ifsfree(temp2,iFS_FR_ALL);
ifsfree(temp3,iFS_FR_ALL);
} // end of this program
In the example above, note the use of in-place operations. with multv, divs, and
exp. Calls with the same input and output and NOT allowed in derivative or other
neighborhood-based operations.
2.2
Matrix Operations
This section contains just a few commonly used matrix operations. These are developed
using the Numerical Recipies in C (Cambridge University Press) conventions and utility
functions. These functions are defined in flip.h.
It is recommended that users set up their vectors to start at 1, not zero, to be consistent
with math. For example, use v=vector(1,n);
2.2.1
dmatrix
Create a matrix of doubles
usage:
double **r;
r = dmatrix(1,6,1,8);
Will create a matrix of doubles, rows indexed from 1 to 6, columns indexed from 1 to 8.
2.2. MATRIX OPERATIONS
2.2.2
matrix
Create a matrix of floats
usage:
float **r;
r = matrix(1,6,1,8);
Will create a matrix of floats, rows indexed from 1 to 6, columns indexed from 1 to 8.
2.2.3
dvector
Create a vector of n doubles
usage:
double *r;
r = dvector(1,6);
Will create a vector of 6 doubles, lower index is 1, higher index is 6.
2.2.4
vector
Create a vector of n floats
usage:
float *r;
r = vector(1,6);
Will create a vector of 6 floats, lower index is 1, higher index is 6.
2.2.5
ivector
Create a vector of n integers
usage:
int *r;
r = ivector(1,6);
Will create a vector of 6 integers, lower index is 1, higher index is 6.
75
76
2.2.6
CHAPTER 2. THE FLIP LIBRARY
free ivector
Free a previously created vector of integers.
Usage:
free_ivector(v,1,6)
2.2.7
free dvector
Free a previously created vector of doubles.
Usage:
free_dvector(v,1,6)
2.2.8
free vector
Free a previously created vector of floats.
Usage:
free_vector(v,1,6)
2.2.9
transpose
Usage:
void transpose(double **v,int rows,int cols,double **vtrans);
The matrix v, which has rows rows and cols columns, will be transposed and stored in
matrix vtrans. The user must ensure that the size of vtrans is correct. This program
assumes the indexing starts with 1, as is the common convention.
2.2.10
ifsmatmult
Multiply two matrices
Usage:
int ifsmatmult(double **, double **, double **, int,int,int,int);
ifsmatmult(x, y, z, xrows,xcols,yrows,ycols);
For the two matrices to be compatible, xcols must equal yrows. The program will return
an error if this is not true. The resultant matrix, z, must be of size xrows x ycols. The
matrices are assumed to have been created with the matrix function defined above, with
a lower index of 1.
2.3. ARITHMETIC OPERATIONS ON IMAGES
2.2.11
77
ifsinverse
double ifsinverse(double **,double **, int);
Computes the inverse of a matrix, using numerical recipies conventions
Usage:
det = ifsinverse(double **x, double **xinv, int n);
x is an nxn matrix. After the call, xinv will contain the inverse of x. The function will
return the determinant.
2.2.12
jacobi
Computes eigenvalues and eigenvectors. call:
float **a,**v;
float *d;
int n;
a = matrix(1,n,1,n); // input float matrix a must be symmetric
v = matrix(1,n,1,n); // output matrix v will contain eigenvectors as columns
d = vector(1,d);
// output vector d will contain eigenvalues
...
jacobi(a,n,d,v,&nrot); // computes everything
// nrot will contain the number of rotations required
2.3
2.3.1
Arithmetic Operations on Images
flabsolute
Take absolute value of an image
int flabsolute(inimage,outimage}
2.3.2
fladds
Add a scalar to an image
int fladds(IFSIMG img1, IFSIMG img2, float scalar)
78
2.3.3
CHAPTER 2. THE FLIP LIBRARY
fladdv
Add two images
int fladdv(IFSIMG img1, IFSIMG img2, IFSIMG img3)
The first input image is img1, the second input image is img2, the output is img3.
Corresponding pixels of img1 and img2 are added and the result stored in img3.
2.3.4
flclip
Limit permitted brightness in images
int flclip(IFSIMG img1, IFSIMG img2,float scalar)
The first image, img1 is clipped so that its maximum value is scalar.
2.3.5
flcp
Copy an image
flcp(IFSIMG inimg, IFSIMG outimg)
The image inimg will be copied to the image outimg
2.3.6
fldivs
Divide an image by a scalar.
fldivs(IFSIMG img1 IFSIMG,img2,float scalar)
Each pixel of img1 will be divided by the scalar, and the result stored in the corresponding
pixel if img.
2.3.7
fldivv
Divide two images
int fldivv(IFSIMG img1, IFSIMG img2, IFSIMG img3);
Each pixel of img1 is divided by the corresponding pixel of img2, and the result stored in
img3. Note, no check for divide by zero is performed, so the special floating point value
INFINITY can occur.
2.3. ARITHMETIC OPERATIONS ON IMAGES
2.3.8
79
flexp
Exponentiate
int flexp(IFSIMG img1, IFSIMG img2)
Each pixel of img2 is independently exponentiated. Result stored in img2.
2.3.9
flln
Compute logs of pixels independently
int flln(IFSIMG img1, IFSIMG img2)
Computes out[i] = log(in[i]);
2.3.10
flmults
Scalar multiply
int flmults(IFSIMG img1, IFSIMG img2,float scalar)
Multiply each pixel of img1 by scalar and store the result in the corresponding pixel of
img2.
2.3.11
flmultv
Vector multiply
int flmultv(IFSIMG img1, IFSIMG img2, IFSIMG img3)
Each pixel of img1 is multiplied by the corresponding pixel of img2, the result stored in
img3. This is equivalent to the MATLAB .* operation.
2.3.12
flneg
Negate image pixels
int flneg(IFSIMG img1, IFSIMG img2)
Each pixel of img1 is multiplied by -1 and the result stored in img2.
2.3.13
flnorm
int flnorm(IFSIMG img1,float *norm)
Returns the 2-norm of the image img1. The second argument is a POINTER to a float,
and the norm (square root of sum of squares of pixels) will be returned.
80
2.3.14
CHAPTER 2. THE FLIP LIBRARY
flrec
Reciprocal of an image
int flrec(IFSIMG img1, IFSIMG img2)
Each pixel of the input image, img1, is divided into one, and the result stored in the
corresponding pixel of img2. This function tests for divide by zero, reports an error, and
exits early.
2.3.15
flsq
Square pixel values
int flsq(IFSIMG img1, IFSIMG img2)
For every pixel, out[i] = in[i] * in[i] ;
2.3.16
flsqrt
Square root of pixels
int flsqrt (IFSIMG img1, IFSIMG img2)
The square root of each pixel it taken. If any pixels are negative, the function will return
FAILURE (0), else it will return SUCCESS (non-zero).
2.3.17
flsubs
Scalar subtract. Subtract a scalar from every element of an image
int flsubs(IFSIMG img1, IFSIMG img2,float scalar)
2.3.18
flsubv
int flsubv(IFSIMG img1, IFSIMG img2, IFSIMG img3);
Vector subtract Each pixel in the second image, img2 is subtracted from the corresponding
pixel in img1, and the result stored in img3. Valid for any number of dimensions.
2.3.19
flthresh
Threshold
int flthresh(IFSIMG img1, IFSIMG img2,float scalar,float bkgnd)
Each pixel of input image img1 is tested against scalar. If pixel > scalar, the pixel is
unchanged, otherwise, the corresponding pixel in the output image is set to the value
bkgnd. Valid for any number of dimensions.
2.4. IMAGE MANIPULATION FUNCTIONS
2.3.20
81
flthresh2
Threshold
int flthresh2(IFSIMG img1, IFSIMG img2,float scalar,float bkgnd,float fgnd)
Each pixel of input image img1 is tested against scalar. If pixel > scalar, the pixel is set
to fgnd, otherwise, the corresponding pixel in the output image is set to the value bkgnd.
Valid for any number of dimensions.
2.4
2.4.1
Image Manipulation Functions
flone border
int flone_border(IFSIMG img1, IFSIMG img2)
Sets the left-most and right-most columns of the image to one. Then set the top row
and bottom row to one. Result copied into img2.
2.4.2
flpad
Image pad int flpad(IFSIMG img1, IFSIMG img2)
Input image img1 is padded by taking the leftmost pixel on each row and replacing it by
the next- to-leftmost. Same thing on right side, top, and bottom. If 3D, appropriate things
are done to the first and last frame.
2.4.3
flplanar
Image pad using linear interpolation.
int flplanar(IFSIMG img1, IFSIMG img2)
The leftmost pixel on each line is replaced by what it would be if the first three pixels were
lin- early increasing in brightness – the zeroth pixel is the linear interpolation of the first
and second. Similar on right side, top, and bottom. Only implemented for 2D images.
2.4.4
flrotate
Rotate an ifs image about its center.
int flrotate(IFSIMG input,IFSIMG output,float angle);
82
CHAPTER 2. THE FLIP LIBRARY
Unlike most other flip functions, flrotate will accept input of any data type. It runs faster
with unsigned byte and float. It will also rotate 3D IFS images, but all frames will be
rotated by the same amount. (Thus a color image can be rotated). Returns: zero if it runs
successfully.
Returns: -2 if the input and output images have different dimensions.
2.4.5
flshx
Shift image in the x direction
int flshx(IFSIMG img1,int dx, IFSIMG img2)
input image img1 is shifted by dx pixels in the x direction and the result stored in img2.
Operation is valid for 3D images.
2.4.6
flshxy
Shift image
int flshxy( IFSIMG int img1,dx,int dy, IFSIMG img2)
Input image img1 is shifted dx pixels in x and dy pixels in y. Operation is valid for 3D
images.
2.4.7
flshy
Shift image
int flshy(IFSIMG img1,int dy, IFSIMG img2)
Shifts image in y direction. Operation is valid for 3D images.
2.4.8
flzero border
Set border pixels to zero.
int flzero_border(IFSIMG img1, IFSIMG img2)
Valid for two dimensional images.
2.5.
2.5
DERIVATIVE OPERATORS
83
Derivative Operators
In computing image derivatives, (with the exception of flDoG), DO NOT CALL THESE
FUNCTIONS IN-PLACE. That is, never do something like
fldx(img,img);
// bad bad bad
Performing an image derivative in-place will radically distort the output. Always use
different destination and source image. Because flDoG actually creates a temporary image,
it is OK to use it in-place.
Except for DoG (derivative of a Gaussian), all the derivative operators listed below
support 1-D (signals) 2-D (images) and 3-D (volumes) data sets. In all cases, x denotes
the column and y the row.
flDoG only supports two-dimensional images, however, if the problem is 2D, it probably
does a better job in the presence of noise.
2.5.1
flDoG
Computes the derivative of an isotropic, zero mean Gaussian, and applies it to an image.
This is by far the best derivative program in the flip library.
int flDoG(IFSIMG a, IFSIMG b, float sigma, int order, int direction);
The ifs image a will be differentiated and its derivative stored as image b. By choosing
combinations of the arguments, order and direction, one can compute the blurs and derivatives in the table below. Sigma is the standard deviation of the Gaussian.. The equation
of the Gaussian is
2
1
x + y2
exp −
2πσ
2σ 2
The kernel used will be computed by the program by extrapolating out to greater than
3 sigma. This could result in a large kernel and long run times. You may get a warning
message to this effect, but the program will run anyway. Because the kernels may get large,
the program checks that the image is at least large enough to hold the image. If not, the
program will exit with an error message.
The message “Something wrong with arguments to function ifsDoG” indicates that an
impossible combination of order and direction were specified.
84
CHAPTER 2. THE FLIP LIBRARY
Order
0
1
2
3
0
1
2
3
0
1
2
3
2.5.2
Direction
0
0
0
0
1
1
1
1
2
2
2
2
Function
Convolution with zeroth order derivative of a Gaussian, which is a blur
First deriv wrt x (column direction)
Second deriv wrt x (column direction)
Third deriv wrt x (column direction)
Blur, same as 0 0
First derivative wrt y (row direction)
Second derivative wrt y (row direction)
Third derivative wrt y (row direction)
Blur, same as 0 0
Undefined. Will produce an error message
Cross second deriv (Partial**2 f )/ (Partial x Partial y)
Undefined. Will produce an error message
flGabor
Performs a Gabor filtering on an image.
The Gabor filter, applied to a point xy in an image, computes
02
x + γ 2 y 02
x0
g(x, y; σ, θ, λ, γ, ψ) = exp −
cos
2π
+
ψ
2σ 2
λ
Here, the Gabor is implemented by using the ifs function flGabor The normal to the
line has the angle theta, not the line itself where
x0 = x cos θ + y sin θ
(2.2)
0
(2.3)
y = −x sin θ + y cos θ
The parameters involved in the construction of a 2D Gabor filter are:
σ , The standard deviation of the Gaussian function
θ , The orientation of the normal to the parallel stripes of the Gabor function
λ , The wavelength of the sinusoidal function
γ , The aspect ratio of the exponential.
ψ , The phase of the sine wave.
Note that flGabor gives the user the options of selecting ψ, the phase of the cosine, which
allows the user to determine whether to be sensitive to lines, rising edges, or falling edges.
A phase of zero means use a cosine centered at zero, which is best for finding lines (two
opposite edges), One may detect very narrow lines by using a ψ of zero and a narrow
2.5.
DERIVATIVE OPERATORS
85
wavelength. A ψ of −π/2 changes the cosine to a sine which makes it sensitive to finding
positive edges. A ψ of π/2 changes the cosine to a downward sine which makes it sensitive
to finding falling edges.
USAGE:
int flGabor(IFSIMG input,IFSIMG output,float sigma,float theta,
float lambda, float gamma,float psi);
The input and output images must both be float; They must be the same size.
sigma is the standard deviation of the blurring Gaussian of the Gabor filter.
theta is the orientation of the Gabor filter. It is an angle, measured in radians, relative to
the x axis. If theta =0 (for example), the filter will prefer vertical edges. Lambda is the
wavelength of the sinusoid. Good example settings for finding lines (not edges) are lambda
= 4, psi = 0;
2.5.3
fldx
Estimate partial deriviative in the x direction. Do not use in-place.
int fldx(img1,img2);
IFSIMG img1,img2;
Compute an approximation of the first deriviative with respect to x by the difference
between pixels in an image images. For each pixel, outrow[j][i] = (inrow[j][i+1] - inrow[j][i1])*.5
If all the inputs are not float, the function returns -1. If the input dimensions are not
compatible, the function returns -2. Note that no error messages are printed, so the user
must check the value returned.
2.5.4
fldx back
Backward difference. Do not use in-place.
The forward and backward differences both estimate the first partial derivative with respect
to x, but do it with higher resolution (and higher noise sensitivity) than fldx. They are
useful in iterative algorithms where you do one iteration using the forward difference, and
the next using the backward.
int fldx_back(IFSIMG img1, IFSIMG img2)
Compute the backward difference between pixels in an image images. For each pixel,
outrow[j][i] = inrow[j][i+1] - inrow[j][i]; is computed. Do not use in-place. If all the inputs
are not float, the function returns -1. If the input dimensions are not compatible, the
function returns -2. Note that no error messages are printed, so the user must check the
value returned.
86
2.5.5
CHAPTER 2. THE FLIP LIBRARY
fldx forw
Forward difference. Do not use in-place.
int fldx_forw(IFSIMG img1, IFSIMG img2)
Compute the forward difference between pixels in an image images. For each pixel, outrow[j][i] = inrow[j][i] - inrow[j][i-1]; Do not use in-place.
2.5.6
fldxx
Second partial derivative with respect to x.
int fldxx(IFSIMG img1, IFSIMG img2)
Uses a 3x1 kernel. Do not use in-place. If all the inputs are not float, the function returns
-1. If the input dimensions are not compatible, the function returns -2. Note that no error
messages are printed, so the user must check the value returned.
2.5.7
fldxy
Second partial derivative with respect to x and y.
int fldxy(IFSIMG img1, IFSIMG img2)
Uses a 3x3 neighborhood. Do not use in-place. If all the inputs are not float, the function
returns -1. If the input dimensions are not compatible, the function returns -2. Note that
no error messages are printed, so the user must check the value returned.
2.5.8
fldxz
Second partial wrt x,z. Do not use in-place.
int fldxz(IFSIMG img1, IFSIMG img2)
2.5.9
fldy
First partial derivative with respect to y. Do not use in-place.
int fldy(IFSIMG img1, IFSIMG img2)
If all the inputs are not float, the function returns -1. If the input dimensions are not
compatible, the function returns -2. Note that no error messages are printed, so the user
must check the value returned
2.5.
DERIVATIVE OPERATORS
2.5.10
87
fldy back
Backward difference The forward and backward differences both estimate the first partial
derivative with respect to y, but do it with higher resolution (and higher noise sensitivity)
than fldy. They are useful in iterative algorithms where you do one iteration using the
forward difference, and the next using the backward. Do not use in-place.
int fldy_back(IFSIMG img1, IFSIMG img2)
Compute the backward difference between pixels in an image images. For each pixel,
outrow[j][i] = (inrow[j+1][i] - inrow[j-1][i])*.5; is computed. Do not use in-place. If all the
inputs are not float, the function returns -1. If the input dimensions are not compatible,
the function returns -2. Note that no error messages are printed, so the user must check
the value returned.
2.5.11
fldy forw
Forward difference
int fldy_forw(img1,img2)
IFSIMG img1,img2;
Compute the forward difference between pixels in an image images. For each pixel, outrow[j][i] = inrow[j][i] - inrow[j-1][i]; Do not use in-place. If all the inputs are not float, the
function returns -1. If the input dimensions are not compatible, the function returns -2.
Note that no error messages are printed, so the user must check the value returned.
2.5.12
fldyy
Second partial derivative with respect to y. Do not use in-place. If all the inputs are not
float, the function returns -1. If the input dimensions are not compatible, the function
returns -2. Note that no error messages are printed, so the user must check the value
returned.
int fldyy(img1,img2);
IFSIMG img1,img2;
Uses a 3x1 kernel.
88
2.5.13
CHAPTER 2. THE FLIP LIBRARY
fldyz
Second partial derivative with respect to y and z. Do not use in-place.
int fldyz(img1,img2)
IFSIMG img1,img2;
Uses a 3x3 kernel. Obviously, only meaningful for 3D data. If all the inputs are not float,
the function returns -1. If the input dimensions are not compatible, the function returns
-2. Note that no error messages are printed, so the user must check the value returned,
2.5.14
fldz
First partial derivative with respect to z. Obviously, only meaningful for 3D data. Do not
use in-place.
int fldz(img1,img2)
IFSIMG img1,img2;
If all the inputs are not float, the function returns -1. If the input dimensions are not
compatible, the function returns -2. Note that no error messages are printed, so the user
must check the value returned.
2.5.15
fldzz
Second partial derivative with respect to z. Only meaningful for 3D data. Do not use
in-place. If all the inputs are not float, the function returns -1. If the input dimensions are
not compatible, the function returns -2. Note that no error messages are printed, so the
user must check the value returned.
int fldzz(img1,img2)
IFSIMG img1,img2;
Uses a 3x1 kernel.
2.6
Running the FLIP functions from the command line
Sometimes, users want to run a FLIP function on an image without bothering to write a
program to call that function. Some programs have been written which allows the user to
do just that. These are listed below
2.6. RUNNING THE FLIP FUNCTIONS FROM THE COMMAND LINE
2.6.1
89
flpg1: single input FLIP functions
This program allows to multiple flip library functions from the command line.
Switches:
-i inputfilename
-o outputfilename
-f functionname
clip - clips the image
divs - divides by a scalar
exp
- takes the exponential of each pixel of the image
log
- takes the natural log of each pixel of the image independently
mults - takes the exponential of each pixel of the image
neg
- Negate image pixels
rec
- Reciprocal of an image
sq
- Square pixel values
curv - Curvature at every point
sqrt - Square root of pixels
subs - Scalar subtract. Subtract a scalar from every element of an image
-s optional, function-specific parameter
Example:
flpg1 -i footprint.ifs -o footdarker.ifs -f subs -s 2.0
2.6.2
der1: take a derivative of an image
This program allows to multiple flip library functions from the command line.
Switches:
-i inputfilename
-o outputfilename
-f functionname
fldx
- Estimate partial derivative in the x direction
fldx_back - Backward difference
fldx_forw - Forward difference
fldxx
- Second partial derivative with respect to x
fldxy
- Second partial derivative with respect to x and y
fldxz
- Second partial derivative with respect to x and z
fldy
- Estimate partial derivative in the x direction
fldy_back - Backward difference
fldy_forw - Forward difference
fldyy
- Second partial derivative with respect to y
fldyz
- Second partial derivative with respect to y and z
90
CHAPTER 2. THE FLIP LIBRARY
fldz
fldzz
2.6.3
- Estimate partial derivative in the z direction
- Second partial derivative with respect to z
ifsDoG:Apply a derivative of Gaussian kernel to an ifs image
usage: ifsDoG [switches]
switchs are
-i infilenname, where infilename is an ifs image
default: the null string
-o outfilenname, where outfilename is an ifs image
default: the null string
-s sigma, std. dev of the filtering Gaussian
default: sqrt of 3.0
-O
order of the derivative
zero is blur with the Gaussian,
one is first deriv, etc, up to 3rd deriv
-d
direction. This flag is the letter c for col, r for row, b for both
default: col
b option only valid for second deriv
example: ifsDoG -i myfile.ifs -o outfile.ifs -O 0 -d r
2.7
2.7.1
Image Manipulation
ifsadd
ifsadd - add two ifs images, point by point out(i, j) = in1(i, j) + in2(i, j) Usage:
int ifsadd (in1, in2, out) IFSHDR *in1,*in2,*out;
RETURNS 0 if successful, -1 if all three arguments do not have same dimensions -2 if data
type unsupported (complex double) -3 if one input has type complex and output is real
-4 if both inputs are real and output is complex CAUTION: if output is type char, values
greater than 255 will be clipped to lie between 0 and 255. NOTES: if one image is real
and the other complex, the output must be complex and the real parts of the images will
be added.
2.7.2
ifsany2any
Convert any ifs image to any data type.
Usage:
2.7. IMAGE MANIPULATION
status=ifsany2any(inputimage,outputimage);
** FUNCTION: convert data type of images, point by point
** CALL: ifsany2any (in1,out)
**
where each argument is an ifs image
** RETURNS: 0 if successful,
**
-1 if both arguments do not have the same dimensions
**
-2 if input data type unsupported (complex)
**
-3 if one input has type complex and output is real
**
-4 if input is real and output is complex
**
-5 if a zero occurs in the input
91
92
CHAPTER 2. THE FLIP LIBRARY
Chapter 3
Image Processing Subroutines
In this chapter, a number of subroutines are presented which are of general applicability.
Most have been written using pointers and sophisticated code in order to optimize speed.
3.1
Geometric functions
The following subroutines are available in the library /usr/local/libiptools.a
3.1.1
chainHull 2D
Finds the convex hull of a set of 2D points. The set is an array of structures of type Point.
Where Point is defined by typedef struct float x, float y Point; Usage:
count = chainHull_2d(Point *S, int n, Point *H);
count is an integer, the number of points in the convex hull (cannot be more than n)
n in the number of points in the input data se// S is the array of input points// H will be
filled in by the subroutine, the points in the convex hull
This software was copied from freeware:
http://softsurfer.com/Archive/algorithm 0109/algorithm 0109.htm#chainHull 2D%28%29
Note: the x,y pairs must be sorted on x, smallest first. If two pairs have the same x coordinate, then those need to be sorted by y. You can use the Unix soft program if that is
convenient, or any of a large selection of sort subroutines.
3.1.2
compute curvature
Given a set of x,y pairs, compute the curvature at every point. Usage:
compute_curvature(struct point_xy parray[],int grid_spacing,
int num_elems, double curvature[]);
93
94
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
The structure points is simply an x,y, pair defined as follows:
struct point_xy {
int x,
int y
};
The user should declare an array of these structures. num elems is the number of elements
in this array. grid spacing is the pixel width; almost always set to 1. This would be
changed only if the pixels are not square. curvature[] is an array of curvatures found by
this program.
3.1.3
InsideTriangle
Determine if a point is inside a triangle
Usage:
int InsideTriangle(int row, int col, double **X);
X is an array of doubles created with
X=dmatrix(1, 2, 1,3);
The three columns of X refer to the coordinates of the 3 vertices of the triangle. The 1,1
entry in the matrix is the row coordinate of the first vertex, The 1,1 entry in the matrix is
the column coordinate of the first vertex
3.1.4
InterpolateTriangle
Given three points in an input image, and a corresponding 3 points in an output image,
the second triangle will be deformed and filled in to match the first. Usage:
status = InterpolateTriangle (inimg, outimg, X,U,IG);
IFSIMG inimg, outimg;
double **X, **G;
int IG
X and U are matrices created using the function dmatrix. IG is a switch which, if nonzero,
will result in sub-pixel interpolation. (At the time of this writing, this feature is not
implemented.) The matrix manipulation functions are in the flip library. See section 2.2.2.
If the input image is three-dimensional and has three frames, it will be treated as color.
Three dimensional images are interpolated only in a 2D sense.
Simple Example:
3.1. GEOMETRIC FUNCTIONS
95
double **X, **Y;
X=dmatrix(1,2,1,3); // X is a matrix with rows numbered
//from 1 to 2 and columns numbered from 1 to 3.
U=dmatrix(1,2,1,3);
X[1][1] =0; X[2][1] = 0; // one corner of undistorted image
U[1][1] =0; U[2][1] =0; // this point is not moved
X[1][2] =0; X[2][2] = 10; // second corner of triangle, ten units to right of previous
U[1][2] =0; U[2][2] =10; // this point is not distorted
X[1][3] =10; X[2][3] = 5; // third corner of triangle, ten units down
//and 5 units over from first
U[1][3] =15; U[2][3] =10; // this point is moved, stretching
// the triangle up and to the right
InterpolateTriange(inputimge, outputimage,X,U,0);
96
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
Real Example
#include <ifs.h>
#include <ifsmatrix.h>
int main(int argc, char *argv[])
{
IFSIMG inimg;
IFSIMG outimg;
int row,col,nr,nc;
int len[4];
double **X, **U;
X=dmatrix(1,2,1,3);
U=dmatrix(1,2,1,3);
inimg = ifspin(argv[1]);
len[2]=nr = ifsdimen(inimg,1);
len[1]=nc = ifsdimen(inimg,0);
len[0]=inimg->ifsdims; // two dimensional
if(len[0]== 3) len[3]=ifsdimen(inimg,2);
outimg = ifscreate(inimg->ifsdt,len,IFS_CR_ALL,0);
{
float ulr,ulc,urr,urc,llr,llc,lrr,lrc,mr,mc;
ulr =0;ulc =0;
urc=nc-1;urr=0;
llr=nr-1;llc =0;
lrr=nr-1;lrc=nc-1;
mr = nr/2; mc =0;
X[1][1] = ulr;X[2][1] =ulc;
X[1][2] = urr;X[2][2] =urc;
X[1][3] = mr;X[2][3] =mc;
U[1][1] = ulr;U[2][1] =ulc;
U[1][2] = urr;U[2][2] =urc;
U[1][3] = 90;U[2][3] =mc;
InterpolateTriangle(inimg,outimg,X,U,0);
X[1][1] = urr;X[2][1] =urc;
X[1][2] = mr;X[2][2] =mc;
X[1][3] = lrr;X[2][3] =lrc;
U[1][1] = urr;U[2][1] =urc;
U[1][2] = 90;U[2][2] =mc;
U[1][3] = lrr;U[2][3] =lrc;
3.1. GEOMETRIC FUNCTIONS
97
InterpolateTriangle(inimg,outimg,X,U,0);
X[1][1] = mr;X[2][1] =mc;
X[1][2] = lrr;X[2][2] =lrc;
X[1][3] = llr;X[2][3] =llc;
U[1][1] = 90;U[2][1] =mc;
U[1][2] = lrr;U[2][2] =lrc;
U[1][3] = llr;U[2][3] =llc;
InterpolateTriangle(inimg,outimg,X,U,0);
}
ifspot(outimg,argv[2]);
}
Example makefile using InterpolateTriangle
distort1: distort1.c
cc -o distort1 distort1.c -I/Users/wes/src/ifs/MacX64/hdr \
/Users/wes/src/ifs/MacX64/ifslib/libiptools.a \
/Users/wes/src/ifs/MacX64/ifslib/libifs.a \
/Users/wes/src/ifs/MacX64/ifslib/libflip.a
3.1.5
cubic splines
IFS library:
libiptools.a
usage:
void cubic_int(int n,int m,float* f, float* t, float* fn, float* tn)
n is the number of points in the input arrays (f and t),
m is the number of points in the output arrays (fn and tn)
both the time arrays, t and tn must be initialized
example initialization
// i n i t i a l i z e t
for ( i =0; i <N; i ++) {
f [ i ]= s i n ( 2 ∗ 3 . 1 4 ∗ i / ( f l o a t ) (N− 1 ) ) ;
t [ i ]=( f l o a t ) i ;
}
// i n i t i a l i z e t n
s t e p s i z e =(N−1)/( f l o a t ) (M−1);
for ( i =0; i <M; i ++) {
tn [ i ]= t [ 0 ] + i ∗ s t e p s i z e ;
98
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
fn [ i ]=0.0;
}
∗/
void c u b i c i n t ( int n , int m, f l o a t ∗ f , f l o a t ∗ t , f l o a t ∗ fn , f l o a t ∗ tn )
3.1.6
Resampling Curves
IFS library:
libiptools.a
Resample a line or curve to ensure uniform (arc-length) sampling. Accepts a set of
points, x-y pairs, and produces a set of x-y pairs. There are two functions which must be
called to use this feature: resampleinit and resamplesub. Usage:
#include <resample.h>
struct rs * resampleinit(int m,int n);
resampleinit sets up a structure in which to hold information about the resampled data.
m is the number of points in the input image (the number of rows in the array). n is the
number of points into which to divide the resampled output image. Once initialized, the
resample function is
void resamplesub(int m, int n, double **x, double **y,struct rs *p)
The first two arguments are the same as above: m is the current number of points, n will
be the number of points on the resampled curve. x and y are matrices, x2,m , y2,n holding
the actual data. These are arrays created by resampleinit using dmatrix (see section 2.2.1).
Their indices run from 1 to 2 (for the first index) and 1 to m or n. That is, they are created
using
x = dmatrix(1,2,1,m);y = dmatrix(1,2,1,n);
.
Note that while these functions are in libiptools, the matrix manipulation functions are
in libflip, so you will need to link with both those libraries.
Example resample
In the example below is shown how to set up and call the two resample functions. It does
not include details about how to read and write the ASCII input and output files.
#include <math.h>
#include <stdio.h>
#include <ifsmatrix.h>
3.1. GEOMETRIC FUNCTIONS
99
#include <resample.h>
#define EPSILON .0001
int main(int argc, char *argv[])
{
double **x; /* the input shape, it has m points */
double **y; /* the output shape, it will have n points, uniformly spaced in arc length */
/* the shapes above are pairs of floats. The even numbered ones are x coords, the odd y
*/
int m;
/* m is the number of points in the input shape */
int n;
/* n is the number of points we demand the output shape will have */
struct rs *rsdata; // this is the structure that will persist between resampleinit
// and resamplesub
double median;
FILE *fp, *fopen();
int j;
int getshape(char *, double **, double *, double); // function to read the input file
int getnumberofpoints(char *);
void clparse(int,char *[],struct clp *);// function to parse command line, not provided here
void resamplesub(int ,int,double **,double **,struct rs *);
struct rs *resampleinit(int,int);
/* call the read subroutine to read in the x,y pairs of points */
/* we pass the address of the shape pointer to getshape because the malloc
will be done inside getshape */
m = getnumberofpoints(infile); // read the input file to get the m
n = NUMBEROFOUTPUTPOINTS;
x = (double **)dmatrix(1,m+1,1,2);
y = (double **)dmatrix(1,m+1,1,2);
m = getshape(infile,x,&median,(double) 0.0); // read the input file
rsdata = resampleinit(m,n);
resamplesub(m,n,x,y,rsdata);
//inititalize the struct
/* write out the y array */
/* actually write the x array, since we have already swaplped pointers */
fp = fopen(outfile,"w");
for(j = 1; j <=NUMBEROFOUTPUTPOINTS; j++)
100
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
{
fprintf(fp,"%lf %lf\n",x[j][1],x[j][2]);
}
fclose(fp);
return 0;
}
3.1.7
Operations on FIFO’s
The following operations are useful in manipulating first-in-first-out memories, or queues.
All of them use a structure which contains information about the queue. The structure
has the following form:
struct myque{
int ∗q ;
int f r o n t ;
int r e a r ;
int s t a r t ;
int end ;
int count ;
};
fifo init; initialize the queue
call:
void fifo_init(int D,struct myque *queue);
fifo add; add a new number to the queue
call:
int fifo_add(int item ,struct myque *queue);
fifo remove
Remove a number from the queue and return it. call:
int fifo_remove(struct myque *queue);
fifo empty
Return true (nonzero) or false (zero) if the queue is or is not empty
call:
int fifo_empty(struct myque *queue);
3.1. GEOMETRIC FUNCTIONS
3.1.8
101
MinimumRegion
This function finds and marks all minimum regions in an image.
Every pixel in the output image either is a zero or has a distinct label
A minimum region is all the same brightness and has no neighbors darker than itself.
This function only runs on Unsigned Char images
This function is an almost direct translation from algorithm 4.6 of Roerding and Meijster.
Usage:
int MinimumRegion(IFSIMG img, IFSIMG labelimg)
Note: the source code for MinimumRegion is part of the source module Watershed.c
3.1.9
Watersheds
A watershed is the boundary between two basins.
int ifs_WaterShed(IFSIMG im,IFSIMG om);
Both images must be ifs images of type int.
The output image is a segmented version of the input image. It will contain uniquely
labeled regions. WaterShed points will have brightness zero. Note that although watershed
pixels are in principal the boundaries of basins, they are not necessarliy a single pixel thick.
The WaterShed program (see section ??) adds additional features by erasing watershed
pixels and assigning them to regions. The WaterShed program also provides the user with
the ability to pseudocolor the output image.
3.1.10
ifs ccl
IFS library:
libiptools.a
This function performs connected components on an image. It is the function called
by the program named ccl. The program ccl simply reads the command line, fills in a
structure from the command line, allocates some memory, and calls this function.
The declaration for the call is
void ifs_ccl(IFSIMG, IFSIMG, IFSIMG,struct PAR *parptr);
Because there are many options, the structure is rather long. The process of defining
the structure and filling it in is given below. The user is advised to simply cut and
paste the block below. This block includes the call to ifs ccl, passing the images and
the structure. The connect type field allows the user to specify which type of connivity is
used to determine when two pixels/voxels are considered neighbors. In three dimensions,
the three types of connectivity are shown in Figure 3.1. In two dimensions, FACE is
4-connected, EDGE is 8-connected.
102
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
Figure 3.1: Three types of connectivity may be used by the connected components function
in 3D images. In 2D images, FACE is equivalent to 4-connected, and EDGE is equivalent
to 8-connected
3.1. GEOMETRIC FUNCTIONS
103
{ /∗ s t a r t o f t h e b l o c k ∗/
// t h i s i s t h e d e f i n i t i o n o f t h e s t r u c t u r e
struct PAR {
char InFileName [ 1 0 0 ] ; // not needed i f c a l l e d as a f u n c t i o n
char OutFileName [ 1 0 0 ] ; // not needed i f c a l l e d as a f u n c t i o n
float lower limit ;
// low l i m i t o f p o i n t s c o n s i d e r e d , u s u a l l y z e r o
float upper limit ;
/∗ upper l i m i t o f p o i n t s c o n s i d r e d , u s u a l l y 255 ∗/
int
connect type ;
/∗ EDGE( 2 ) ,FACE( 1 ) or VERTEX( 4 ) ∗/
f l o a t c o n n t h r e s h o l d ; // c o n n e c t i o n t h r e s h o l d . two p i x e l s w i t h
// g r e a t e r d i f f e r e n c e w i l l not be c o n n e c t e d
int
roi set ;
// s e t t o one f o r Region o f I n t e r e s t
int
roi seed [ 3 ] ;
/∗ r o i s e e d l o c a t i o n , 3 numbers ∗/
int
r o i l a b e l ; /∗ l a b e l f o r r e g i o n o f i n t e r e s t ∗/
int
roi seg out ;
/∗ segment o u t t h e r o i components ∗/
int
r o i s e g v a l u e ; /∗ v o x e l v a l u e s f o r r e g i o n o f i n t e r e s t ∗/
int
l o w e r b g l a b e l ; /∗ l a b e l used f o r l o w e r b a c k g r o u n d ∗/
int
u p p e r b g l a b e l ; /∗ l a b e l used f o r upper b a c k g r o u n d ∗/
int
m i n l a b e l ; /∗ minimum l a b e l used ∗/
int
m a x l a b e l ; /∗ maximum l a b e l used ∗/
int
c a m s i z e ; /∗ s i z e o f c o n t e n t a d d r e s s a b l e memory a r r a y ∗/
unsigned int
∗cam ;
/∗ p o i n t e r t o t h e cam ; ∗/
/∗ t h e f o l l o w i n g 3 numbers c o u l d be o b t a i n e d from t h e image
b u t a r e i n c l u d e d i n t h e s t r u c t u r e o n l y f o r e f f i c i e n c y o f a c c e s s ∗/
int nr ; // number o f rows
int nc ; // number o f columns
int n f ; // number o f frames
};
struct PAR mypar , ∗ p a r p t r ; // an i n s t a n c e o f t h e s t r u c t u r e and a p o i n t e r t o i t
void i f s c c l ( IFSIMG , IFSIMG , IFSIMG , struct PAR ∗ ) ;
unsigned int ∗ cam ptr ;
int i ;
par=&mypar ; // i t i a l i z e t h e p o i n t e r
par−>InFileName [ 0 ] = 0 ; // not needed i f c a l l e d as a f u n c t i o n
par−>OutFileName [ 0 ] = 0 ; // not needed i f c a l l e d as a f u n c t i o n
par−>l o w e r l i m i t =0;
// low l i m i t o f p o i n t s c o n s i d e r e d , u s u a l l y z e r o
/∗ upper l i m i t o f p o i n t s c o n s i d r e d , u s u a l l y 255 ∗/
par−>u p p e r l i m i t =1;
par−>c o n n e c t t y p e =1;
/∗ EDGE( 2 ) ,FACE( 1 ) or VERTEX( 4 ) ∗/
par−>c o n n t h r e s h o l d =0; // c o n n e c t i o n t h r e s h o l d . two p i x e l s w i t h
par−>r o i s e t =0;
// s e t t o one f o r Region o f I n t e r e s t
104
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
par−>r o i s e e d [ 0 ] = 0 ;
/∗ r o i s e e d l o c a t i o n , 3 numbers ∗/
par−>r o i l a b e l =0; /∗ l a b e l f o r r e g i o n o f i n t e r e s t ∗/
par−>r o i s e g o u t =0;
/∗ segment o u t t h e r o i components ∗/
par−>r o i s e g v a l u e =1; /∗ v o x e l v a l u e s f o r r e g i o n o f i n t e r e s t ∗/
par−>l o w e r b g l a b e l =1; /∗ l a b e l used f o r l o w e r b a c k g r o u n d ∗/
par−>u p p e r b g l a b e l =500; /∗ l a b e l used f o r upper b a c k g r o u n d ∗/
par−>m i n l a b e l =1; /∗ minimum l a b e l used ∗/
par−>m a x l a b e l =5000; /∗ maximum l a b e l used ∗/
par−>c a m s i z e =64000; /∗ s i z e o f c o n t e n t a d d r e s s a b l e memory a r r a y ∗/
par−>cam=0;
/∗ p o i n t e r t o t h e cam i n i t i a l i z e d l a t e r ∗/
/∗ t h e f o l l o w i n g 3 numbers c o u l d be o b t a i n e d from t h e image
b u t a r e i n c l u d e d i n t h e s t r u c t u r e o n l y f o r e f f i c i e n c y o f a c c e s s ∗/
par−>nr=i f s d i m e n ( inimg , 1 ) ; // number o f rows
par−>nc=i f s d i m e n ( inimg , 0 ) ; ; // number o f columns
par−>n f =1; // number o f frames
/∗ now t h a t t h e s t r u c t u r e i s i n i t i a l i z e d , we a r e r e a d y t o c a l l t h e
c o n n e c t e d components f u n c t i o n ∗/
/∗ i n i t i a l i z e t h e c o n t e n t −a d d r e s s a b e memory∗/
/∗−−−−a l l o c a t e CAM and c a r d i n a l i t y a r r a y s ∗/
par−>cam = ( unsigned int ∗ ) c a l l o c ( par−>c a m s i z e , s i z e o f ( int ) ) ;
i f ( par−>cam == NULL) {
p r i n t f ( ” E r r o r : Unable t o a l l o c a t e %d e l e m e n t CAM\n” , par−>c a m s i z e ) ;
e x i t ( −1);
}
/∗−−−− i n i t i a l i z e CAM ∗/
cam ptr = par−>cam ;
for ( i = 0 ; i < par−>c a m s i z e ; i ++) ∗ cam ptr++ = i ;
/∗ n o t i c e c c l t a k e s t h r e e image i n p u t s , however , t h e t h i r d one
i s o n l y t o u c h e d i f ROI p r o c e s s i n g i s r e q u e s t e d , so we use outimg ∗/
/∗ FINALLY, we c a l l i t ! ∗/
i f s c c l ( inputimg , i m a g e a f t e r c c l , outimgwithROI , p a r p t r ) ;
}
3.1. GEOMETRIC FUNCTIONS
3.1.11
105
ifscfft2d
IFS library:
libiptools.a
ifscfft2d - perform in-place 2D fast Fourier transform Usage:
len = cfft2d(img_ptr, type) IFSHDR * imgptr; int type;
Ifscfftt2d performs an in-place 2-D fast Fourier transform on a complex ifs image. The
transform is performed in place on 8BYTE-PER-PIXEL (complex float) data only! Note
that ffts only work on images of dimension 2n×2n . The second argument is an indicator for
forward or inverse fft, -1 for forward, +1 for inverse. If there is some error, the subroutine
exits to the user with an error message. Possible errors are:
• Image dimensions are not a power of two
• Image data type is not complex float
106
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
3.1.12
ifsc2imag
IFS library:
libiptools.a
ifsc2imag - extract imaginary part of a complex ifs image, point by point Usage:
val = ifsc2imag (in1, out) int val; IMSHDR *in1,*out;
RETURNS 0 if successful, -1 if both arguments do not have same dimensions -2 if data
type unsupported (complex double) CAUTION: if output is type char, values greater than
255 will be clipped to lie between 0 and 255.
3.1. GEOMETRIC FUNCTIONS
3.1.13
107
ifsc2mag
IFS library:
libiptools.a
ifsc2mag - return magnitude of a complex ifs image, point by point Usage:
val = ifsc2mag (in1, out) int val; IMSHDR * in1,*out;
RETURNS 0 if successful, -1 if both arguments do not have same dimensions -2 if data
type unsupported (complex double) CAUTION: if output is type char, values greater than
255 will be truncated to 255.
108
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
3.1.14
ifsc2phase
IFS library:
libiptools.a
ifsc2phase - return phase of a complex ifs image, point by point Usage:
val = ifsc2phase (in1,out) int val; IMSHDR *in1,*out;
RETURNS 0 if successful, -1 if both arguments do not have same dimensions, -2 if data
type unsupported (complex double) CAUTION: if output is type char, values greater than
255 will be truncated to 255.
3.1. GEOMETRIC FUNCTIONS
3.1.15
109
ifsc2real
IFS library:
libiptools.a
ifsc2real - return real part of a complex ifs image, point by point Usage:
val = ifsc2real (in1,out) int val; IMSHDR *in1,*out;
RETURNS 0 if successful, -1 if both arguments do not have same dimensions -2 if data
type unsupported (complex double) CAUTION: if output is type char, values greater than
255 will be truncated to 255.
110
3.1.16
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
ifsInsert2Dinto3D
IFS library:
libiptools.a
ifsInsert2Dinto3D - inserts a 2D image as a single frame into a 3D ifs image
Usage:
val = ifsInsert2Dinto3D (IFSIMG in,IFSIMG out,int frame)
RETURNS 0 if successful, -1 if both arguments do not have same dimensions or if data
type unsupported (complex double) CAUTION: if output is type char, values greater than
255 will be converted to char.
3.1. GEOMETRIC FUNCTIONS
3.1.17
111
ifsmult
IFS library:
libiptools.a
ifsmult - multiply two ifs images, point by point Usage:
int ifsmult (in1, in2,out) IFSHDR *in1,*in 2,*out;
RETURNS 0 if successful, -1 if all three arguments do not have same dimensions -2 if data
type unsupported (complex double) -3 if one input has type complex and output is real
-4 if both inputs are real and output is complex CAUTION: if output is type char, values
greater than 255 will be truncated to 255. NOTES: if one image is real and the other
complex, the output must be complex and the real parts of the images will be added.
112
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
3.1.18
ifsrecip
IFS library:
libiptools.a
ifsrecip take reciprocal of an ifs image, point by point Usage:
int ifsrecip (in1,out) IFSHDR *in1,*out;
RETURNS 0 if successful, -1 if both arguments do not have same dimensions -2 if data
type unsupported (complex double) -3 if one input has type complex and output is real
-4 if both inputs are real and output is complex CAUTION: if output is type char, values
greater than 255 will be truncated to 255. NOTES: if one image is real and the other
complex, the output must be complex and the real parts of the images will be added.
3.1. GEOMETRIC FUNCTIONS
3.1.19
113
ifssub
IFS library:
libiptools.a
ifssub subtracts two ifs images, point by point. The second argument is subtracted
from first. Usage:
int ifssub (in1, in2, out) IFSHDR *in1,*in2,*out;
RETURNS 0 if successful, -1 if all three arguments do not have same dimensions -2 if data
type unsupported (complex double) -3 if one input has type complex and output is real
-4 if both inputs are real and output is complex CAUTION: if output is type char, values
greater than 255 will be truncated to 255. NOTES: if one image is real and the other
complex, the output must be complex and the real parts of the images will be added.
114
3.1.20
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
ifsvidscale
IFS library:
libiptools.a
ifsvidscale converts an ifs image, of any data type, to an unsigned char ifs image. The
brightness values are scaled to lie between 0 and 255. Usage:
int ifsvidscale (IFSHDR in1, IFSIMG out,float *minvalptr,float *maxvalptr, int switch3d)
The two arguments minvalptr and maxvalptr are pointers to floats, and will be returned
by ifsvidscale, reporting the minimum and maximum of the input images, respectively.
The switch3d argument, if not ==0, indicates that the frames of the image should be
scaled independently. Note that in this case, the minvalptr and maxvalptr apply only to
the last frame in the sequence.
RETURNS 0 if successful
The function will scale minimum brightness - maximum brightness to 0 to 255.
NOTES: The second image must be unsigned char.
Example:
img2=ifscreate("u8bit",len,IFS_CR_ALL,0);
ifsvidscale(inimage, img2,&mymin,&mymax,0);
3.2
3.2.1
Functions to modify images
ifscolormap
IFS library:
libiptools.a
The function ifscolormap is similar to the program ColorMap in that it allows you to assign
a number of different colors to an 8-bit, unsigned image. That is, each of the possible 256
brightness levels will be assigned a color. There are many ways to assign an R, G, and B
value to a single pixel brightness. The function offers several different ways to interpret
the brightnesses.
Usage:
void ifscolormap( IFSIMG inputimage, IFSIMG outputimage, int
X);
Where inputimage is an unsigned 8 bit fs image, and X is an integer between 0 and 6 which
tells the program which color map to use as follows:
0 grey scale
1 inverse gray scale
2 bronson
3 hot metal
4 heated spectrum
5 log
6 random
3.2. FUNCTIONS TO MODIFY IMAGES
115
The input image must be unsigned 8 bit, since there are only 256 unique colors .
The input image must be two-dimensional.
The output file must be a 3 D unsigned 8 bit ifs image, with 3 frames, with the usual
interpretation that frame 0 is red, frame 1 is green, and frame 2 is blue. The function does
not create this image, a pointer to it is passed by the calling function.
example use
int l e n [ 4 ] ;
IFSIMG inimage , outimg ;
extern void i f s c o l o r m a p ( IFSIMG , IFSIMG , int ) ;
...
len [0]=3;
l e n [ 1 ] = i f s d i m e n ( inimage , 0 ) ; // g e t number o f c o l s
l e n [ 2 ] = i f s d i m e n ( inimage , 1 ) ; // g e t number o f rows
l e n [ 3 ] = 3 ; // image w i l l have 3 frames
outimg=i f s c r e a t e ( ” u 8 b i t ” , l e n , IFS CR ALL , 0 ) ;
i f s c o l o r m a p ( inimg , outimg , 3 ) ; // use a h o t m e t a l c o l o r map
...
i fs C Vp ot ( outimg , ”myimage . png” ) ;
...
3.2.2
Lower Complete Images
To understand this, first recall that in a digital image, a maximum is a connected set
of pixels, which are all the same brightness, with the property that no pixel in this set
is adjacent to any brighter pixel. A minimum is a similarly defined set. A plateau is
a connected set of pixels, which are all the same brightness, but which has at least one
neighboring pixel which is brighter and one which is darker. Plateaus cause probems to
some algorithms.
A lower complete image is one in which every pixel is either a maximum, a minimum,
or has at least one lower neighbor. That is, a lower complete image has no plateaus. This
function provides that capability.
void Build_Lower_Complete(IFSIMG inimage,IFSIMG LowerCompleteImage)
The input, inimage, must be unsigned 8 bit. The output, LowerCompleteImage, must be
type int. The brightness values will be changed to ensure the image is lowercomplete.
3.2.3
zoomupdown
Will zoom an image
Example usage:
116
CHAPTER 3. IMAGE PROCESSING SUBROUTINES
img1 = ifspin("/Users/wes/Images/asterix256.ifs");
len[0]=2;
len[1]= ifsdimen(img1,0) * 2;
len[2] =ifsdimen(img1,0) * 1;
img2 = ifscreate(img1->ifsdt,len,IFS_CR_ALL,0);
zoomupdown(img1,img2);
The input image will be zoomed to the size of the output image. The output image will
be overwritten with the zoomed version of the input image. The two images do not have
to have proportional dimensions. For example, inputimage could be 512 x 512 and output
image could be 640 x 480. Of course, unless the images have proportional dimensions, the
output image will be distorted.
3.3
3.3.1
Random number generators
gaussrand
IFS library:
libiptools.a
double gaussrand()
returns a Gaussian-destributed random number with standard deviation of one and mean
of zero.
Chapter 4
Image Synthesis Programs
4.1
Qsyn-synthesize range images
Qsyn generates synthetic altitude images of objects which are composed of quadric surfaces
or pieces of quadric surfaces. Usage:
qsyn [-f][-l labelfile.ifs] [-o depthfile.ifs] formatfile.q
The -f switch is optional and if used will cause the output file to be floating point.
The -l switch is optional and if used will cause qsyn to also output a label image, in which
each surface is a different brightness – the image is segmented.
If the -o switch is not used to provide a name for the altitude output image, then after
running, the program will ask for the name of the output altitude image.
The label image is an image in which every pixel belonging to the same region is labeled
the same. Thus, the label image is equivalent to the output of an ideal segmenter. This
can be used to test the performance of segmentation algorithms.
Qsyn is a program which generates synthetic altitude images of objects which are
composed of quadric surfaces or pieces of quadric surfaces. The image data is in an unsigned
byte format, although a few minor changes could be made to Qsyn to allow for some other
output data type. Image manipulation is done using the IFS image manipulation routines
in use at Communication Unlimited. Qsyn generates altitude images, i.e., two dimensional
images which contain three dimensional information, where the coordinates of a pixel (its
row and column index) correspond directly to the x and y values for the pixel, and the
pixel value itself (the datum) corresponds directly to the altitude or z value for the point.
Hence, a point in three-space at position [x, y, z] corresponds to some pixel in an image I:
[x, y, z] → I[r, c]
(4.1)
where I[r,c] is the value of the pixel at row r, column c of the image. r, c, and I[r,c] are
linearly related to y, x, and z, respectively. In Qsyn, the linear relationship is simply taken
117
118
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
to be r = y, c = x, and I[r, c] = z. Note that an altitude image is not the same as a
range image, which is also commonly used to represent three-dimensional images. In a
range image, the pixel value represents the distance from some point in three space to a
fixed reference position (i.e., the view point), whereas an altitude image is based on the
distance to some reference plane, hence a range image is actually a perspective projection
of an altitude image.
Qsyn generates images composed of quadric surfaces. An image may contain any number of surfaces; in addition, each surface may also have constraints placed on it. These constraints are also quadric surfaces (quadric inequalities). A quadric surface is a 3-dimensional
surface which may be described by a general quadric equation:
q(x, y, z) = Ax2 + By2 + Cz2 + F yz + Gxz + Hxy + P x + Qy + Rz + K = 0
(4.2)
This includes common shapes such as spheres, cones, and planes. Qsyn works by generating
a quadric surface which is bounded by a set of quadric constraints. For example, an image
of an open-ended can maybe produced by synthesizing an image of a cylinder which is
constrained by two planes perpendicular to the cylinder. The constraints would specify
those points on the cylindrical surface which lie above the lower plane and below the upper
plane. As a matter of terminology, I will use the term quadric section to refer to a quadric
surface along with a set of constraints on that surface. In order to use Qsyn, you must
understand the coordinate systems it uses to orient surfaces and sections. Theoretically,
you could place surfaces wherever you wanted by specifying the appropriate coefficients in
the quadric equation 4.2. In practice, this is a pain since the coefficients are a function of
the objects position and orientation as well as its shape. E.g.,
x2 + y 2 + z 2 = r 2
(4.3)
describes a sphere of radius r centered at the origin. The quadric coefficients are A = B =
C = 1; K = −(r2 ). Moving this sphere so that its center is at location (x, y, z) = (10, 5, 0)
gives:
(x − 10)2 + (y − 5)2 + z 2 = r2
(4.4)
which when put into the form of equation 4.5 looks like
x2 + y 2 + z 2 − 20x − 10y + (125 − r2 ) = 0.
(4.5)
Rotating an object affects the quadric coefficients in a still more complicated way. Qsyn
allows you to specify a surface using any coordinate system you desire; you may then
translate or rotate the object to move it to a different coordinate system.
Qsyn uses several different coordinate systems to ease the task of creating images which
are composed of multiple surfaces. Figure 4.1 shows the various coordinate systems used,
and are described here. Each surface (including constraints) is defined in terms of its own
local coordinate system. Typically you would choose the coordinate system in which it was
4.1. QSYN-SYNTHESIZE RANGE IMAGES
119
easiest to describe the shape you want. Each quadric section has its own coordinate system,
known as a section or object coordinate system. The latter term is perhaps misleading in
that what you think of as an object may actually consist of more than one section.
By specifying the relationship between the local coordinate system for each surface in a
section to the sections coordinate system, you specify how the various parts of the section
fit together. This essentially is used to relate the constraints to the actual surface being
synthesized, with the coordinate system of the surface itself (its local system) typically
being coincident with the section coordinate system. This is not a requirement though;
the surface and its constraints are all placed relative to a common section system, rather
than the constraints being placed relative to the local system of the surface.
The next higher level coordinate system is the reference or base coordinate system. This
is the base coordinate system for the entire image to be synthesized. Its relationship to the
object coordinate systems is the same as that of the object to local coordinate systems.
By specifying the relative locations of each object coordinate system in the base system,
you define how the various quadric sections fit together, and define what the over all image
will look like.
The highest level coordinate system is the viewpoint coordinate system. This corresponds to the coordinate system for the image array, and hence, the display equipment.
The x and y axes correspond to the horizontal and vertical axes of the display, and the z
axis is the actual pixel value, i.e., the brightness or color of the pixel indicates the altitude.
The relation between the view coordinate system and the base coordinate system specifies the position which you are actually seeing the image from. In many cases the two
coordinate systems may be coincident, or one merely a translation of the other.
Note that the term “viewpoint system” is somewhat misleading in that this is not a
range image; this transform really defines a plane of projection for the image (which is
fully described at the level of the base system). The projection plane itself is the xy plane
of the viewpoint coordinate system. The image array itself is just a finite piece of this
infinite projection plane. Specifically, the origin [x, y] = [0, 0] corresponds with the pixel at
location [col, row] = [0, 0] in the image array (which is in one corner of the image). Hence,
if you define the objects in your image to lie around the origin (in the base coordinate
system), when you display the image you will probably find that all of the objects will
lie in one corner of the image, unless you have displaced the base system relative to the
viewpoint system. Put simply, the origin of the base system will be in one corner of the
image you synthesize unless you make sure to move it – and you may end up not seeing
parts of your objects since they will be clipped at the image borders.
In Qsyn, the relations between coordinate systems are expressed in terms of six basic
motions: translations along the three coordinate axes, and rotations about the axes. Motions along the axes go by the names of movex, movey, and movez. Rotations about the
axes go by the names of rotx, roty, and rotz, or alternatively as yaw, pitch, and roll, respectively. When specifying the relationship between two coordinate systems, the motions
are given in terms of the higher coordinate system, i.e., the higher level system is the base
120
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
Figure 4.1: Coordinate systems used by Qsyn
4.1. QSYN-SYNTHESIZE RANGE IMAGES
121
Figure 4.2: Order of motions
system. For example, to specify that the local coordinate system for a constraint has its
origin at location (x, y, z) = (10, 5, 2) in the section coordinate system, you would specify
the motion as the motion as (movex 10, movey 5, movez 2), as this would be specifying the
origin of the higher system (the section system) in terms of the lower (the local system).
This is easy to see for motions which are pure translations, but may provide a source of
confusion when rotations are involved.
The best way to regard the motions is as being object oriented. Although you are
specifying the relationship between two coordinate systems, the lower coordinate system
can be regarded as an object in the higher coordinate system (imagine that the lower level
system has a cube sitting at its origin, and you are moving the cube around in the higher
level system). Initially, the two coordinate systems start out with coincident axes, i.e., the
lower system is an object sitting at location (0, 0, 0) in the higher system. If you specify a
motion of movex10, then all objects in the higher level system are displaced 10 units down
the x axis. If you specify a motion of roll20, then all objects swivel around the z axis of
the higher system. This is not the same as simply rotating the lower coordinate systems
coordinate system by 20 degrees! If the lower systems origin coincides with the higher
systems origin, then the effects are the same; however, if the origin points do not coincide,
then the lower systems origin will be seen to swing on an arc around the higher systems
axis. Hence, the rotation will also cause a translation in two of the axes of the higher
122
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
system. Figure 4.1 illustrates this, and also show how the order of motions is important.
Qsyn works by reading a file which describes the image to be synthesized. This file contains the quadric coefficients for each surface and constraints (in their own local coordinate
system), and movement commands which specify how the coordinate systems are located.
Qsyn reads this specification file and generates the image; when it is done, it prompts
for the name of a file to write the image to. The output file is a 2-d IFS format image.
The data type for the image will be unsigned byte or float (depending on a command line
switch), with the value of a pixel indicating its height. The nearer a pixel is, the higher
its pixel value. The format for the image specification file is relatively simple. Presented
below is a sample specification file; the format is described below. It is a text file composed
of several blocks. These blocks may contain other blocks within them.
At the beginning of the file is a header block which specifies the size (number of rows
and columns) of the image to be generated, the number of quadric sections to synthesize,
and a set of motions which will translate the reference coordinate system to the viewpoint
coordinate system.
The motions which specify the relationship between the two coordinate systems are
actually an instance of a type of sub-block known as a coordinate transform block, or just
transform. These transforms occur in several places, and always have the same format.
There are six basic motions which may be specified in a transform block. There are also
several complex motions which are simply composites of the basic motions. All of the
motions are specified by some keyword describing the motion to perform, followed by the
parameters appropriate for that keyword. The six basic motions are those mentioned
earlier: movex, movey, movez, rotz(roll), roty(pitch), and rotx(yaw). The movex, movey,
and movez commands can also be shortened to x, y, and z. Each motion takes a single
argument which is the amount to move or the angle to rotate (in degrees). To specify a
complete transform block, you merely specify an arbitrary number of basic motions (in
arbitrary order), followed by the keyword end. The basic motions are performed in the
order specified. A sample transform block might look like:
movex 20 movey 10 pitch 30 end
This will shift an object 20 units along the x axis, 10 units in y, and swing the object 30
degrees around the y axis.
The composite motions are just shortcuts for specifying certain common sets of motions.
The combination ‘movex 10 movey 20 movez 30’ can be specified more rapidly as ‘movexyz
10 20 30’ or just ‘xyz 10 20 3’. Similarly, rpy 10 20 30 is short for roll 10 pitch 20 yaw 30. All
six basic motions can be expressed using the commands rpyt θz , θy , θx , ∆x , ∆y , ∆z and trpy
θz , θy , θx , ∆x , ∆y , ∆z . Rpyt does the rotations first, then the translations; trpy performs
the translations first. Note that the syntax for trpy is inconsistent in that although the
translations are performed first, they are the last arguments specified for the command.
After the header block there comes a set of section blocks, one block for each quadric
section to synthesize. Each block describes a surface to generate, and all the constraints
4.2. 3DSYN-SYNTHESIZE DENSITY IMAGES
123
for the surface. The quadric section blocks are in turn composed of smaller blocks. The
first sub-block is a transform block which converts from the section coordinate system
to the base coordinate system. This is followed by a surface block. A surface block
contains a set of quadric coefficients to describe a single quadric surface, and also contains
a transform block which translates the surfaces local coordinate system to the section
coordinate system. After the surface block comes the number of constraints, followed by
a set of constraint blocks. A constraint block is identical to a surface block except that it
contains a flag indicating which way the constraint inequality goes (e.g., choose all points
in the surface below some plane ).
4.2
3dsyn-synthesize density images
CONVERSION TO LATEX NOT FINISHED
3dsyn generates synthetic three dimensional density images of objects which are composed of quadric surfaces or pieces of quadric surfaces. Usage:
3dsyn format file.q
3dsyn is a program which generates synthetic three dimensional density images of objects
which are composed of quadric surfaces or pieces of quadric surfaces. The image data is
in an unsigned byte format, although a few minor changes could be made to 3dsyn to
allow for some other output data type. Image manipulation is done using the IFS image
manipulation routines in use at Communication Unlimited.
3dsyn generates density images, i.e., three dimensional images which contain three
dimensional information, where the coordinates of a voxel (its row and column and frame
index) correspond directly to the x, y, and z values for the voxel, and the voxel value itself
(the datum) corresponds directly to the density for the point. Hence, a point in three-space
at position [x, y, z] corresponds to some voxel in an image I:
[x, y, z] → [f, r, c]
(4.6)
where I[f, r, c] is the value of the voxel at frame f, row r, column c of the image. The
variables, f, r, c, and I[f, r, c] are linearly related to z, y, and x, respectively. In 3dsyn, the
linear relationship is simply taken to be f = z, r = y, and c = x, and I[f,r,c] = density.
3dsyn generates images composed of quadric surfaces. An image may contain any
number of surfaces; in addition, each surface may also have constraints placed on it.
These constraints are also quadric surfaces (quadric inequalities). A quadric surface is
a 3-dimensional surface which may be described by a general quadric equation:
q(x, y, z) = Ax2 + By 2 + Cz 2 + F yz + Gxz + Hxy + P x + Qy + Rz + K = 0.
(4.7)
This includes common shapes such as spheres, cones, and planes. 3dsyn works by generating a quadric surface which is bounded by a set of quadric constraints. For example, an
124
#
#
#
#
#
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
This is a Qsyn description file which will generate a simple altitude image
of a clipped lead sticking through a hole in the under side of a printed
circuit board. The lead will have a "clinch angle" (angle that lead is
bent away from pointing straight up) of 80 degrees, and a "lead angle"
(angle in the xy plane -- the plane representing the PC board) of 30 degrees.
#The image is composed of 4 pieces (quadric sections):
# 1. A cylindrical piece which is the body of the lead.
# 2.A plane with a hole in it which represents the circuit board.
# The cylinder in (1) goes through the hole.
# 3.A sphere at one end of the cylinder in (1) [same radius as the
# cylinder] which terminates the lower end of the lead.
# 4.A second spherical section which caps the other end of the lead.
#
# This second sphere has a larger radius than the sphere, so that
#
# the higher end of the cylinder is clipped almost in a plane.
#
# Note that if this cap wasnt here, youd be able to see inside the #
# cylinder in (1)! #
# #
# NOTE: This file is not directly suitable to be passed as input to Qsyn.
#
# Qsyn understands comments in a file (comments going from
#
# the # symbol to the end of the line). If you insist on removing them, a little #
# cleverness under Unix systems will make it suitable: #
# #
# sed s/#.*$//example.q | Qsyn #
# #
# The strange looking "sed" command will edit out the comments before #
# piping the file into Qsyn. #
# itself. #
# # #####################################################################
Figure 4.3: Qsyn expample page 1
4.2. 3DSYN-SYNTHESIZE DENSITY IMAGES
125
#-------------------------Header section------------------------------------128 128 #Dimensions of image
4 # Number of quadric sections in image
# This is the ’base’ to ’viewpoint’ coordinate system transform block:
roll 030 #0 # Rotate 30 degrees about the Z axis
# This rotates EVERYTHING by 30 degrees, and is
# what gives the lead a "lead angle" of 30 degrees.
# Note that Im really rotating the board too, but
# since the board is an infinite xy-plane, you cant
# tell it. Hence, a more technically accurate, but
# slightly more cumbersome way to do this is to have
# the "roll 30" in the section to base transforms
# of each of the actual pieces making up the lead.
movex 64 # Now Ill do a translation in X and Y so that
movey 64 # the object is centered in the image rather
movez 75 # than in the lower left corner.
end # movez 75 is just cause I want board at Z = 75. \
#
#----------------------End of header section--------------------------------# This is the first quadric section. It describes the plane which represents
# the printed circuit board.
# SECTION to BASE coordinate system transform block.
# All of the surfaces in this sections (that is, including the constraint )
end # A Null block (i.e., the two systems here
#
are coincident).
####### Define quadric surface:
# The quadric surface coefficients:
000
000
001
0 # The plane "Z = 0"
# and the transform relating the LOCAL system to the SECTION system:
end # Null block. Systems are coincident
#######end of definition for the quadric surface.
Figure 4.4: Qsyn example , page2
126
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
#
Now: define the constraints on the above surface:
1 # this is the number of constraints.
#
1 1 1 # constraint quadric coefficients
0 0 0
# X*X+Y*Y+Z*Z=100, i.e., a sphere of
0 0 0 -100 # radius 10.
#
#LOCAL to SECTION transform for this constraint:
end
#Once again, no transform.
# And lastly, a "<" or ">" symbol which indicates on which side of the
# constraint surface the object must lie:
>
# The ">" specifies that my constraint
#
equation actually is
#
X*X + Y*Y + Z*Z > =100
# Hence, only points on the plane Z = 0 which
# are OUTSIDE this sphere are valid.
# This puts a hole at the center of my plane.
#
#
#
#
#
#
#
#
This is the second quadric section. Its the cylinder which makes up the
body of the lead. I originally define the cylinder as lying on the Z axis
(which also makes it easy to specify constraints on it). Then I use the
SECTION to BASE transform to tip the cylinder (and its constraints) over
to give the appearance of a clinched lead.
The SECTION to BASE transform: lead is clinched 80 degrees. The "movez 6"
displaces the cylinder upwards 6 units, which is needed because otherwise
the lead will be embedded in the board plane, rather than lying just above it
pitch 080 movez 6 end
# Define my cylinder: cylinder on Z axis with radius 6:
110 000 000 -36
end # No transform.
Figure 4.5: Qsyn example, page3
4.2. 3DSYN-SYNTHESIZE DENSITY IMAGES
127
# Now, specify my constraints. Remember that the cylinder is defined as
# lying on the Z axis (even in the SECTION system, since the above transform
# was null), so the constraints clip the cylinder at right angles to its
# axis. Now, the SECTION to BASE transform applies to both the cylinder
\# and its constraints, so the net effect is to pitch the CLIPPED cylinder
# by 80 degrees.
#
2 # there will be two constraints.
0 0 0 0 0 0 0 0 1 0 end > # Constraint 1: Z > =0
0 0 0 0 0 0 0 0 1-34 end<
#Constraint 2: Z<=34
#
# So, now I have a cylindrical piece lying between Z = 0 and Z = 34.
# Note that the cylinder is NOT capped at the ends.
# Section 3. This is a sphere which will cap off the lower end of the lead.
movez 6 end # The "movez 6" is same as in section 2.
1 1 1
0 0 0
# Sphere of radius 6 (at the origin in the local
0 0 0
# system)...
-36
end
#... and at the origin in the SECTION system...
#
but centered at x, y, z = 0,0,6 in the BASE system.
0
# Zero constraints.
Figure 4.6: Qsyn example, page4
128
#
#
#
#
#
#
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
Lastly, section 4, the sphere capping off the upper end of the lead.
You need to pay careful attention to the movements for this piece to
observe how the spherical patch does indeed end up capping off the
cylinder described in section 2. Note that the movements given here
certainly do not describe the ONLY valid way to get the patch; any of
a variety of movements would do the trick.
pitch 080 movez 6 end
1 1 1
# sphere of radius 8.
0 0 0
0 0 0
-64
movez 28. 7085 end
# That goofy number you have to work out from
# the geometry of the situation. The sphere
# is placed so that it will sit right at the
# end of the clipped cylinder. The sphere
# will intersect the cylinder at a height of
# Z = 34 (or Z = 40 after the "movez 6" is
# applied).
1 # 1 constraint:
0 0 0 0 0 0 0 0 1 -34 end > #only want that part of the
# sphere which will cap off
# the cylinder; I dont want
# to put a big ball at the
# end of the cylinder.
#### and now, the name of the file to write the image to:
pcb_lead.ifs
Figure 4.7: Sample Qsyn input file, page5
4.2. 3DSYN-SYNTHESIZE DENSITY IMAGES
129
128 128
2
end
end
000
000
1 0 -1 -20
end
4
000
000
1 0 0 -20 end >
000
000
1 0 0 -30 end <
000
000
0 1 0 -20 end >
000
000
0 1 0 -30 end <
end
000
000
-2 0 -1 +70
end
4
000
000
1 0 0 -30 end >
000
000
1 0 0 -35 end <
000
000
0 1 0 -20 end >
THIS IS NOT COMPLETE
Figure 4.8: Another example Qsyn description: a plane at z = 0 with two sloped planes in
a rectangular area between x = 20 and x = 35
.
130
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
image of an open-ended can may be produced by synthesizing an image of a cylinder which
is constrained by two planes perpendicular to the cylinder. The constraints would specify
those points on the cylindrical surface which lie above the lower plane and below the upper
plane. As a matter of terminology, I will use the term quadric section to refer to a quadric
surface along with a set of constraints on that surface. In order to use 3dsyn, you must
understand the coordinate systems it uses to orient surfaces and sections. Theoretically,
you could place surfaces wherever you wanted by specifying the appropriate coefficients in
the quadric equation 7. In practice, this is a pain since the coefficients are a function of
the objects position and orientation as well as its shape. E.g.,
x2 + y 2 + z 2 = r 2
(4.8)
describes a sphere of radius r centered at the origin. The quadric coefficients are A = B =
C = 1, K = −(r2 ). Moving this sphere so that its center is at location (x, y, z) = (10, 5, 0)
gives: (x − 102 + (y − 5)2 + z 2 = r2 which when put into the form of equation 7 looks
like x2 + y 2 + z 2 ?20x?10y + (125?r)2 = 0. (10) Rotating an object affects the quadric
coefficients in a still more complicated way. 3dsyn allows you to specify a surface using
any coordinate system you desire; you may then translate or rotate the object to move it
to a different coordinate system. 3dsyn uses several different coordinate systems to ease
the task of creating images which are composed of multiple surfaces. Figure 3.1 shows the
various coordinate systems used, and are described here in the text.
Each surface (including constraints) is defined in terms of its own local coordinate
system. Typically you would choose the coordinate system in which it was easiest to
describe the shape you want. Each quadric section has its own coordinate system, known
as a section or object coordinate system. The latter term is perhaps misleading in that
what you think of as an object may actually consist of more than one section.
By specifying the relationship between the local coordinate system for each surface in a
section to the sections coordinate system, you specify how the various parts of the section
fit together. This essentially is used to relate the constraints to the actual surface being
synthesized, with the coordinate system of the surface itself (its local system) typically
being coincident with the section coordinate system. This is not a requirement though;
the surface and its constraints are all placed relative to a common section system, rather
than the constraints being placed relative to the local system of the surface.
The next higher level coordinate system is the reference or base coordinate system. This
is the base coordinate system for the entire image to be synthesized. Its relationship to the
object coordinate systems is the same as that of the object to local coordinate systems.
By specifying the relative locations of each object coordinate system in the base system,
you define how the various quadric sections fit together, and define what the overall image
will look like.
The highest level coordinate system is the view point coordinate system. This corresponds to the coordinate system for the image array, and hence, the display equipment.
4.2. 3DSYN-SYNTHESIZE DENSITY IMAGES
131
The relation between the view coordinate system and the base coordinate system specifies the position which you are actually seeing the image from. In many cases the two
coordinate systems may be coincident, or one merely a translation of the other. Note that
the term viewpoint system is somewhat misleading in that this is not a range image; this
transform really defines a plane of projection for the image (which is fully described at
the level of the base system). The projection plane itself is the xy plane of the viewpoint
coordinate system. The image array itself is just a finite piece of this infinite projection
plane. Specifically, the origin [x, y, z] = [0, 0, 0] corresponds with the voxel at location [f
rame, col, row] = [0, 0, 0] in the image array (which is in one corner of the image). Hence,
if you define the objects in your image to lie around the origin (in the base coordinate
system), when you display the image you will probably find that all of the objects will
lie in one corner of the image, unless you have displaced the base system relative to the
viewpoint system. Put simply, the origin of the base system will be in one corner of the
image you synthesize unless you make sure to move it - and you may end up not seeing
parts of your objects since they will be clipped at the image borders.
In 3dsyn, the relation between coordinate systems is expressed in terms of six basic motions: translations along the three coordinate axes, and rotations about the axes. Motions
along the axes go by the names of movex, movey, and movez. Rotations about the axes go
by the names of rotx, roty, and rotz, or alternatively as yaw, pitch, and roll, respectively.
When specifying the relationship between two coordinate systems, the motions are given
in terms of the higher coordinate system, i.e., the higher level system is the base system.
For example, to specify that the local coordinate system for a constraint has its origin at
location (x,y,z) = (10,5,2) in the section coordinate system, you would specify the motion
as (movex 10, movey 5, movez 2). Note that you do not specify the motion as (movex -10,
movey -5, movez -2), as this would be specifying the origin of the higher system (the section
system) in terms of the lower (the local system). This is easy to see for motions which are
pure translations, but may provide a source of confusion when rotations are involved.
The best way to regard the motions is as being object oriented. Although you are
specifying the relationship between two coordinate systems, the lower coordinate system
can be regarded as an object in the higher coordinate system (imagine that the lower level
system has a cube sitting at its origin, and you are moving the cube around in the higher
level system). Initially, the two coordinate systems start out with coincident axes, i.e., the
lower system is an object sitting at location (0, 0, 0) in the higher system. If you specify
a motion of movex 10, then all objects in the higher level system are displaced 10 units
down the x axis. If you specify a motion of roll 20, then all objects swivel around the z
axis of the higher system. This is not the same as simply rotating the lower coordinate
systems coordinate system by 20 degrees! If the lower systems origin coincides with the
higher systems origin, then the effects are the same; however, if the origin points do not
coincide, then the lower systems origin will be seen to swing on an arc around the higher
systems axis. Hence, the rotation will also cause a translation in two of the axes of the
higher system. Figure 3.1 illustrates this, and also shows how the order of motions is
132
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
important. 3dsyn works by reading a file which describes the image to be synthesized.
This file contains the quadric coefficients for each surface and constraint (in their own
local coordinate system), the density of the material contained within that surface, and
movement commands which specify how the coordinate systems are located. 3dsyn reads
this specification file and generates the image; when it is done, it prompts for the name of a
file to write the image to. The output file is a 3-d IFS format image. The data type for the
image will be unsigned byte, with the value of a voxel indicating its density. The format
for the image specification file is relatively simple. Figure 3.8 shows a sample specification
file; the format (described below), is identical to the description for Qsyn except for the
inclusion of density value on each line describing a quadric.
It is a text file composed of several blocks. These blocks may contain other blocks
within them. At the beginning of the file is a header block which specifies the size (number
of frames, rows and columns) of the image to be generated, the number of quadric sections
to synthesize, and a set of motions which will translate the reference coordinate system
to the view point coordinate system. The motions which specify the relationship between
the two coordinate systems are actually an instance of a type of sub-block known as a
coordinate transform block, or just transform. These transforms occur in several places,
and always have the same format. There are six basic motions which may be specified in
a transform block. There are also several complex motions which are simply composites
of the basic motions. All of the motions are specified by some keyword describing the
motion to perform, followed by the parameters appropriate for that keyword. The six
basic motions are those mentioned earlier: movex, movey, movez, rotz (roll), roty (pitch),
and rotx (yaw). The movex, movey, and movez commands can also be shortened to x, y,
and z. Each motion takes a single argument which is the amount to move or the angle to
rotate (in degrees). To specify a complete transform block, you merely specify an arbitrary
number of basic motions (in arbitrary order), followed by the keyword end. The basic
motions are performed in the order specified. A sample transform block might look like:
movex 20 movey 10 pitch 30 end
This will shift an object 20 units along the x axis, 10 units in y, and swing the object
30 degrees around the y axis.
The composite motions are just shortcuts for specifying certain common sets of motions. The com- bination movex10movey20movez30 can be specified more rapidly as
movexyz102030 or just xyz102030. Similarly, rpy102030 is short for roll10pitch20yaw30. All
six basic motions can be expressed using the commands rpyt ?z?y?xDeltaxDeltayDeltaz
and trpy ?z?y?xxyz. Rpyt does the rotations first, then the translations; trpy performs
the translations first. Note that the syntax for trpy is inconsistent in that although the
translations are performed first, they are the last arguments specified for the command.
After the header block there comes a set of section blocks, one block for each quadric
section to synthesize. Each block describes a surface to generate, and all the constraints
for the surface. The quadric section blocks are in turn composed of smaller blocks. The
first sub-block is a transform block which converts from the section coordinate system to
4.3. MATTE - SYNTHESIZE LUMINANCE IMAGES
133
32 32 32 7 rpyt 0.0 0.0 0.0 15.0 15.0 15.0 end
end 0.7164 0.4030 0.4030 0 0 0 0 0 0 -87.3151 255.0 0.0 end 0
rpyt 0.0 0.0 0.0 0.0 -0.2944 -0.2944 end 0.5835 0.3352 0.3352 0 0 0 0 0 0 -65.5430 -255.0 0.0
end 0
rpyt -18.0 0.0 0.0 3.52 0.0 0.0 end 0.00923521 0.00116281 0.00116281 0 0 0 0 0 0 -0.028607 31.0
end 0
rpyt 18.0 0.0 0.0 -3.52 0.0 0.0 end 0.02825761 0.00430336 0.00430336 0 0 0 0 0 0 -0.1851891 31.
rpyt 0.0 0.0 0.0 0.0 5.6 0.0 end 0.00390625 0.00275625 0.00275625 0 0 0 0 0 0 -0.04410 23.0 0.0
end 0
rpyt 0.0 0.0 0.0 0.0 1.6 0.0 end 1.0 1.0 1.0 0 0 0 0 0 0 -0.541696 47.0 0.0 end 0
rpyt 0.0 0.0 0.0 0.0 -1.6 0.0 end 1.0 1.0 1.0 0 0 0 0 0 0 -0.541696 47.0 0.0
end 0
Figure 13: Figure3.8: Example 3Dsyn input file (A synthetic head)
the base coordinate system. This is followed by a surface block. A surface block contains
a set of quadric coefficients to describe a single quadric surface, the interior and exterior
densities of the object, and also contains a transform block which translates the surfaces
local coordinate system to the section coordinate system. After the surface block comes
the number of constraints, followed by a set of constraint blocks. A constraint block is
identical to a surface block except that it contains a flag indicating which way the constraint
inequality goes (e.g., choose all points in the surface below some plane).
4.3
Matte - synthesize luminance images
CONVERSION TO LATEX NOT FINISHED Name: matte.c
Action: Produces a matte luminance image given a range image and one or more light
sources of any brightnesses. That is, the range image is modeled as being a Lambertian
reflector. matte converts a 2-D range image into a matte luminance image.
USAGE: usage: matte -i infile -o outfile -s
FLAGS: command line args are... -h help-screen -i Input file name -o output file name
-s Ignore shadowing LIGHTS: This program generates a matte image illuminated by a set
of light sources that you specify. The user is prompted for the locations of the light sources.
Notes
• Comments (like in the example) aren’t allowed
• Be careful with the z coordinate. Large positive z values place the light source in
front of the object: good. Negative z, or even small positive z, may place the light
BEHIND the object: (bad), which may generate a null image.
• 50 lights max.
134
CHAPTER 4. IMAGE SYNTHESIS PROGRAMS
Example:
matte -i pcblead.ifs -o leadbrightness.ifs
Enter number of light sources>2
For each source, enter position (col,row,height) and brightness>64 64 200 10 20 30 200 2
ALGORITHM
Read lights from user (or redirect of standard input) call ifsderiv to compute gradients
of range image for every pixel Compute normal to this pix; Compute vector from this
pix to each light; Compute cosine of angle between normal and lights; Light this pix by
summing the source brightness times the cosine.
4.4
Tomosim - simulate tomographic X-ray source
CONVERSION TO LATEX NOT FINISHED
This program is used to simulate a 3-D beam tomographic sensor. Either cone-beam or
parallel- beam sensors may be simulated. An ifs 3D image is used as input (as produced,
for example, by 3dsyn). The program produces a set of ifs 2D images, where each of the
output images corresponds to one projection USAGE:
tomosim inputimage numofpoints radius detector rows detector cols¡-o¿ ¡-d n¿ IFSIMG
input image; int numofpoints; /*center int radius; /*three dimensional*/ /*The number
of points around a 360 degree circle,*/ /*centered at the*/ of the volume specified by
the input image*/ /*The distance (in voxels) from the center of the*/ /*volume to the
detector. Will be treated as*/ /*identical as the distance from the */ /*center of the
volume to the center of the detector array*/ int detector rows; /*number of rows on the
detector*/ int detector cols; /*number of columns on the detector*/ The names of the
output files are read from stdin as they are needed. Since the program may take quite a
while to run, manually typing these names is tedious. The recommended way to run the
program is to first create a file containing the names of all the output image files, and then
to run tomosim redirecting stdin to this file. Switches -o The -o switch, if used, will use
parallel-beam (orthographic) rather than cone beam projection -d The -d switch, if used,
means that the next argument will be the debug control value (really only of interest to the
programmer) Application: For cone beam, just specify the number of points. The sensor
rotates in x-y plane, about an origin at the center of the 3D volume provided. For fan
beam, simply specify a detector with only one row. The -o switch provides parallel beam
simulation in either single row or multiple row cases.
Chapter 5
Programs for processing images
The following is a list of programs which exist in the ifs bin directory. (Depending of
local installations, this is usually /usr/local/bin/ifs) These programs are for the most part,
simply mains wrapped around some of the standard subroutines documented in earlier
chapters. These programs are only documented briefly here, since the operation is generally
obvious.
Generally, on-line help for any program can be obtained by simply starting that program
up, but providing it an incorrect number of arguments. Most programs also support the -h
switch. For example, add -h will tell you how to use add. Most programs us the -x switch
convention. For example,
program -i infilename -o outfilename
5.1
add
add two ifs images, point by point Author: Wes Snyder
5.2
addhdr
adds an IFS header to a raw data file. rmvhdr is the reverse function. Perpetrator: Mark
Lanzo
5.3
atoi
Converts an ascii file to ifs. Input file is to be in the format produced by itoa using the -v
switch. The -v switch on itoa adds two lines at the beginning of the file which specifies the
135
136
CHAPTER 5. PROGRAMS FOR PROCESSING IMAGES
size and data type. Author: Wesley Snyder
example:
Image has 4 rows and 4 columns
Data format is u8bit
0 0 0 0
0 1 0 0
0 0 2 0
0 0 0 0
/end{verbatim}
Usage:
\begin{verbatim}
atoi imga.txt imga.ifs
Note this program does not use the -i -o convention.
5.4
any2any
convert data types
Converts any IFS image to or from (almost) any other data format including other ifs data
types
usage: any2any [switches]
-i inputfile.ifs
-o outputfile.xxx
-d datatype
switches are
datatype is an ifs data type, such as byte, ubyte, char, uchar, u8bit, short, ushort, u16bit,
int, float 32flt, double, 64flt, etc. For other file types, such as bmp, jpg, png, etc, the type
is determined by the file name. If outfile is not ifs, dtype IS required to be uchar, (for this
version), even if neither in nor out is ifs.
Examples:
convert an ifs image of some unspecified data type to an ifs image of type float
any2any -i startrack.ifs -o startrackfloat.ifs -d float
convert an ifs image of unspecified data type to png. Note that this may not work if the
input if 3-D.
any2any -i startrack.ifs -o startrack.png -d uchar
convert a jpeg input image to a float ifs image.
any2any -i lena.jpg -o lenafloat.ifs -d float
5.5. C2IMAG
5.5
137
c2imag
take imaginary part of an ifs image, point by point Author: Wesley Snyder
5.6
c2mag
take magnitude of an ifs image, point by point Author: Wesley Snyder
5.7
c2phase
take phase of an ifs image, point by point Author: Wesley Snyder
5.8
c2real
take real part of an ifs image, point by point Author: Wesley Snyder
5.9
compmag
produces an ifs file (type float) equal to the log of the square of the magnitude of a complex
image Victim: Wesley Snyder
5.10
ChooseFrame
Select a single frame from an image. This is particularly useful for images which have been
read as color (say, JPEG) and you wish to store a single frame of the RGB image.
ChooseFrame -i inputimage -o outputimage -f framenumber
The default frame number is zero.
5.11
gauss add Gaussian-distributed noise to an image
Switches:
-i inputfilename
-o outputfilename
-m mean
-s stddev
-n (no argument) - don’t allow negative values for noise
-w (no argument) -don’t allow overflows (wrap arounds) e.g. adding a value of 3 to an 8bit
138
CHAPTER 5. PROGRAMS FOR PROCESSING IMAGES
pixel with value of 254 will produce a pixel with value of 1
-S IntegerSeedForRandomNumGen (normally dont use this)
5.12
ifsDoG Apply a derivative of Gaussian kernel to an ifs
image
usage: ifsDoG [switches]
switchs are
-i infilenname, where infilename is an ifs image default: the null string
-o outfilenname, where outfilename is an ifs image default: the null string
-s sigma, std. dev of the filtering Gaussian default: sqrt of 3.0
-O order of the derivative zero is blur with the Gaussian, one is first deriv, etc, up to 3rd
deriv direction.
-d This flag is the letter c for col, r for row, b for both default: columns
b option only valid for second deriv
example: ifsDoG -i myfile.ifs -o outfile.ifs -O 0 -d r
5.13
itoa
converts an image to printable ASCII. The output is written to the terminal. Output can
be redirected to a file using the Unix redirect command.
Examples:
1) to output an image to the screen:
itoa site14.c.ifs
2) to ouptut an image to a file
itoa site14.c.ifs > site14.c.txt
3) to output an image to a file with a prefix specifying the rows, columns, and data type
itoa -v site14.c.ifs
If the -v switch is used the first two lines output will look like this:
Image has 48 rows and 32 columns
Data format is 16bit
Author: Mark Lanzo
5.14. MKDOC
5.14
139
mkdoc
makes a LaTeX compatible version of this index on standard out. Author: Wesley Snyder
5.15
mult
multiply two ifs images, point by point Author: Wesley Snyder
5.16
profile
Take a cross section of an IFS 2D image. Output is in standard plot filter format (to
stdout). Author: Mark Lanzo
5.17
prthdr
Print the header structure for an IFS image (in human readable format). Author: Mark
Lanzo
5.18
rmvhdr
Remove the header from an IFS image to yield a raw data file. Author: Mark Lanzo
5.19
subsample
subsamples an arbitrary ifs image to be of a speci ed size: Author: Wesley Snyder
5.20
recip
take reciprocal of an ifs image, point by point Author: Wesley Snyder
5.21
sub
subtract two ifs images, point by point Author: Wesley Snyder
140
5.22
CHAPTER 5. PROGRAMS FOR PROCESSING IMAGES
triangulate
Find an optimal set of triangles which completely covers a set of points.
Usage:
triangulate inputimage outputimage
(Note that this program, at this time, does not use the standard -i, -o designation for
arguments. Therefore, the order of the arguments IS important.) This program accepts an
input file, a standard text file, which contains the set of row, column coordinates of vertex
points. The output file will contain descriptions of triangles which cover that set of points.
5.22.1
Input File Format
First line, the number of vertices
all other lines, row, column pair
example:
4
0
1
1
0
0
0
10
10
5.22.2
Output File Format
First line: number of triangles found.
all other lines, row, col coordinates of the vertices in this triangle
example:
2
0 10 0 0 1 0
1 0 1 10 0 10
5.23
vidscale
video scale an ifs image, that is, produce an output image which is the same size as the
input image, but scaled to be between 0 and 255, and be unsigned char.
vidscale -i infile.ifs -o outfileu8bit.ifs -s
5.24. WINDOW
5.24
141
window
This program extracts a window from an ifs image. The resultant output image is of the
same data type as the input.
Usage:
window input output xleft ylower xright yupper
input and output are two dimensional ifs image files. Output will be created by this
program. xleft is the index of the left-most column of the input image which should be in
the window. ylower is the index of the lowest-index row of the desired window. xright and
yupper are the other extremes. NOTE: yupper must be greater than ylower. Thus, upper
and lower correspond to indices, not to a top-bottom relation on a display screen. Author:
Wesley Snyder
5.25
zoomupdown
This is a program which is really just a wrapper called the iptools function by the same
name.
Usage: zoomupdown inputimage outputimage numrowsofOutputImage numcolsofOutputImage
Program will read the input image and will create an output image with the specified
number of rows and columns. Then the input image will be resized to be of the specified
number of dimensions. No interpolation is done across frames, in the case of 3D images.
If you need to do that, use squp. If the input image is 3D, and has 3 frames, it will be
treated as if it were color.
142
CHAPTER 5. PROGRAMS FOR PROCESSING IMAGES
Chapter 6
Programs for Analyzing Images
In this section, programs are provided which do image analysis.
6.1
Harris-Laplace
This program reads an image file and computes the output of the Harris corner detector
over scale, and applies a Laplacian over the same range of scales.
Usage:
HarrisLaplace [switches]
Switches are:
-i inputfilename
-H Harris measure out. Default: HarrisMeasure.ifs
-L Laplace measure out. Default: LaplaceMeasure.ifs
The output images are ifs 3D images, data type of these images is float.
6.2
PCON - Piecewise-constant image noise removal
This program does Edge-preserving smoothing and noise removal using a piecewise-constant
prior.
USAGE:
pcon [switches] .
Switchs are -g input filenname, where infilename is an ifs image; default: the null string
-s sigma The std dev of the noise. default: 1.0
-r r step size, smaller is more stable but slower. default: 0.02
143
144
CHAPTER 6. PROGRAMS FOR ANALYZING IMAGES
-b b The coefficient in front of the prior term. Beta of Eq. 6.41 in Snyder and Qi
-t t1 initial temperature. default: 2.0
-T t2 final temperature default: 0.0005
-l dlt rate by which the temperature drops. default: 0.99
-o outcount output a temporary file every this many iterations. default: 50
example: pcon -g foofile.ifs -s 3
SEE Snyder and Qi, Machine Vision, Cambridge University Press, 2005, Equation 6.41.
This program works by finding the image f which minimizes
X (fij − gij )2
−|∇|ij
bX
−
(6.1)
exp
2σ 2
τ
2τ 2
ij
ij
where g is a measured image, σ is the standard deviation of the noise, and the notation
|∇fij | denotes some scalar measure of the image gradient in the vicinity of pixel ij. There
are five parameters to this program:
• sigma which is the standard deviation of the (assumed additive, Gaussian, white)
noise.
• b, the strength of the second term, relative to the first. The second term is called the
“prior” term, since it is a function of only the (unknown) true imagef and not of the
measured, noisy image g.
• τinitial is the initial value of τ . In most literature, the variable τ is called the temperature because the algorithm bears similarity to the process of annealing in metallurgy.
The algorithm implemented in pcon is an approximation to simulated annealing,
called “mean-field annealing.” The optimal value of τiniital is problem dependent,
but a good approximation can be found by performing the following analysis: Find
the largest pixel-to-adjacent-pixel difference which should be considered noise and
not an edge. Set τiniital to twice that value.
• τf inal is the final of τ at which the algorithm will stop. I suggest you allow the
temperature difference be two-to-four orders of magnitude. E.g., if τinitial is 10.0,
τf inal should be something like 0.01.
• λ is the rate of decrease of temperature. The program uses a geometric annealing
schedule (as opposed to a logarithmic schedule) following τ = λτ . A good value is
typically 0.99. Values closer to one (e.g. 0.999) will run slower but give better results.
Example:6.1 illustrates a noisy image, a cardiac angiogram, to which pcon is applied to
produce figure 6.2. Notice that some bright points are preserved. These are points where
the random noise was sufficient to make the pixel-to-pixel difference significantly larger
than τinitial , therefore these points are considered by the algorithm to be edges and are
6.2. PCON - PIECEWISE-CONSTANT IMAGE NOISE REMOVAL
Figure 6.1: Input image
Figure 6.2: Piecewise-constant image
145
146
CHAPTER 6. PROGRAMS FOR ANALYZING IMAGES
Figure 6.3: Profile across an artery, showing the piecewise-constant property of the solution
not removed. The profile illustrated in Figure 6.2 across one of the arteries in the output
shows the piecewise- constant result.
The implementation of PCON is optimized for speed, using pointer arithmetic and
other programming hacks.
6.3
PLIN - Piecewise-linear image noise removal
This program does Edge-preserving smoothing and noise removal using a piecewise-linear
prior.
USAGE:
plin -i infile [-s sigma] [-r stepsize] [-b priorgain] [-t initialtemp]
[-T finaltemp] [-l dlt] [-o n]
Once the program is running, it will prompt the user for control variables, these are listed
below, along with good values to use
sigma: The std dev of the noise. default 1.0
r,step size, smaller is more stable but slower. default is 0.02
b, The coefficient in front of the prior term. Beta of Eq. 6.41 in Snyder and Qi,
good value is .5
t,
initial temperature. default
2.0
6.3. PLIN - PIECEWISE-LINEAR IMAGE NOISE REMOVAL
147
t2, final temperature default 0.005
lambda: rate by which the temperature drops. good value : 0.99
n: used with the -o switch. The program will output a temporary
image every n iterations
example: plin -i G
SEE Snyder and Qi, Machine Vision, Cambridge University Press, 2005, Equation 6.41.
This program works by finding the image f which minimizes
X (fij − gij )2
−|∇2 |ij
bX
−
exp
2σ 2
τ
2τ 2
ij
(6.2)
ij
where g is a measured image, σ is the standard deviation of the noise, and the notation
|∇fij | denotes some scalar measure of the image gradient in the vicinity of pixel ij. There
are six parameters to this program:
• sigma which is the standard deviation of the (assumed additive, Gaussian, white)
noise.
• r, The step size of the gradient descent term.
• b, the strength of the second term, relative to the first. The second term is called the
“prior” term, since it is a function of only the (unknown) true imagef and not of the
measured, noisy image g.
• τinitial is the initial value of τ . In most literature, the variable τ is called the temperature because the algorithm bears similarity to the process of annealing in metallurgy.
The algorithm implemented in pcon is an approximation to simulated annealing,
called “mean-field annealing.” The optimal value of τiniital is problem dependent,
but a good approximation can be found by performing the following analysis: Find
the largest pixel-to-adjacent-pixel difference which should be considered noise and
not an edge. Set τiniital to twice that value.
• τf inal is the final of τ at which the algorithm will stop. I suggest you allow the
temperature difference be two-to-four orders of magnitude. E.g., if τinitial is 10.0,
τf inal should be something like 0.01.
• λ is the rate of decrease of temperature. The program uses a geometric annealing
schedule (as opposed to a logarithmic schedule) following τ = λτ . A good value is
typically 0.99. Values closer to one (e.g. 0.999) will run slower but give better results.
148
CHAPTER 6. PROGRAMS FOR ANALYZING IMAGES
Figure 6.4: Piecewise-linear image
Example:6.1 illustrates a noisy image, a cardiac angiogram, to which plin is applied to
produce figure 6.4. Notice that some bright points are preserved. These are points where
the random noise was sufficient to make the pixel-to-pixel difference significantly larger
than τinitial , therefore these points are considered by the algorithm to be edges and are
not removed. The profile illustrated in Figure 6.5 across one of the arteries in the output
shows the piecewise- linear result.
The implementation of PLIN is optimized for speed, using pointer arithmetic and other
programming hacks.
6.4
WaterSheds
The program WaterShed is a wrapper around the function ifs WaterShed, allowing the
function to be called from the command line. In addition, the user may select several
post-processing features.
Usage:
WaterShed -i infilename -o outfilename -c connectedtype [-C filename] [-n filename]
outfile will contain watershed points
-c is connection type, either 4-connected or 8-connected.
-C file will be in color
-n file will not have watershed points
6.5. CCL CONNECTED-COMPONENT LABELING
149
Figure 6.5: Profile across an artery, showing the piecewise-linear property of the solution
The input image must be unsigned char ifs image.
The output image will be int.
The program first finds all minima in the image and assigns each a label. Those labels
become the labels of regtions.
Figure 6.6 illustrates an image, with a surround which is minimal, a brightness which
grows positive and then drops in two places (a volcano with a vent). Figure ?? shows
the watershed output, illustrating the presence of watershed pixels. Figure 6.7 illustrates
a labeling with all the watershed pixels assigned to regions, and Figure ?? shows a color
labeling of that image.
6.5
ccl Connected-component Labeling
This program uniquely labels the connected components of an ifs image. It uses the algorithm described in Snyder and Qi, Machine Vision, Cambridge University Press, 2005.
This program only supports images in the following data types: unsigned char, short,
and float. Switches:
-h : print out this message
-i <input_image_file_name>
-o <output_image_file_name> This will be the label image, in which is stored at each pixel
-p <parameter_file_name> (optional)
-l <lower limit for labeling region> (default 0) Normally this is the background
-u <upper limit for labeling region> (default 255)
-[f|e|v] : use face/edge/vertex connectivity (default face)
150
CHAPTER 6. PROGRAMS FOR ANALYZING IMAGES
Figure 6.6: Left:Original image (Volcano with a vent and a zero surround) Right: watershed
segmentation showing watershed pixels
Figure 6.7: Left:Region Labeling with watershed pixels assigned to regions. Right: Region
Labeling in pseudocolor, using a random color map
6.6. RESAMPLE CURVE
151
-t <threshold for connectivity>
(two pixels which differ by more than this will not be merged-(default 2)
-s <row> <column> <frame> (Seed Location of Region of Interest)
Normally, ROIs are not used. -r <label of ROI> (default 1)
-g : outimg is ROI_seg_out image (default label image)
-j <pixel value for ROI_seg\_out image > (default 128)
-a <upper background label> (default 0)
-b <lower background label> (default 0)
-m <minimum label used> (default 0)
-x <maximum label used> (default 32767)
-c <Size of the content-addressable memory used to resolve
equivalent region labels.> (default 4096)
ccl is a wrapper around the function ifs ccl. It parses the command line, fills in the structure
used by ifs ccl, initializes some things, and then calls ifs ccl. If you need to call connected
components from inside a program, see the description of the function ifs ccl. See the
documentation for ifs ccl for additional documentation, including figure 3.1 which defines
the types of connectivity.
6.6
resample curve
The program resample is simply a wrapper for resampleinit and resamplesub. See section
3.1.6. It resamples a discrete curve and returns a set of points equally far apart (arc-length
sampling).
usage:
resample -i infile -o outimage -n numpoints
inputfile is an ascii file of x-y pairs.
the first line is a sharp sign, a space, and the number of pairs, e.g. # 798
The output file will be written in the same format, but the numbers will be float
152
CHAPTER 6. PROGRAMS FOR ANALYZING IMAGES
Chapter 7
Programs for Viewing IFS images
7.1
ColorMap
The program ColorMap allows you to assign a number of different colors to an 8-bit,
unsigned image. That is, each of the possible 256 brightness levels will be assigned a color.
There are many ways to assign an R, G, and B value to a single pixel brightness. The
program offers several different ways to interpret the brightnesses.
Usage:
ColorMap -i inputfile.ifs -o outputfile.ifs -m X -f Y
Where inputfile is an ifs image. and X is an integer between 0 and 6 which tells the program
which color map to use:
0 grey scale
1 inverse gray scale
2 bronson
3 hot metal
4 heated spectrum
5 log
6 random
The input image may be any ifs format, however, if it is not unsigned 8 bit, the user will
get a warning message that only brightnesses between 0 and 255 will be mapped. If the user
has this problem, he or she should probably use vidscale to convert the darkest-brightest
values to 0-255.
Should the input file be 3D, the program will convert frame 0 by default. Using the -f
switch, the frame to be converted can be selected.
The output file will the 3 D ifs image, with 3 frames, with the usual interpretation that
frame 0 is red, frame 1 is green, and frame 2 is blue.
153
154
7.2
CHAPTER 7. PROGRAMS FOR VIEWING IFS IMAGES
Eigenimages
Program to find the principal eigenimage of a set of images.
The program will optionally also calculate the projection of another image onto the principal eigenimage.
Usage:
Eigenimage -c controlfile -o outfile [-t projfile]
The control file contains a single number (number of files followed by a list of file names,
one per line.
Example:
2
file1.ifs
file2.ifs
file3.ifs
The output file is an ifs image of the principal eigenimage.
The -t switch allows the user to specify the name of a file to project onto the eigenimage,
and measure the length of the projection
All images must have the same dimensions.
7.3
ifsview – view ifs images
This is a new program with ifs release 8. It supercedes wxifsview, which may still run on
some computers.
The application ifsview provides the ability to view, zoom, or probe ifs images. It uses
the openCV software system. To run ifsview, use the following command:
ifsview -i image [-c] [-I ignoreswitch] [-s]
image is the input image. image can be any format of ifs, or jpg, tiff, bmp, and png. If ifs,
it can be monochromatic or color. If monochromatic, it may have two or three dimensions.
colorswitch The optional color switch, if it exists, tells ifsview that if the input image
happens to be three dimensional and have three frames, it should be displayed as a color
image, rather than a 3D image.
ignoreswitch If this brightness is entered, then any pixels of this value will not enter the
calculation of contrast.
-s If the -s switch is present, frames in a 3D image with be brightness-scaled independently.
Otherwise, the brightest and darkest points in the entire image will be used for scaling.
Once you have started up ifsview, you have a variety of options:
7.3. IFSVIEW – VIEW IFS IMAGES
155
• LOUPE As soon as the image pops up, and you move the mouse over it, another
image will pop up which is a zoomed version of the original image, zoomed about
where the mouse is. We will refer to this second image as the “loupe” image, as in a
jewler’s loupe. As you move the mouse, the second image will move around also.
• stopping the tracking A right click on the original image will freeze the loupe image. A
second right click will turn tracking back on. On the mac, a right click is accomplished
by hitting the trackpad with two fingers simultaneously.
• Additional zoom With the pointer on the original image, you can use right and left
arrow keys to increase or decrease zooming (respectively). Note that you will not see
the result of the zoom until you move the mouse again, which will refresh the loupe
image.
• Image values – original image Clicking on the original image will return the brightness
at the point of the click, or if color, will return the R,G,B values.
• Image values – loupe image To look at points in great detail, first move the mouse
to get to where you want to be in the original image. Then right click to turn off
tracking. Move the pointer to the loupe image, and click on any point. The brightness
or color of that point will be returned.
• Exploring 3D images With the mouse on the original image (tracking can be on or
off), the up and down arrow will display different frames of the 3D image. Remember
that these values don’t show up in the loupe image until you move the mouse. On
some computers, the arrow keys don’t work with this application. As an alternative
to the arrow keys, you can use
m
i
j
k
c
control-c
L
l
frame up
frame down
zoom down
zoom up
toggle contrast enhancement on/off
exit program
increase size of loupe image
decrease size of loupe image
• Contrast enhancement The lower-case c key will toggle contrast enhancement of the
loupe image on and off.
Should you simply wish to display an image and obtain information about it, use the
program ifsview, which is just a wrapper around ifsCVPopup, and that way, you won’t
need to mess with linking openCV, which can be a painful hassle.
IMPORTANT NOTE ABOUT ifsview:
156
CHAPTER 7. PROGRAMS FOR VIEWING IFS IMAGES
ifsview uses the openCV functions. OpenCV supports ONLY dynamic libraries. This
means you must either have openCV installed on your computer, or you must have the
openCV libraries available, even though you actually aren’t writing any software that will
use them. We tried (unsuccessfully) to get openCV to generate static libraries so it would
be portable, but we failed, and learned from web conversations that it does not seem to be
possible. The openCV libraries are in the ifslib that you downloaded.
7.4
makecolor
This program accepts a 2D ifsimage as input and produces a jpg, png, or other output.
This is necessary because ifs uses openCV to convert images from ifs to other format.
openCV thinks all jpg, png, etc. images are color, so if you give it an input which is a 2D
image, it will fail, producing an output which is not readable.
Usage: example:
makecolor -i input.ifs -o output.ifs
7.5
PlayMovie- play a 3D ifs image as a movie
Plays a 3d ifs image as a movie
Usage:PlayMovie [arguments]
switches are
-i inputfile.ifs
-z floating point zoom factor. Will zoom image prior to playing. Default: 1.0
-h this usage
-s time (in microseconds) to delay between frames (minimum 1, max 999999). If the
argument of the -s switch is greater than 1,000,000, the program will wait for the user to
hit a key before going to the next frame.
-d direction if direction is 0, the movie will be played forward, if 1, backward, if 2 forward
then back.
This program is just a wrapper around CreateIFSDisplayWindow and WriteToIFSDisplayWindow. It plays a 3D image as a movie with controllable zoom and speed. IMPORTANT NOTE ABOUT PlayMovie:
PlayMovie uses the openCV functions. OpenCV supports ONLY dynamic libraries.
This means you must either have openCV installed on your computer, or you must have
the openCV libraries available, even though you actually aren’t writing any software that
will use them. We tried (unsuccessfully) to get openCV to generate static libraries so it
would be portable, but we failed, and learned from web conversations that it does not seem
to be possible. The openCV libraries are in the ifslib that you downloaded.
7.6. PLOTCONTOUR
7.6
157
Plotcontour
Plotcontour: a program which will plot a 1D contour into an ifs image. The contour will
be white on a black background. usage:
plotcontour -i infile -o outimage -s scale
-r imagerows -c imagecols
infile is an ascii file of x,y point pairs, the first line of which is sharp sign, space,
number of points
e.g. # 799
On each following line, the format is ”x y”
Normally, x is columns and y is rows
example:
# 4
0 200
200 0
0 0
200 200
the outimage file is the name of an ifs file containing white dots on a black background
optional argument scale will multiply x and y coords by scale
optional arguments imagerows, imagecols will force the image output to be that size.
Note that if the points go off the image, they will be clipped.
the -p switch will write precisely the coordinates specified in the file.
7.7
C2LaTeX-convert source code to LaTeX
This program allows the user to include his/her source code into a LaTeX document. Any
line which starts with
//l(the ell character)
will not only be a comment to C or C++, but allows the user to include any LaTeX command at all. (Well, almost any). The exception is you may not include the string
\end{verbatim}
You may of course, use the \textbackslash with no problem. You might also consider
using the listing environment rather than the verbatim environment.
Usage:
C2LaTeX -i inputfile.c -o outputfile.tex -m ValueOrFilename
158
CHAPTER 7. PROGRAMS FOR VIEWING IFS IMAGES
if the -m switch as a value of zero: (e.g. below)
C2LaTeX -i inputfile.c -o outputfile.tex -m 0
Then the output LaTeX file will not contain a header (the stuff before the \begin{document})
or the \end{document} . This is particularly useful if you intend to include or input this
LaTeX file into another file.
If it is to be stand-alone, the -m switch should specify the name of the header file you
want the program to use, e.g.:
C2LaTeX -i inputfile.c -o outputfile.tex -m myheader.tex