RGBcal and DyEye are tools for analyzing RGB (Red-Green-Blue) color images on DOS-based microcomputers. Their purpose is to transform an RGB image via some equation into quantitative information. This information can be boolean, denoting the presence or absence of some characteristic (e.g., plant versus soil; see Ewing and Horton, 1998a), or it may be continuous (e.g., the concentration of dye on the soil surface; see Ewing and Horton, 1998b). RGBcal is used to develop and calibrate the transforming relationship, and DyEye is used to effect the transformation. Both programs work with uncompressed TIFF (tag image file format) files, a common raster image file format recognized by most scanners, digital cameras, image editing programs, and even many word processors. TIFF files with full RGB information are also called 24-bit TIFF, or (sometimes) True Color. The programs were designed to be used on small DOS-based computers, but are capable of working with quite large image files. The programs and portions of the source code are in the public domain. The programs were originally developed with agronomic applications in mind, as reflected in the examples, but they are in no way restricted to that field.
RGBcal and DyEye were written in Pascal and compiled using Turbo Pascal 7.0 (copyright © 1983, 1992 Borland International, Inc., Scotts Valley, CA). Portions of the program copyright © 1983, 1987, 1989, 1992 Borland International, Inc., all rights reserved. The graphics driver distributed with the program is copyright © 1991, 1993, Knight Software. The program author, Borland International, Inc., and Iowa State University (ISU) are not liable for any aspect of these programs, nor do they guarantee their functionality or accuracy. Mention of a specific product in this manual does not imply endorsement by ISU, nor criticism of similar products not mentioned.
The programs require an DOS machine with approximately 512K of available RAM and the DOS operating system (version 2.11 or greater). The executable files were optimized for 80286 and later microprocessors with a math coprocessor (required). A graphics display (SVGA, 1024 x 768 x 256 colors, hence 1 MB vRAM) is required: if your display is not up to this level, the program will run, but you won't see what it is doing, so interacting with the program will be difficult!
The design philosophy behind these programs is simply that processing of large images should not be limited to huge power-hungry computers, but should be available to lowly DOS machines as well. Of course, this idealism comes at a cost: a bigger machine may read in an image once and hold several copies of it (at different stages of processing) in memory, allowing it to perform operations almost instantaneously. These programs will need to read the image in many times, and will hold only a few lines in memory at any given moment. The need to read the image many times slows the processing (although using a disk cache alleviates much of this problem), and holding only a few lines in memory limits DyEye to only one filter operation per image. Within these constraints, the programs can handle larger images than many programs much more powerful (and expensive). Because the programs only hold a few lines at a time, files of several megabytes in size can be processed. The TIFF specification limits both image width and length to 65536 pixels, but these programs are theoretically limited to widths of approximately 16,380 pixels. The actual width they can handle will change depending on how many files you use for calibration (in RGBcal), and how many color parameters your equation has and how large your mask processor is (in DyEye).
If your computer tells you there is not enough memory to run the program then you may need to close your graphical interface and run in DOS without TSRs or other memory resident programs loaded. I have not encountered any problems running these programs under a graphical interface in a full-screen DOS box (with no background jobs). If your graphical interface requires a .PIF file, you should run in full-screen mode and allocate memory for high-resolution graphics. I also recommend that you not have the window close automatically upon exit.
To run RGBcal and DyEye, you'll need the
following files:
DYEYE.EXE BGI256.BGI MANUAL.TXT, or MANUAL.WP5, or MANUAL.HTML |
The RGBcal executable The DyEye executable The graphics driver (small) This manual, text version, or This manual, WP 5.1 format, or This manual, HTML version. |
RGBGRAPH.PAS NONLIN.PAS DYEYE.PAS DYGRAPH.PAS INTFACE2.TPU INTFACE2.INT |
The RGBcal main program file RGBcal graphics & other routines The nonlinear curve-fitting code The DyEye main program file DyEye graphics & other routines The interface unit (compiled) The interface to the interface unit (!) |
The programs are started from the DOS prompt in their home directory (e.g. c:\color) by entering the command RGBcal (or DyEye). The opening screen will show a window with program information (title, version and date), and a menu bar at the top. Menu selections can be made by entering the first letter of the command, or by using the left and right arrow keys to move from one menu entry to another and then hitting the <Enter> key when the desired menu entry is highlighted. Each of the menu entries can be exited at any time using the <ESC> key. The program can be exited at any time by hitting <alt-x>. The programs do not recognize a pointing device such as a mouse.
Within the dialog boxes of each menu entry the up and down arrow keys, or the left and right tab key, are used to move from one box to another. The space key (or alternatively the right arrow key) is used to mark or to "toggle" choices. In some boxes a numerical entry or filename is required, and here normal editing keys, such as the home, end, insert, and delete keys, have their normal functions. If the current setting is desired the <Enter> key is pressed or the arrow keys can used to bypass the box. Pressing <Enter> when an "OK" box is highlighted will close the dialog window and your choices will be kept. Pressing <ESC> anywhere in a dialog window will close the window, and the previous selections will be kept. Within graphical dialogs, boxes along the left edge of the screen are selected by entering the first letter of the box (e.g., "F" for the File box), and other graphical windows are available by pressing the first letter of their menu selection. For example, in DyEye's Zoom menu, you can get to the Enhance menu just by pressing "E". Within each graphical box, only certain keystrokes are recognized.
RGBcal is a tool for developing a calibration equation relating color parameters (e.g., red, hue) to some independent parameter of interest (e.g., dye concentration, nitrogen status of a crop). A useful calibration equation will be based on those color parameters that change most clearly and unambiguously as the independent parameter changes, so correlation and visualization tools are included in RGBcal. The equation is developed and its parameters optimized using RGBcal's nonlinear regression package. Sometimes it is useful to output an image in data format (for example, for export to a more advanced statistical package), so RGBcal can also do that. The equation and related information from RGBcal is put into a small file (DYEYE.CFG) which is read by DyEye upon startup.
RGBcal takes as input up to 1024 calibration images. Each file should correspond to a known value of the independent parameter. In our work, we construct these files using the software that came with our color scanner -- any TIFF editor will do. We find areas in our (big) calibration image(s) that correspond to known values (such as known dye concentrations), select and copy them, then paste them into a new file, which we save in uncompressed TIFF RGB format.
If the objective is to segment images according to some relationship rather than to obtain continuous quantitative data, then many files may not be needed. If RGBcal is given only a single file, it will notify you that it cannot perform regression, but the other tools -- correlation, color space visualization, and output -- will work.
Implicit in the very concept of these programs is the idea of consistency. All the images must be acquired and processed the same way if color is to be interpreted as consistent values. For example, if you are separating on the basis of red, illumination differences can wreak havoc with your results: perhaps redness (red / intensity) would be safer. If you have been using direct sunlight, and you supplement it with fluorescent or even incandescent lighting on a foggy day, recalibrate. If you have been acquiring images using a 35mm camera and you change to a digital camera, or if you change film speed or paper gloss, recalibrate. Be especially careful about automatic corrections that are built into many photographic processes: cameras, automated film development systems, and scanners often compensate automatically for low contrast and high or low light levels.
Once you have the files you want selected, hit the OK button. The program will prompt for a parameter value corresponding to each file. The program then performs and optionally displays some basic statistics. (Display of the statistics is controlled in the Setup menu.) One of the statistics is the total number of pixels summed across all the files. This may not be the number you expect, because white and black pixels are ignored during this counting. The reason for ignoring white and black pixels is that the calibration files are generally produced by copying and pasting from other programs (see above), and oftentimes the copied region doesn't exactly match the size of the new file -- in which case the remainder is filled in with blank spaces, typically white or black. As a safeguard, RGBcal automatically interprets black and white pixels as blanks.
If the program crashed while in the Regress menu, it will have left a file telling it what files it used and what independent parameters correspond to them, and it will load this information upon starting up. You can also create files like this, and do repeated analyses without having to select files and manually enter independent parameter values for each file. The file format and some operational instructions are given in Appendix C.
Correlation:
The Correlation menu produces a correlation matrix
showing correlation between the following variables: red ("R"), green
("G"), blue ("B"), hue ("H"), saturation ("S"), intensity ("I"),
principal components one ("1"), two ("2"), and three ("3"), angle ("A":
the angle between the principal component one axis, and the line
connecting the principal component origin to the projection of a point
onto the principal component one/principal component two plane), and
the independent parameter ("P": e.g., dye concentration). This can be
useful as an initial screening tool: if a color parameter is not at all
correlated with the independent parameter, it can subsequently be
ignored. The converse is not necessarily true: a color parameter may be
strongly correlated with the independent parameter, but be useless as a
predictive parameter due to, for example, wide scatter or low slope in
the specific region of interest . The correlation table also serves to
confirm whether the principal components are as expected: typically,
principal component one correlates strongly with intensity, and hue
correlates somewhat well with angle. Because of the large number of
multiplications involved, this menu item is generally slow to execute.
The View menu has several options, not all of which are obvious from a perusal of the screen. The View submenu allows you to choose between various color spaces. The first two are in Hue-Saturation-Intensity (HSI) space, the next two are in PC space, and the last six are different views of RGB space. In each color space, you have the option of using color to denote the third color dimension, or the value of the independent parameter ( "P"). Selecting the View entry with an uppercase V toggles between cylindrical and biconical coordinates in HSI space (this takes effect at the next redisplay).
The Palettes submenu lets you rotate between 5 different palettes (a color wheel, a "linearized" color wheel, a warm palette, a broken palette, and a grey palette), and their inverses. Selecting the Palette entry with an uppercase P toggles between displays that have white lines on a black background (the default), and black lines on a white background, and will take effect on the next palette change. You can also load your own palette to replace the grey palette 5: for more on this see the Setup menu below.
Selecting the File submenu outputs a large (approximately 500kB) palette-color TIFF file that is a "snapshot" of the left portion of the screen. This snapshot is output as-is, so use the options to help you compose your shot carefully. The output file is named RGBCAL.TIF, and it overwrites any existing file of that name: if you want to produce multiple files, you will have to rename them between file outputs. The RGBCAL.TIF can be imported for printing by many word processing programs.
Selecting Means will toggle between displaying all points, and displaying means by file (i.e., one point per file). Selecting this entry with an uppercase M increases the size of the individual points, from one to five pixels square, then back to one again.
Selecting the Hue zero allows you to adjust the hue offset. This is useful because, by definition, a hue of zero corresponds to red, but for a given analysis it may be useful to have zero hue be some other color (for example, a hue offset of 4/3 would change zero hue to blue). The arrow keys move the circle showing the current hue offset in 1.5° increments. If you then hit the <ENTER> key and return to the main menu, any change in the hue offset will be kept (likewise, hitting the <ESC> key leaves the previous value unchanged). Selecting this entry with an uppercase H toggles the display of the hue offset line. The Hue offset you select will be automatically added to the Hue during subsequent calculations, including those in the nonlinear optimizer, so this is an extra, non-optimized parameter you get to use when you use hue in an equation.
Regress:
The Regress menu opens a nonlinear regression
package. Here you can type in an equation with up to three fitting
parameters and all ten color parameters. When developing your equation,
it can be useful to see the relationship between the independent
parameter and the color parameters. Before you run the regression, you
can view these relationships by hitting the "Residuals" button. RGBcal
will display a plot of the independent parameter as a function of the
first color parameter (Red). The left and right arrow keys will let you
page to similar graphs for the other color parameters. After entering
an equation and giving initial values for the fitted parameters, select
"regress" and the nonlinear curve fitter will be invoked. The optimizer
will run until it either converges (finds no effective difference
between two successive iterations), or has iterated 500 times. At this
point, the program displays some summary statistics, and you can view a
plot of the residuals. Ewing and Horton (1998) obtained better
predictions from regressions based on file means than from regressions
based on the entire data set. RGBcal performs regression only on image
file means.
Remember to prefix the color parameters with an 'X', thus red is XR, hue is XH, and so on. This is needed to distinguish between the numeral 1 and principal component one, between A for angle and A the fitting parameter, and between B for Blue and B the fitting parameter. Besides addition, subtraction, multiplication, division, and exponentiation, the equation parser recognizes pi and e, and can handle exp, ln, log (base 10 logarithm), abs, sqrt, sqr (square), sin, cos, tan), acos (arccosine), and atan (arctangent). There are a few things you can do to speed up the equation parser. Use exp(x) rather then e^x: the first is translated directly into a function, but the second is parsed and performed as two operations. Likewise, square numbers by using sqr(x) rather than x^2. Use the constants A-C, rather than inputting numbers longhand, even if the number is only one digit (unless you've run out of parameters!). These changes may not result in a discernable speed difference in RGBcal, where you are running at most 1024 points through the parser, but the same equation format and parser is used by DyEye, which parses every point in the entire image.
Curve-fitting is a whole science (some would say art) in its own right, and there are few tips I can offer. Choose an equation that seems plausible, and try many initial values: in some cases the parameter values will settle on a "local" rather than a "global" solution (minimum error sum of squares), and also the fitting routine will converge faster from some starting points than from others. It is not unusual for the curve-fitter to crash the program. Fortunately, the program has a safeguard, and your time inputting the data is not lost: start up the program again and see. Crashes are generally caused by one of two things: either a fitting parameter changed sign, or a value was generated that was out of bounds (due to memory constraints, the values are all single precision, limiting them to approximately 1.0e-37 to 1.0e+37). Using an equation that results in taking the logarithm of a negative number or some other mathematical sin results in errors that are detected without crashing the program. See Appendix B for error codes generated by the equation parser and the program.
How can crashes be avoided? If you have a value that is likely to change sign a few times, a simple way to avoid crashing is to substitute, say, (10-B) for B, and give B an initial value of 10. Now the value of B is free to wander, and is less likely to reach zero. This example assumes that you don't care whether your value changes sign: if you do, constraining the model some other way is called for. Suppose B should always be positive, and the curve-fitter is trying to make it negative. You can substitute exp(B) for B -- now B can have any value, but exp(B) will always be positive (Barak et al., 1990). (Of course, you'll need to correct the output value back to just B, and change the equation to its "real" form, before using the equation elsewhere [such as DyEye]. Note also that any statistics you see, such as a parameter correlation matrix, will not be correct.) Similarly, if B must be greater than 2.6, substitute exp(B)+2.6 for B. In a more complex situation, you may need to constrain b between two values (say, 0 < B < 1): this can be done by substituting B with (pi/2)+(arctan(B)/pi).
Output:
The Output menu allows you to output the data
(TIFF) files in a numerical (ASCII) format. You may choose to output
data pixel-by-pixel (which can easily produce files of multiple
megabyte size), or as file means; file names can be included, and data
from the three different color spaces can be included or omitted as
desired. This is useful if you want to export the data to a spreadsheet
or a more advanced statistical package. Sadly, our experience is that
commonly available versions of these advanced statistical packages are
generally not equipped to handle the size of data set which can easily
be generated by a few color photographs. To work with one of our
calibration data sets, which contained over 262,000 points, we had to
adapt our own nonlinear regression procedure to run on a workstation.
On the other hand, as noted above, we obtained better fits in both a
statistical (higher r2) and a visual sense (the subsequently
interpreted images corresponded more closely to the known values) by
using file means; we only went to the trouble of fitting entire data
sets to see how good (or bad) a fit would result.
DyEye is the production end of the two programs. DyEye uses the equation developed in RGBcal to transform images from color (RGB) values to parameter values. (Greyscale and palette-color TIFF images can also be read in, displayed, and manipulated, but they cannot be transformed by the equation, and the program will not recognize the palette assignments in palette-color images.) The resulting parameter image can be manipulated to constrain the calculated pixel values between user-selected values. The image can also be enhanced through some basic image processing filters, and thresholded if the desired output is boolean rather than continuous. The final image can be output as a TIFF file (binary, greyscale, or palette-color), or as ASCII text.
The remarks given for RGBcal concerning consistency in image acquisition apply equally, if not more so, to DyEye: if images are not acquired under consistent conditions with respect to lighting, light quality, and automatic correction in any of the various steps of image acquisition, there is no guarantee that the resulting interpretation of the image will be correct. Likewise, remarks concerning optimizing your equation for RGBcal apply even more so here, as the images you send to DyEye are likely to have more points than the number of files you input to RGBcal.
Configure:
In the Configure Menu, you will see the values
read in from DYEYE.CFG. You may change the Hue offset (see discussion
of this value under RGBcal - View menu), the
equation, the fitting parameters A, B, and C, and the eigenvectors for
principal components one and two (If you want to change the eigenvector
for principal component three, you'll have to edit DYEYE.CFG directly -
see Appendix C for the file format).
Zoom:
The Zoom menu displays the image and a histogram
showing the distribution of values in the image. The top and bottom of
the histogram display the high and low values found in the image. Here
you can change the palette (by pressing 1-5; numbers 6-0 change the
pointer palette, which appears as highlighting on the histogram when
you zoom into it with the arrow keys), zoom in or out on the histogram,
and change whether you are displaying the image as interpreted by the
equation, or simply as one of the color parameters (Red, Hue, etc.).
The histogram will generally show one or more peaks, showing that certain value ranges are displayed more frequently than others. If some of these values are essentially outliers, and you want to enhance the contrast in the higher frequency section of the histogram, you can eliminate the histogram tails by zooming into the histogram. Pressing the down arrow, for example, will highlight the high values that you want truncated, and the colors in the remaining areas will be stretched out. When you have adjusted the histogram to your satisfaction, press "u" and the display will be updated. If you zoom in too far, press the <Page Up> key to increase the range upward, or the <Page Down> key to increase it downward.
Normally the program will display the image as
interpreted through the equation that is currently displayed in the Configure menu. However, sometimes it is useful
to see how the image looks when displayed using a single color
parameter on its own. In the Zoom menu, press "v" to skip down to the
View submenu. Pressing one of the characters displayed here will
display the image according to the corresponding color parameter. For
example, pressing "r" will display the RGB image using just the Red
color channel, and "h" will display the image just using Hue. You can
get back to the Zoom part of the menu by pressing "z", or by using the
arrow keys. Outside of the view menu, the program will always default
to using the equation that is displayed in the configure menu.
If you elected (in the Setup
menu) to manually input the truncation values, you will be asked for
these values the first time you enter a graphical menu (Zoom, Enhance,
or Threshold). Sometimes it is useful to view an image once, play with
the histogram, then back out and set the values manually.
To quit this menu and return to the main menu, hit
<Enter> (to keep the current high and low truncation values) or
<ESC> (to leave the high and low truncation values unchanged). If
you want to keep the values and continue directly to the Enhance or
Threshold menus, press"E" (for Enhance) or "T" (for Threshold).
The median filter displays the median value of
all the values that show up inside the mask. This is the slowest
filter, but one of the most powerful: it smooths out noise, but with
very little blurring of edges.
The Gaussian and mean are smoothing filters. The
Gaussian weights each pixel inside the mask differently, while the mean
takes a simple arithmetic average, but the effect is quite similar.
These filters will take out noise, and their smoothing effect will blur
edges. The Gaussian filter works only on sizes up to 9x9.
The maximum and minimum filters are exactly that -
the center pixel takes the greatest or smallest value of pixels found
within the mask. This can be used to highlight small features - think of
finding stars against a black sky, for example - or to hide noise that
is biased in one direction only.
The original - Laplacian subtracts a Laplacian
operator from the original image. The Laplacian operator is a change
detector, giving extreme values where pixels values change and medium
values where pixel values are constant. Subtracting a Laplacian from
the original image has the effect of sharpening and highlighting edges.
This is included for completeness, and it is useful for picking up
details, but don't be fooled into thinking that the resulting pixel
values are in any way related to your equation! The original -
Laplacian will change your pixel values beyond recognition. Note also
that the original - Laplacian filter works only for sizes up to 7x7,
and for 13x13.
The local equilibrium filter is used to pick up
features that might be lost because of local changes in lighting within
the image. It compares all values within the mask to the value of the
central pixel, and assigns a value based on how many were less than the
central pixel. As a result, it reduces the number of possible values
from 256 to the number of pixels in the mask, and the resulting
histogram looks like a comb. If an image has extreme differences in
lighting, this filter will help find features that might otherwise
remain hidden in the shadows. As with the original - Laplacian, though,
the resulting pixel values bear little or no relationship to your
original equation.
The histogram will show whether your image is
naturally segmented into two regions. If your histogram shows a bimodal
distribution (two humps), you may be able to achieve good separation
just by highlighting from between the two humps to the top (or bottom).
On the other hand, sometimes it is nice to get feedback by looking at
the image as you threshold: by displaying both image and histogram,
DyEye lets you do both.
Within the Threshold menu, you can also change
palettes. You have the regular 5 palettes (palette 5 is black by
default, but you can read in your own palette if you like: see the Setup menu for more information), plus 5 pointer
palettes. These are the colors assigned to the highlighted areas.
Palette 6 is white, 7 is red, 8 is green, 9 is blue, and 10 is black.
You can choose the combination of palette that makes the most sense to
the thresholding you are doing, but note that it is possible to try to
contrast black with black. Needless to say, this won't make for a
useful display!
Output:
The Output menu lets you output the final
interpreted image as a TIFF or text file. Within TIFF format, you can
export it as binary (black and white), 16 shades of grey, 256 shades of
grey, 16 palette colors, or 256 palette colors. Note that 16 palette
colors is not an "official" TIFF format, and this file will take as
much disk space as a 256 palette color file. However, sometimes it is
more useful to see discrete color breaks, and this option lets you
select for it.
Outputting a file as a palette-color TIFF file
means that the colors that you see displayed on the screen will be
hard-coded into the file, and should therefore show up when the file is
imported by a word processor. The choice of palette is therefore
important: choose the palette you like, and if you don't like any of
them, make your own and import it (see the Setup
menu).
Output in text mode is useful for exporting to
more advanced packages that can plot 3D surfaces, but it has the
disadvantage that the exported files can be quite large. Whereas the
output TIFF files use at most 1 byte per pixel, the text file uses 10,
so be prepared for large files. You can choose between linear format
(one value per line in the file, with values going across the image
line by line, like words on a page), and matrix format (a rectangular
format: values will all be in the correct position).
Finally, you have the option of outputting a TAG
file (A TAG file takes the same name as your outputted TIFF or text
file, but uses the filename extension .TAG). The TAG file gives
information on the equation you used, the truncation values, the
fitting parameters, and the thresholding values (if used). Note that
this is not a complete characterization of how you got from the RGB
values to the final output file: it does not include the hue offset (if
HSI space is used), the eigenvectors (if PC space is used), or specify
which enhancement operations were used; nonetheless, it can be useful
to help you keep track of what you've done for a given image.
Setup:
In the Setup menu, you have three options. First,
you can display some basic statistics about a TIFF file (what general
class of TIFF, how big an area it covers). Second, you can read in a
palette that will be used as palette #5, so that when you select
palette 5 in the Zoom, Enhance,
and Threshold menus, this palette will be
used. This is the palette that will be output if you choose to output a
palette-color TIFF file while using palette #5. The palette file has a
simple format: it is a text file that is 256 lines long, with each line
having 3 values between 0 and 255: one each for red, green, and blue.
Because the program automatically assigns black to 0 and white to 255,
you actually control only 254 colors. If you are outputting a 16
palette color file, you still need to input all 256 palette colors,
because the palette colors actually used will be from lines 0, 16, 32,
and so on. Finally, the Setup menu lets you force Zoom and subsequent
menus to use the upper and lower truncation values that you specify
yourself. When DyEye reads in an RGB TIFF file and runs each point
through an equation, some values may be out of the range that you
anticipate: for example, the equation may have exponential behavior,
and a slight change in RGB values at the high end gives you a value
that you know is double what it ought to be. You can constrain the
output between preset values. This is like what you do in the Zoom
menu, except that here you specify the numbers themselves, rather than
zooming in on the histogram.
Ewing, R. P. and R. Horton. 1998a. Quantitative color image analysis of agronomic images. Submitted to Agron. J.
Ewing, R. P. and R. Horton. 1998b. Discriminating dyes in soil with color image analysis. Submitted to Soil Sci. Soc. Am. J.
Kaspar, T. C. and R. P. Ewing. 1997. RootEdge: Software for measuring root length from desktop scanner images. Agron. J. 89:932-940.
The TIFF (Tag Image File Format) reader in RGBcal and DyEye was developed using the TIFF revision 6.0 specifications (June 3, 1992, Aldus Corporation, Seattle, WA), but it is not a full TIFF reader. Images produced by scanners tend to be relatively simple, and the programs' capabilities reflect this. The programs assume that the internal format is either continuous or stripped. TIFF 6.0 supports many forms of compression and many forms of internal image storage, but these programs do not. If your files are compressed or have a complex internal format that the programs cannot handle, try reading them into a commercial image or paint program, then saving them under a new name in uncompressed TIFF format.
If you attempt to read in an image that is not in TIFF format, or a TIFF-format image whose header the programs cannot understand, they will display a file inspection dialog box. You will be asked for the image height and width in pixels, the size of the header in bytes, the number of bits per pixel, whether this is a black/white/grey image or an RGB (red-green-blue) image, and whether the image is a negative (i.e., a pixel value of 0 represents the color white). If the image portion of the file is constructed like a simple TIFF image -- pixels arranged sequentially, left to right and top to bottom like words on a page -- the programs should be able to read the image. However, you will have to enter the image information for each file, each time the programs runs through the files: this can be tedious!
TIFF tags that RGBcal and DyEye recognize:
| 254 | Subfile. File must have no subfiles. |
| 256 | Width. File width must be less than or equal to 16380 pixels (due to memory limitations). |
| 257 | Height. File height may not exceed 65536 pixels. This is part of the standard TIFF specification. |
| 258 | Bits per sample. Valid entries are 1, 4, and 8; RGB samples should be 8. |
| 259 | Compression. File may not be compressed (valid entry is 1). |
| 262 | Photometric interpretation. Valid entries are 0 through 3. 0 and 1 are for grey-scale, 2 means RGB, and 3 is palette-color (each pixel-value is assigned a color through a color table). The programs can read palette-color files, but there is no guarantee that thresholding them will yield meaningful results, so the programs issue a warning flag when it encounters these files. |
| 273 | Strip offsets. Most scanner files will have only one strip, but some will have several. |
| 277 | Samples per pixel. Valid entries are 3, denoting RGB, and 1, denoting other. |
| 278 | Rows per strip. May not exceed 65536. |
| 279 | Strip byte counts (number of bytes in a strip). |
| 282 | X-resolution in pixels per unit (see tag 296). |
| 283 | Y-resolution in pixels per unit. |
| 284 | (Optional) planar configuration. Must equal 1 (chunky format). |
| 296 | Units. Valid entries are 2 (dpi) and 3 (dpc), otherwise the image is unitless. |
| 320 | Color map. This points to the map of the color palette in palette-color images. |
Equation Parser Error Codes:
| 0 | OK -- the equation is formatted and/or executed with no errors |
| 1 | Blank string / no formula -- you must enter an equation |
| 2 | Mismatched/unequal parentheses -- most likely a '(' is missing |
| 3 | Badly formed number -- e.g. 132..3 (double decimal point) |
| 4 | ')' expected |
| 5 | Sqrt of negative number |
| 6 | Log of zero or negative number |
| 7 | Unrecognized function |
| 8 | Invalid character -- for example, '@' and 'z' do not appear in any of the recognized functions or variables. |
| 9 | Double operation -- for example, 14-*6 |
| 10 | Illegal exponentiation -- for example, -2.5^-2.5 |
| 11 | Division by zero |
| 12 | Badly formed equation -- usually indicates that the equation ended before it should have (for example, 15+19*) |
| 13 | Indeterminate problem -- there is a problem, but the parser cannot determine its exact nature. |
| 100-199 | I/O errors (typically disk and/or file problems, such as disk full, or file in use). |
| 200 | Division by zero -- this would be in the curve-fitting code rather than in the parsed equation, which would trap the error as mentioned above. Often results from a fitting parameter changing sign. May indicate an inappropriate equation for the data set: equations that fit nicely rarely produce this error. |
| 203 | Out of heap memory. Options to fix this include: don't use a graphical interface, change your system configuration (i.e., don't use a network, drop your CD driver), use smaller image files, or (if this error shows up in DyEye) simplify the equation. This shouldn't happen unless you're using pretty large files, and even then, the program should display its own error message rather than crashing. |
| 204 | Invalid pointer operation - a problem with memory allocation or deallocation. If you can reproduce the sequence of events that caused it, contact me: I would like to know what lead up to it, and I may be able to fix it. |
| 205 | Floating point overflow - result of a numerical operation is too great. |
| 206 | Floating point underflow - result of a numerical operation is too small. |
| 207 | Invalid floating point operation. This can result from attempting to take the square root of a negative number, or attempting to take the logarithm of zero or a negative number. It can also result from an equation that is too complex, overloading the math coprocessor's stack. Because the math coprocessor typically holds only 8 results on its stack, complex equations that require the storage of many temporary variables can overload the stack. You can avoid this by using simpler equations, or by rearranging your equation so that fewer intermediate results need to be stored. |
The file format is as follows:
| Lines 1-9 | Principal components eigenvectors: first the R, G, and B values corresponding to principal component 1, then the same for 2 and 3. |
| Line 10 | Hue offset (0..2 pi) |
| Line 11 | The equation, in RGBcal format |
| Lines 12-14 | Initial values of the parameters A, B, and C |
| Line 15 | The number of non-white, non-black pixels across all the calibration files. |
| Line 16 | The directory where the image files are located |
| Lines 17+ | A list of image file names followed by their corresponding independent parameter values. |
You can produce your own files in this format, and invoke them at startup by typing, for example, RGBcal DEFAULT.LST. Assuming the file DEFAULT.LST is in the current directory and conforms to the format given above, the values will be loaded and ready for use.
RGBcal and DyEye are provided as-is, with no guarantee of technical support, bug fixes, or future upgrades. However, I try to support the programs as best I can, so if you have a question or need help getting them to work, drop me a line.
The programs are distributed with source code for everything but the rudiments of the user interface (screen-handling and some basic input/output functions). The reason for leaving out these portions is that key parts were written by Borland, and I don't have the right to distribute them as such. However, the compiled version of the interface is included with the distribution files, and I've given an outline of what is available in it, so you can still use it - you just can't modify it.
I have several purposes in distributing the source code with the programs. First, I want you to have access to the code so that if something goes wrong, or the program does something you don't understand, you can examine the code and discover the reason. If you discover bugs and see how to fix them, I'd appreciate being informed of this so I can maintain the code.
Second, writing this program has been an education for me. If you can benefit from looking over the code and seeing how I do something, that's great. Also, if you see a better way of doing something, I'd appreciate hearing about it. Along this line, I should admit up front that the interface in the graphical menus is poorly coded - I'm sorry, but I didn't have time to put together a really smooth interface here. I am in the process of learning Delphi, but it will be a while before I translate the programs.
Finally, you may find that the code can do almost, but not quite, everything that you want to do. Image analysis applications are often custom-built for exactly this reason: each application has its own specific requirements. If you have access to the code, you can easily write another procedure and slip your specific needs into my framework. Once again, I ask that you inform me of what you wanted and how you went about getting it: this way, others may benefit from your effort.