You are on page 1of 42

COPY-PASTE 2014

Image Processing
in Delphi
http://imageprocessingindelphi.blogspot.com/












Sorry, :-) I just copy and paste from the internet. Very thanks to the author of
http://imageprocessingindelphi.blogspot.com/
Its just for educational purpose.




Its not an official, you can see an full article in this url :
http://imageprocessingindelphi.blogspot.com
http://imageprocessingindelphi.blogspot.com/
Table of Contents


Chapter 1. Introduction
Introduction to Image Processing in Delphi
Image Processing Types
Digital Image Formats
Chapter 2. Delphi Components and Graphical User Interface
TImage, An Image Component in Delphi
Writing Simple Graphical User Interface for Image Processing
Chapter 3. Image Histogram
What is An Image Histogram?
The Purpose of Image Histogram
Computing and displaying Image Histogram in Delphi
Chapter 4. Pixel Operation
Pixel Operation: An Introduction
Brightness Modification
Brightness Manipulation in Delphi
Contrast Enhancement
Coding Contrast Enhancement in Delphi
Color Inversion
Color Inversion Processing in Delphi
RGB to Gray Scale Conversion
RGB to Gray Scale Conversion Using Delphi
Thresholding
Threshold Below, Threshold Above, and Threshold Inside Implementation in Delphi

http://imageprocessingindelphi.blogspot.com/
Chapter 1.
Introduction

1.1. Introduction into image processing in Delphi
Have you ever used Photoshop or other image processing software to make a cool
impressive oil painting style of your photograph? Do you know that number of cars
parking in basement can be deducted automatically by computer using the image
captured by a camera in real time? That's what image processing done to make them
possible.
Using Delphi is fun because you can design graphical user interface easily and rapidly.
If you're familiar with Photoshop, Gimp, or other image processing software, you
might be wonder how such software is written. With image processing techniques,
you can write a software to manipulate image brightness, contrast, finding the edge
feature, giving emboss effect, or change the picture to an oil painting look. Learning
image processing is really fun, and using Delphi as the development tools make it
more fun. You will learn basic image processing concept, formulas, and advanced
application of it.
Image processing deals with color manipulation, pixel-by-pixel operation, even frame-
by-frame operation. In this blog, I will try to share and discuss many image processing
techniques, rangin from basic to advanced topics.
1.2. Image Processing Type
Many types of image processing can be classified into some categories:
1. Pixel operation, is an operation of pixels, that each pixel in an image is operated
independently, means that the value of the pixel is not affected by other pixels
value. It depends solely on its previous value and the operation parameters.
Brightness and contrast manipulation are the examples.
2. Global operation, when a global characteristic of an image is used to deduct the
parameter to operate each pixel. The global characteristic is usually determined
using statistical method, for example is automatic brightness and contrast
equalization, where the histogram is redistributed for a better distribution.
3. Multi-frame operation, where an image is operated with other images to get a
result. For example is the generation of transitional image of subsequent slow
motion picture. When a 20 fps (frames per second) movie will be played back four
times slower, it looks smoother if we show them in 20 fps with 3 additional
http://imageprocessingindelphi.blogspot.com/
transition frames between the two original frames, rather than show only the
original frames by 5 fps.
4. Geometric operation, where the shape, size, or the orientation is modified.
Resizing and skewing are some examples.
5. Neighboring pixels operation, where the result of a pixel operation depends not
only on its previous value but also on other surrounding pixels values. Smoothing
and sharpening operation are some examples.
6. Morphologic operation, is operation that is focused on specific image region. This
operation is closely related to image analysis, because it deals with object/morph
detection algorithm.

1.3. Digital Image Format
There are many digital image representation such as raster and vector format. The
raster type represent the image in pixels, while vector type represent the image in
vector notation (curve, line, circle, etc). Only raster type will be discussed here. Raster
image is constructed by many pixels, where each pixel is arranged in rows and
columns. Each pixel can be addressed by its Cartesian coordinate. Within raster image,
there are some very popular formats: binary, gray scale, true color, and indexed color.

Binary Image
In binary image, there are only two values: 0 or 1, representing two different colors.
Most common color mapping is black for 0 and white for 1. Example of binary image is
shown in figure 1.



Figure 1. Binary Image

http://imageprocessingindelphi.blogspot.com/
Gray Scale
Using gray scale, the intensity of a pixel can vary in many values, giving smoother
image. Each pixel can has many possible values, depending on the bit-depth of the
format, for example, an 8 bit gray scale has 256 possible value for each pixel to
represent the dot intensity. The most common color mapping for gray scale is black
for 0 (zero) value, white for maximum value (255 in case of 8-bit image), and gray for
values in between. Other color mapping is possible such as dark brown for zero and
light orange for maximum value. An example of a gray scale image is shown in figure
2.

Figure 2. Gray Scale Image

True Color Image
In a color image, a specific color of a pixel is represented as a combination of three
primary color: red, green, and blue (RGB), therefor this true color format is also known
as RGB format. This RGB primary color is using display format, where the display
device normally has red, green, and blue light source to construct a pixel. This is
different with printing based representation that normally uses cyan, magenta, and
yellow (CMY) as their primary color, as used by printing devices. For 24-bit RGB
format, each element (red, green, and blue) uses 8 bit depth to represent its intensity,
so there are 2^24 or more than 16 million of possible color value for each pixel. An
example of true color image is shown in figure 3.

Figure 3. A True Color Image

http://imageprocessingindelphi.blogspot.com/
Indexed Color Image
The memory to store a true color image is three times than to store gray-scale image.
Inpractical image, the number of colors is often limited, much less than 16 million
combination, because the number of color in an image can't exceed the number of its
pixels. Even if the number of pixels exceed 16 million, the number of colors can be
much less. To reserve the computer's storage memory, an indexed color format is
used for this case. In this format, each pixel is represent an index of a color table.





Figure 4. Indexed Color Image and Its Colormap

This color table is known as color pallet or color map. Using this format, we can
manipulate the color in all pixels faster, because we just need to manipulate the color
map, which have much fewer element that the pixels.Figure 4 is a typical indexed 256-
color image and its own palette (shown as a rectangle of swatches).

http://imageprocessingindelphi.blogspot.com/
Chapter 2.
Delphi Components and Graphical User Interface

2.1. TImage, An Image Component in Delphi
Delphi doesn't provide image processing component, so we have to write the
processing algorithm by ourself, that's why this blog is written. Many third party image
processing component are available, but we don't need it as we are going to learn on
how to make it. To design the graphical user interface, Delphi (both Delphi pro and
Turbo Delphi Explorer) provides TImage component.
This component has Picture property that can be used to store image data. Picture
property has a method called LoadFromFile that can be used to retrieve image data
from a file. Other important TPicture sub-properties are:
Height, represent the value of the image's height in pixel unit.
Width, represent the value of the image's width in pixel unit.
Bitmap, contain the data format information and the pixels values of the image.
The most common used format for for the bitmap are:
pf1bit The bitmap is a device-independent bitmap with one bit per pixel (black
and white palette)
pf8bit The bitmap is a device-independent bitmap that uses a 256color palette.
pf24bit The bitmap is a device-independent true-color bitmap that uses 24 bits
per pixel.
When an image is first loaded from a file, the format will be the original format stored
on that file, but we can change the bitmap format, and the data in the bitmap will be
changed accordingly. Just be careful because this format conversion is not reversible.

2.2. Writing Simple Graphical User Interface for Image Processing
Basic Form
To learn image processing in Delphi by directly coding the algorithm, first we need to
make our GUI (graphical user interface) to load an image, view, process, and show the
result.
http://imageprocessingindelphi.blogspot.com/
1. Create a new project (File->New->Application in Delphi 7 or File->New->VCL Form
Application in Turbo Delphi Explorer).
2. Set the FormStyle property of the form to fsMDIForm.
3. Change the form name from Form1 to MainForm.
4. Add a main menu component (from Standard component pallet) on the form,
double click it and set a menu item File, with Open, Save, Close, and Exit sub
menus.
5. Add an OpenPictureDialog (from Dialogs component pallet) and SavePictureDialog
(from dialog component pallet) components on the form.
6. Set the Option.ofOverwritePrompt property of SavePictureDialog to true.
7. Add a status bar (from Win32 component pallet) on the form to ease the window
resizing.
8. Resize the window as shown in figure 1.
9. Save the form (File->Save As), type MainUnit in the file name edit box.
10. Create a new form to display the the picture as a child window on the main form
using menu File->New->Form.
11. Set the FormStyle property of the form to fsMDIChild.
12. Change the form name to ImageForm.
13. Resize the form as shown in the figure 2.
14. Add an Image component (from Additional component pallet).
15. Set the Align property of the Image component to alClient.
16. Set the Stretch property of the Image component to "true".
17. Set the Proportional property of the Image component to "true".
18. Save the form using menu File->Save as, and name it as ImageUnit.
19. Save the project using menu File->Save project as , name it with ImageProcessor,
so this will be our executable file name if we compile it.

http://imageprocessingindelphi.blogspot.com/

Figure 1. MainForm


Figure 2. ImageForm

After this steps, if we compile and run the executable, the child form will be shown
because Delphi will auto-create it. This child form should be displayed only after
executing a file operation, so we need to exclude the child form in auto-create: go to
Project->Options->Form, point to ImageForm to select, and press the > button, so the
ImageForm will move to Available forms box, then press OK.

Writing From Closing Event Handler for Image Form
When the image form is closed, we have to free the resources used by the form, view
the ImageForm (Shift+F12 and select the ImageForm and press OK), then click Events
tab on the object inspector, double click the OnClose edit box, you'll be directed to the
event handler, and change the Action variable to caFree between begin and end.
view plainprint?
1. procedure TImageForm.FormClose(Sender: TObject; var Action: TCloseAction);
2. begin
3. Action:=caFree;
4. end;


http://imageprocessingindelphi.blogspot.com/
Loading Image File
Here some steps to load an image from a file:
1. To load and display an image file, we will use ImageForm defined in ImageUnit, so
click on MainForm and click menu File->Use Unit, and select ImageUnit then press OK.
Make sure that uses ImageUnit is automatically added below the
keyword implementation.
view plainprint?
1. implementation
2.
3. uses ImageUnit;
4.
5. {$R *.dfm}

2. Add ActiveX in the uses , this trick is needed to resolve TOpenPictureDiaolog bug
(showing access violation error, I find this bug on Delphi 7 running on Windows XP
SP2). Now the uses section will look like this:
view plainprint?
1. implementation
2.
3. uses ActiveX, ImageUnit;
4.
5. {$R *.dfm}

As an integrated part of the trick, add an initialization and finalization just before the
end of the file (before end.) like shown below:
view plainprint?
1. initialization
2. OleInitialize(nil);
3. finalization
4. OleUninitialize
5. end.

3. Make an event handler of MainMenu1->File->Open, by double clicking the
MainMenu1 component, and double click the Open menu. you will be directed to the
script editor.
view plainprint?
1. procedure TMainForm.Open1Click(Sender: TObject);
2. begin
3.
4. end;

Edit that script as shown below:
view plainprint?
1. procedure TMainForm.Open1Click(Sender: TObject);
2. var
3. formatInfo:string;
http://imageprocessingindelphi.blogspot.com/
4. begin
5. if OpenPictureDialog1.Execute then
6. begin
7. Application.CreateForm(TImageForm, ImageForm);
8. ImageForm.Image1.Picture.LoadFromFile(
9. OpenPictureDialog1.FileName);
10. ImageForm.ClientHeight:=
11. ImageForm.Image1.Picture.Height;
12. ImageForm.ClientWidth:=
13. ImageForm.Image1.Picture.Width;
14. case (ImageForm.Image1.Picture.Bitmap.PixelFormat) of
15. pf1bit : formatInfo:='Binary';
16. pf8bit : formatInfo:='Gray scale';
17. pf24bit: formatInfo:='True color';
18. end;
19. StatusBar1.SimpleText:= OpenPictureDialog1.FileName +' '+
20. IntToStr(ImageForm.Image1.Picture.Width) + 'x'+
21. IntToStr(ImageForm.Image1.Picture.Height) + ' '+
22. formatInfo;
23. end;
24. end;

Saving The Image to A File
Although we haven't implemented the image processing code, we can implement file
saving function right now. To write File->Save event handler, follow this steps:

1. Double click the MainMenu1 component, and double click the Save item, you'll be
directed to the event handler sript:
view plainprint?
1. procedure TMainForm.Save1Click(Sender: TObject);
2. begin
3.
4. end;

2. Edit that script as shown below:
view plainprint?
1. procedure TMainForm.Save1Click(Sender: TObject);
2. begin
3. try
4. begin
5. if SavePictureDialog1.Execute then
6. TImageForm(ActiveMDIChild).Image1.Picture.SaveToFile(
7. SavePictureDialog1.FileName);
8. end
9. except
10. ShowMessage('Operation is not complete');
11. end;
12. end;

http://imageprocessingindelphi.blogspot.com/

Figure 3. The Executable

Writing File->Close Event Handler
1. Double click the MainMenu1 component, and double click the Close item, you'll be
directed to the event handler sript:
view plainprint?
1. procedure TMainForm.Close1Click(Sender: TObject);
2. begin
3.
4. end;
2. Edit that script as shown below:
view plainprint?
1. procedure TMainForm.CLose1Click(Sender: TObject);
2. begin
3. try
4. ActiveMDIChild.Close;
5. except
6. ShowMessage('Operation is not completed');
7. end;
8. end;
Writing File->Exit Event Handler
To write File-Exit event handler, double click the MainMenu1 component, and double
click the Close item, you'll be directed to the event handler sript, and add close; inside
the begin-end:
view plainprint?
1. procedure TMainForm.Exit1Click(Sender: TObject);
2. begin
3. Close;
4. end;

Now you can compile and run the executable. Figure 3 show the executable viewing
an image. You can download the source code of this GUI for Delphi 7here, and for
Turbo Delphi Explorer here.
http://imageprocessingindelphi.blogspot.com/
Chapter 3.
Image Histogram

3.1. What Is An Image Histogram?
Image histogram (gray level histogram) is one of simple and easy statistical tool for
image analysis. From the histogram, many useful information of an image can be
represented from an image. Image histogram is easy and fast to compute.
Gray level histogram is a function that show how many pixels for every gray level exist
in an image. The x-axis is the gray level, and the y-axis is the number of pixels that
have certain level appear on an image.


Figure 1. An Image And Its Histogram

Figure 1. Show an image and its histogram, you can show in the histogram that the
pixels values (the gray level values) is distributed only on the middle part of the
available level, at levels between 100-200. We can say that the image doesn't
maximize the usage of the available bit-depth (0-255).
http://imageprocessingindelphi.blogspot.com/


Figure 2. The Image And Its Histogram After Equalization

Using image processing techniques, we can manipulate the image to equalize the
histogram, so we will have a better picture. The image and it's histogram after
equalization is shown in Figure 2.
3.2. The Purpuses of Image Histogram Analysis
Image histogram analysis is very useful in image processing, some of the purposes are:
1. Selecting appropriate digitizing parameter. Histogram can be used to visually
judge if an image is in an appropriate range of gray level. Ideally, digital image
should use all available gray scale range, from minimum to maximum. This is
important to optimize the display and other imaging devices to use all their
potential capability. The imaging devices will be optimum if the they display (or
print) the image data that contain optimum usage of its format (for example 0-
255 for 8bit monochrome image).
2. Selection of Thresholding Level. One of image processing technique is
thresholding, where all pixels above certain brightness level is maximized to the
maximum value and others are minimized to the minimum value.
http://imageprocessingindelphi.blogspot.com/


This is very useful in object and background separation if there is significant
difference between an object and its background on an image.
3.3. Computing and Displaying Image Histogram in Delphi
To make our own histogram analysis using Delphi, first you need to make (or
download the source code) of the graphical user interface for image processing we
described in the previous chapter. To compute the image histogram, you need to
make a vector variable to store the count of each pixel level. After that, you may begin
to check the pixel value, and increment the variable that store the pixels count for that
level. Histogram for color pixel is computed in the same way, but independently done
for each R, G, and B element.
Creating Histogram Form
1. Open the GUI project created in the previous chapter.
2. Create a new form, change the form name property to HistogramForm, change
the Caption to 'Histogram', set the ClientHeight property to 170, set the
ClientWidth property to 275, and set the form style property to fsMDIChild.Make
OnClose event handler, click Events tab on the object inspector, double click the
OnClose event handler edit box. You'll be directed to the event handler, and
change the Action variable to caFree between begin and end.
view plainprint?
1. procedure THistogramForm.FormClose(Sender: TObject;
2. var Action: TCloseAction);
3. begin
4. Action:=caFree;
5. end;
http://imageprocessingindelphi.blogspot.com/
3. Go to menu Project->Options, on the Forms page, click HistogramForm to select,
and press > to move the it from auto created forms list to available forms list.
4. Save the unit (File->Save) as HistogramUnit.

Adding Vector Variables to Store The Histogram
To add variables to store the histogram, add the variables to the original
HistogramForm abstraction in private section. Also add a
procedureShowHistogram() to compute histogram in the public section. Add ExtCtrls
in under the uses of the interface section, as we're going to use TImage in the form
class abstraction.
view plainprint?
1. uses
2. ExtCtrls, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For
ms, Dialogs;
3.
4. type
5. THistogramForm = class(TForm)
6. procedure FormClose(Sender: TObject; var Action: TCloseAction);
7. private
8. { Private declarations }
9. MaxCount:Integer;
10. HistogramGray:Array[0..255]of Integer;
11. HistogramRed:Array[0..255]of Integer;
12. HistogramGreen:Array[0..255]of Integer;
13. HistogramBlue:Array[0..255]of Integer;
14. public
15. { Public declarations }
16. procedure ShowHistogram(Image:TImage);
17. end;
Writing The Histogram Computation Procedure
In the implementation, write the ShowHistogram procedure as shown below:
view plainprint?
1. procedure THistogramForm.ShowHistogram(Image:TImage);
2. var
3. i,j:integer;
4. pixelPointer:PByteArray;
5. begin
6. try
7. begin
8. for i:=0 to 255 do
9. begin
10. HistogramGray[i]:=0;
11. HistogramRed[i]:=0;
12. HistogramGreen[i]:=0;
13. HistogramBlue[i]:=0;
14. end;
15. if Image.Picture.Bitmap.PixelFormat=pf8bit then
16. begin
17. for i:=0 to Image.Height-1 do
18. begin
19. pixelPointer:=Image.Picture.Bitmap.ScanLine[i];
http://imageprocessingindelphi.blogspot.com/
20. for j:=0 to Image.Width-1 do
21. begin
22. Inc(HistogramGray[pixelPointer[j]]);
23. end;
24. end;
25. MaxCount:=0;
26. for i:=0 to 255 do
27. if HistogramGray[i]>MaxCount then
28. MaxCount:=HistogramGray[i];
29. end;
30. if Image.Picture.Bitmap.PixelFormat=pf24bit then
31. begin
32. for i:=0 to Image.Height-1 do
33. begin
34. pixelPointer:=Image.Picture.Bitmap.ScanLine[i];
35. for j:=0 to Image.Width-1 do
36. begin
37. Inc(HistogramBlue[pixelPointer[3*j]]);
38. Inc(HistogramGreen[pixelPointer[3*j+1]]);
39. Inc(HistogramRed[pixelPointer[3*j+2]]);
40. end;
41. end;
42. for i:=0 to 255 do
43. begin
44. if HistogramRed[i]>MaxCount then
45. MaxCount:=HistogramRed[i];
46. if HistogramGreen[i]>MaxCount then
47. MaxCount:=HistogramGreen[i];
48. if HistogramBlue[i]>MaxCount then
49. MaxCount:=HistogramBlue[i];
50. end;
51. end;
52. Canvas.MoveTo(10, 160);
53. Canvas.Pen.Color:=clBlack;
54. for i:=0 to 255 do
55. Canvas.LineTo(10+i,
56. 160-round(150*HistogramGray[i]/MaxCount));
57. Canvas.Pen.Color:=clRed;
58. Canvas.MoveTo(10, 160);
59. for i:=0 to 255 do
60. Canvas.LineTo(10+i,
61. 160-(round(150*HistogramRed[i]/MaxCount)));
62. Canvas.Pen.Color:=clGreen;
63. Canvas.MoveTo(10, 160);
64. for i:=0 to 255 do
65. Canvas.LineTo(10+i,
66. 160-(round(150*HistogramGreen[i]/MaxCount)));
67. Canvas.Pen.Color:=clBlue;
68. Canvas.MoveTo(10, 160);
69. for i:=0 to 255 do
70. Canvas.LineTo(10+i,
71. 160-(round(150*HistogramBlue[i]/MaxCount)));
72. end;
73. except
74. Free; //free the histogram form if an exception happens
75. ShowMessage('Operation is not completed');
76. end;
77. end;
Histogram Form Repainting
When the form is activated from minimized condition, we need to redraw the canvas
we have drawn on ShowHistogram procedure. Place a focus on the histogram form, go
http://imageprocessingindelphi.blogspot.com/
to object inspector, on the Events tab, double click OnPaint event and we will be
directed to the event handler, edit as shown below:
view plainprint?
1. procedure THistogramForm.FormPaint(Sender: TObject);
2. var
3. i:integer;
4. begin
5. Canvas.MoveTo(10, 160);;
6. Canvas.Pen.Color:=clBlack;
7. for i:=0 to 255 do
8. Canvas.LineTo(10+i,
9. 160-round(150*HistogramGray[i]/MaxCount));
10. Canvas.Pen.Color:=clRed;
11. Canvas.MoveTo(10, 160);
12. for i:=0 to 255 do
13. Canvas.LineTo(10+i,
14. 160-(round(150*HistogramRed[i]/MaxCount)));
15. Canvas.Pen.Color:=clGreen;
16. Canvas.MoveTo(10, 160);
17. for i:=0 to 255 do
18. Canvas.LineTo(10+i,
19. 160-(round(150*HistogramGreen[i]/MaxCount)));
20. Canvas.Pen.Color:=clBlue;
21. Canvas.MoveTo(10, 160);
22. for i:=0 to 255 do
23. Canvas.LineTo(10+i,
24. 160-(round(150*HistogramBlue[i]/MaxCount)));
25. end;

Calling Histogram Procedure from Main Form
To call showHistogram procedure, we need the user interface in the main form. On
the main form, double click the MainMenu component, and add menu item Image-
>Histogram (see figure 1), then double click the Histogram item, so we will be directed
to its event handler, and edit as shown below:
view plainprint?
1. procedure TMainForm.Histogram1Click(Sender: TObject);
2. begin
3. if ImageForm<>nil then
4. begin
5. ImageForm:=TImageForm(ActiveMDIChild);
6. try
7. begin
8. Application.CreateForm(THistogramForm,HistogramForm);
9. HistogramForm.ShowHistogram(ImageForm.Image1);
10. end;
11. except
12. HistogramForm.Free;
13. ShowMessage('Cannot complete the operation');
14. end;
15. end;
16. end;

http://imageprocessingindelphi.blogspot.com/

Figure 1. Image Histogram Main Menu
Make sure that in that main unit uses HistogramUnit under
the uses ofimplementation section. Now you can save all form, compile, and run the
executable. The example of executable running is shown in figure 2.

Figure 2. Image Histogram Execution

Source Code Download
You can download the source code for both Delphi 7 and Turbo Delphi Explorer. The
Delphi 7 source code can be downloaded here, and the Turbo Delphi Explorer source
code here.

http://imageprocessingindelphi.blogspot.com/
Chapter 4.
Pixel Operation

4.1. Pixel Operation: An Introduction
Pixel operation is operation of an image where each pixel's intensity value is modified.
The modification/transformation depends solely on it's previous value, regardless of
its position and other pixels value. Some image operation in this category are
brightness modification, contrast enhancement, color inversion (negation), and
thresholding operation.
Pixel operation is done by transforming each pixel value to new value according to a
transformation function, known as gray-scale transformation (GST) function. This
function map the gray-level input (Ki) to an new gray-level output (Ko). In general, a
GST function can be expressed as:
Ko=f(Ki)

Figure 1. typical Gray-Scale Transformation (GST) Function Plot

The mapping of typical GST function can presented as transformation curve, as shown
in Figure 1. The function can be linear or non-linear. In a true color image, GST
function is applied to each RGB elements. Each function for each color element can
take the same form or different depends on the application.

http://imageprocessingindelphi.blogspot.com/
4.2. Brightness Modifiation
We can't read a book or see something clearly in a room with low light source. In real
life, we can improve brightness by exposing the object with strong light source. In
image processing, it's equivalent to white color (analogous to light source) addition.
This is done by simply adding a constant to each color element. When the constant is
positive then the image become brighter and when the constant is negative then the
image will be darker.

Figure 1. Brightness Manipulation Function Plot
The GST function for brightness manipulation ca be plotted as shown in figure 1.
Remember that the addition with the constant is limited to 0-255 (8bit monochrome
or 24bit true color format). The effect on the image's histogram is shown in figure 2.

Figure 2. Brightness Manipulation Effect on Image Histogram
http://imageprocessingindelphi.blogspot.com/

For true color image, the modification for each color elements can be different. We
can add more blue and reduce the red element to make different color source
addition (equivalent to color light source exposure in real life).

4.3. Brightness Manipulation in Delphi
To manipulate an image's brightness is easy, first we can make the graphical user
interface (GUI) to ease the manipulation. The GUI consist of a form with three sliding
bar (TScrollBar). Each scroll bar is used to adjust the brightness constant for each color
element.
1. Open our previous image histogram project (you can download the source
code there if you don't have it).
2. Create a new form (File->New->Form).
3. Change the name property to BrightnessForm, change the Caption property to
'Brightness'. Set the FormStyle property to fsMDIChild. Resize the form to fit the
main form (parent form).
4. On the Object Inspector, click on Events tab, and double click in the OnClose
event. You'll be directed to the event handler, and assign the Action variable with
caFree between begin and end.
view plainprint?
1. procedure TBrightnessForm.FormClose(Sender: TObject;
2. var Action: TCloseAction);
3. begin
4. Action:=caFree;
5. end;

5. Add three scroll bar components (from the standard component pallet) to the
form. Change the Name property to RedScrollBar, GreenScrollBar, and
BlueScrollBar. Set the minimum and maximum property of each scroll bar to -255
and 255.
6. Place three label components (from the standar component pallet) to the form,
place the layout to associate each label to each scroll bar. Change the Label's
caption to Red, Green, and Blue, to label the scroll bar functions (See Figure 1).
http://imageprocessingindelphi.blogspot.com/
7. Add two buttons (from standard component pallet), change their caption to OK
and Cancel, and set their name to OKButton and CancelButton accordingly.
8. Save the unit as BrightnessUnit (using menu File->Save As).
9. Go to Project->Options->Form, point to BrightnessForm to select, and press the >
button, so the BrightessForm will move to Available forms box, then press OK.


Figure 1. Brightness Modification GUI

To modify the image, it's common to backup the original image, so we can do a cancel
operation after displaying the change on the original image form. To do this, we have
to provide TImage object in the form to temporarily store the image. A procedure
(SetBrightness) to associate the image input to the brightness form is also needed.
1. Edit the BrightnessForm abstraction to provide TImage object and the
SetBrightness procedure. Add ExtCtrls under uses in the Interfacesection because
we're gonna use TImage component.
view plainprint?
1. uses
2. ExtCtrls, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls
, Forms,Dialogs, StdCtrls
3.
4. type= class(TForm)
5. TBrightnessForm = class(TForm)
6. RedScrollBar: TScrollBar;
7. GreenScrollBar: TScrollBar;
8. BlueScrollBar: TScrollBar;
9. Label1: TLabel;
10. Label2: TLabel;
11. Label3: TLabel;
12. OKButton: TButton;
13. CancelButton: TButton;
14. procedure FormClose(Sender: TObject; var Action: TCloseAction);
15. private
16. { Private declarations }
17. TemporaryImage:TImage;
18. OriginalImage:TImage;
http://imageprocessingindelphi.blogspot.com/
19. Applied:boolean;
20. public
21. { Public declarations }
22. procedure SetBrightness(Image: TImage);
23. end;

2. Write the SetBrightness procedure in the implementation section
view plainprint?
1. procedure TBrightnessForm.SetBrightness(Image: TImage);
2. begin
3. try
4. begin
5. TemporaryImage:=Image;
6. OriginalImage:=TImage.Create(self);
7. OriginalImage.Picture.Bitmap.Assign(Image.Picture.Bitmap);
8. end;
9. except
10. begin
11. Free; //free the brightness form
12. ShowMessage('Cannot complete the operation');
13. end;
14. end;
15. end;

3. Double click the RedScrollBar component, the you'll be directed to its event
handler, edit as shown below
view plainprint?
1. procedure TBrightnessForm.RedScrollBarChange(Sender: TObject);
2. var
3. i,j:Integer;
4. temp:integer;
5. pixelPointer:PByteArray;
6. originalPixelPointer:PByteArray;
7. begin
8. try
9. begin
10. for i:=0 to TemporaryImage.Picture.Height-1 do
11. begin
12. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];
13. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];
14. for j:=0 to TemporaryImage.Picture.Width-1 do
15. begin
16. temp:=originalPixelPointer[3*j+2]+ RedScrollBar.Position;
17. if temp<0 then temp:=0;
18. if temp>255 then temp:=255;
19. pixelPointer[3*j+2]:=temp;
20. end;
21. end;
22. TemporaryImage.Refresh;
23. end;
24. except
25. begin
26. Free;
27. ShowMessage('Cannot complete the operation');
28. end;
29. end;
30. end;
http://imageprocessingindelphi.blogspot.com/

4. Double click the GreenScrollBar component, the you'll be directed to its event
handler, edit as shown below
view plainprint?
1. procedure TBrightnessForm.GreenScrollBarChange(Sender: TObject);
2. var
3. i,j:Integer;
4. temp:integer;
5. pixelPointer:PByteArray;
6. originalPixelPointer:PByteArray;
7. begin
8. try
9. begin
10. for i:=0 to TemporaryImage.Picture.Height-1 do
11. begin
12. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];
13. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];
14. for j:=0 to TemporaryImage.Picture.Width-1 do
15. begin
16. temp:=originalPixelPointer[3*j+1]+ GreenScrollBar.Position;
17. if temp<0 then temp:=0;
18. if temp>255 then temp:=255;
19. pixelPointer[3*j+1]:=temp;
20. end;
21. end;
22. TemporaryImage.Refresh;
23. end;
24. except
25. begin
26. Free;
27. ShowMessage('Cannot complete the operation');
28. end;
29. end;
30. end;

5. Double click the BlueScrollBar component, the you'll be directed to its event
handler, edit as shown below
view plainprint?
1. procedure TBrightnessForm.BlueScrollBarChange(Sender: TObject);
2. var
3. i,j:Integer;
4. temp:integer;
5. pixelPointer:PByteArray;
6. originalPixelPointer:PByteArray;
7. begin
8. try
9. begin
10. for i:=0 to TemporaryImage.Picture.Height-1 do
11. begin
12. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];
13. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];
14. for j:=0 to TemporaryImage.Picture.Width-1 do
15. begin
16. temp:=originalPixelPointer[3*j]+ BlueScrollBar.Position;
17. if temp<0 then temp:=0;
18. if temp>255 then temp:=255;
http://imageprocessingindelphi.blogspot.com/
19. pixelPointer[3*j]:=temp;
20. end;
21. end;
22. TemporaryImage.Refresh;
23. end;
24. except
25. begin
26. Free;
27. ShowMessage('Cannot complete the operation');
28. end;
29. end;
30. end;

6. Double click OKButton component, you'll be directed to its event handler, and
edit it as shown below:
view plainprint?
1. procedure TBrightnessForm.OKButtonClick(Sender: TObject);
2. begin
3. Applied:=true;
4. Close();
5. end;

7. Double click CancelButton component, you'll be directed to its event handler, and
edit it as shown below:
view plainprint?
1. procedure TBrightnessForm.OKButtonClick(Sender: TObject);
2. begin
3. Applied:=false;
4. Close();
5. end;

8. Edit BrightnessForm's OnClose even handler as shown below:
view plainprint?
1. procedure TBrightnessForm.FormClose(Sender: TObject;
2. var Action: TCloseAction);
3. begin
4. if Applied=false then
5. TemporaryImage.Picture.Bitmap.Assign(
6. OriginalImage.Picture.Bitmap);
7. Action:=caFree;
8. end;

Showing The Brightness Manipulation Form from Main Form
Now you can call the brightness form from main form. To do this, we need to add a
menu to provide the access, double click the main menu component in the main form,
and add Brightness menu item under menu Image (Image->Brightness), see Figure 2.

http://imageprocessingindelphi.blogspot.com/

Figure 2. Brightness Menu

Write the event handler for the menu as shown below:
view plainprint?
1. procedure TMainForm.Brightness1Click(Sender: TObject);
2. begin
3. if ImageForm<>nil then
4. begin
5. ImageForm:=TImageForm(ActiveMDIChild);
6. try
7. begin
8. Application.CreateForm(TBrightnessForm,BrightnessForm);
9. Brightnessform.SetBrightness(ImageForm.Image1);
10. end;
11. except
12. BrightnessForm.Free;
13. ShowMessage('Cannot complete the operation');
14. end;
15. end;
16. end;

Figure 3. Brightness Modification Execution
http://imageprocessingindelphi.blogspot.com/

Don't forget to add BrightnessUnit under the uses in the MainUnit's implementation.
Use menu File->Use Unit (Alt+F11). Now you can save, compile and run the
executable. The execution look like figure 3. Here you can download the source code
for Delphi 7 project , and Turbo Delphi Explorer project source code here.

4.4. Contrast Enhancement
Contrast in an image is the difference between pixels values. Without contrast we
can't see anything because everything will be white or black, or just gray. If an image
has a low contrast, it means that different objects in the image have low luminosity
difference, and and it'll be difficult to separate them in our perception. Contrast
enhancement will be helpful in increasing the visibility of an image. Figure 1 show two
images with different contrast and their histogram.

Figure 1. Histograms of An Image Before Contrast Enhancement (upper image) and After
Contrast Enhancement (lower image)

Contrast enhancement can be done using various gray scale transformation (GST)
formulas. The following is one of contrast enhancement GST formula:
Po=G(Pi-C)+C
Which G is contrast gain, and C is the center for contrasting reference. At point C the
pixel value is not modified, at above C point the pixels values is increased, and below C
they're decreased.

http://imageprocessingindelphi.blogspot.com/
4.5. Coding Contrast Enhancement in Delphi
Designing the GUI and The Processing Algorithm
To make our contrast enhancement processing, we need to design the graphical user
interface (GUI) first. The GUI is similar with our previous brightness modification user
interface. The following steps explains how to make it:
1. Open (or download first) our previous brightness modification project.
2. Create a new form (File->New->Form).
3. Change the name property to ContrastForm, change the Caption property to
'Contrast'. Set the FormStyle property to fsMDIChild. Resize the form to fit the
main form (parent form).
4. On the Object Inspector, click on Events tab, and double click in the OnClose
event. You'll be directed to the event handler, and assign the Action variable with
caFree between begin and end
view plainprint?
1. procedure TContrastForm.FormClose(Sender: TObject;
2. var Action: TCloseAction);
3. begin
4. Action:=caFree;
5. end;

5. Add two scroll bar components (from the standard component pallet) to the
form. Change the Name property to CenterScrollBar and ContrastScrollBar. Set
the Minimum property of CenterScrollBar to 0 and the Maximum to 255. Set the
minimum property of ContrastScrollBar to -100 and the maximum to 100. Set the
position of CenterScrollBar to 127, set the position of ContrastScrollBar to 0.
6. Place two label components (from the standar component pallet) to the form, set
the layout to associate each label to each scroll bar. Change the Label's caption to
'Center' and 'Contrast' accordingly (see Figure 1).
7. Add two buttons (from standard component pallet), change their caption to OK
and Cancel, and set their name to OKButton and CancelButton accordingly.
8. Save the unit as ContrastUnit (using menu File -> Save As).
9. Go to Project->Options->Form, point to ContrastForm to select, and press the >
button, so the ContrastForm will move to Available forms box, then press OK.
http://imageprocessingindelphi.blogspot.com/

Figure 1. Contrast GUI Form

To modify the image, it's common to backup the original image, so we can do a cancel
operation after displaying the change on the original image form. To do this, we have
to provide TImage object in the form to temporarily store the image. A procedure
(SetContrast) to associate the image input to the brightness form is also needed.
1. Edit the BrightnessForm abstraction to provide TImage (TemporaryImage and
OriginalImage) object and the SetBrightness procedure. A boolean flag (Applied) is
also needed to mark whether a Cancel or OK button has been pressed. Add
ExtCtrls under uses in theInterface section because we're gonna use TImage
component. Edit as shown below:
view plainprint?
1. type
2. TContrastForm = class(TForm)
3. CenterScrollbar: TScrollBar;
4. ContrastScrollBar: TScrollBar;
5. Label1: TLabel;
6. Label2: TLabel;
7. OKButton: TButton;
8. CancelButton: TButton;
9. procedure FormClose(Sender: TObject; var Action: TCloseAction);
10. private
11. { Private declarations }
12. TemporaryImage:TImage;
13. OriginalImage:TImage;
14. Applied:boolean;
15. public
16. { Public declarations }
17. procedure SetContrast(Image: TImage);
18. end;
2. Write the SetContrast procedure definition in the implementation section:
view plainprint?
1. procedure TContrastForm.SetContrast(Image: TImage);
2. begin
3. try
4. begin
5. TemporaryImage:=Image;
6. TemporaryImage.Picture.Bitmap.PixelFormat:=pf24bit;
7. OriginalImage:=TImage.Create(self);
8. OriginalImage.Picture.Bitmap.Assign(Image.Picture.Bitmap);
9. end;
http://imageprocessingindelphi.blogspot.com/
10. except
11. begin
12. Free; //free the contrast form
13. ShowMessage('Cannot complete the operation');
14. end;
15. end;
16. end;
3. Double click the CenterScrollBar component, the you'll be directed to its event
handler, edit as shown below
view plainprint?
1. procedure TContrastForm.CenterScrollbarChange(Sender: TObject);
2. var
3. i,j:Integer;
4. temp:real;
5. pixelPointer:PByteArray;
6. originalPixelPointer:PByteArray;
7. begin
8. try
9. begin
10. if TemporaryImage.Picture.Bitmap.PixelFormat=pf8bit then
11. for i:=0 to TemporaryImage.Picture.Height-1 do
12. begin
13. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];
14. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];
15. for j:=0 to TemporaryImage.Picture.Width-1 do
16. begin
17. temp:=((originalPixelPointer[j]-CenterScrollBAr.Position)
18. *exp(ContrastScrollBar.Position/50))
19. + CenterScrollBar.Position;
20. if temp<0>255 then temp:=255;
21. pixelPointer[j]:=round(temp);
22. end;
23. end;
24. if TemporaryImage.Picture.Bitmap.PixelFormat=pf24bit then
25. for i:=0 to TemporaryImage.Picture.Height-1 do
26. begin
27. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];
28. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];
29. for j:=0 to TemporaryImage.Picture.Width-1 do
30. begin
31. temp:=((originalPixelPointer[3*j]-CenterScrollBAr.Position)
32. *exp(ContrastScrollBar.Position/50))
33. + CenterScrollBar.Position;
34. if temp<0>255 then temp:=255;
35. pixelPointer[3*j]:=round(temp);
36. temp:=((originalPixelPointer[3*j+1]-CenterScrollBAr.Position)
37. *exp(ContrastScrollBar.Position/50))
38. + CenterScrollBar.Position;
39. if temp<0>255 then temp:=255;
40. pixelPointer[3*j+2]:=round(temp);
41. temp:=((originalPixelPointer[3*j+2]-CenterScrollBAr.Position)
42. *exp(ContrastScrollBar.Position/50))
43. + CenterScrollBar.Position;
44. if temp<0>255 then temp:=255;
45. pixelPointer[3*j+2]:=round(temp);
46. end;
47. end;
48. TemporaryImage.Refresh;
49. end;
50. except
51. begin
52. Free;
http://imageprocessingindelphi.blogspot.com/
53. ShowMessage('Cannot complete the operation');
54. end;
55. end;
56. end;
In the code shown above, you can see the contrast gain is computed as
exp(ContrastScrollBar.Position/50), with this formula, when the scroll bar position
is zero (the default), the gain will be exp(0/50)=1, and at maximum the contrast
gain will be exp(100/50)=100, and at the minimum the contrast gain will be exp(-
100/50)=1/100.

4. On the ContrastForm, double clicks the OKButton component, you'll be directed
to its event handler, then edit as shown below:
view plainprint?
1. procedure TContrastForm.OKButtonClick(Sender: TObject);
2. begin
3. Applied:=true;
4. Close();
5. end;
5. Double click the CancelButton component in the ContrastForm, and you'll be
directed to its event handler, edit as shown below:
view plainprint?
1. procedure TContrastForm.CancelButtonClick(Sender: TObject);
2. begin
3. Applied:=false;
4. Close();
5. end;
6. To implement the decision whether the image on the source form will be
modified or reverted to the original bitmap, edit the ContrastForm's OnClose
event handler as shown below:
view plainprint?
1. procedure TContrastForm.FormClose(Sender: TObject; var Action: TCloseAction)
;
2. begin
3. if Applied=false then
4. TemporaryImage.Picture.Bitmap.Assign(
5. OriginalImage.Picture.Bitmap);
6. Action:=caFree;
7. end;

Calling the GUI Module from The Main Application
To show the contrast enhancement interface and to connect the active image form to
the contrast GUI, we need to add a new item in the main menu. Double click the main
menu component in the main form, and add a Contrast menu item under menu Image
(Image -> Contrast, see Figure 2.
http://imageprocessingindelphi.blogspot.com/

Figure 2. Contrast Menu Item

Write the event handler for the menu as shown below:
view plainprint?
1. procedure TMainForm.Contrast1Click(Sender: TObject);
2. begin
3. if ImageForm<>nil then
4. begin
5. ImageForm:=TImageForm(ActiveMDIChild);
6. try
7. begin
8. Application.CreateForm(TContrastForm,ContrastForm);
9. ContrastForm.SetContrast(ImageForm.Image1);
10. end;
11. except
12. ContrastForm.Free;
13. ShowMessage('Cannot complete the operation');
14. end;
15. end;
16. end;
http://imageprocessingindelphi.blogspot.com/

Figure 3. Contrast Processing Execution
Don't forget to add ContrastUnit under the uses in the MainUnit's implementation.
Use menu File->Use Unit (Alt+F11). Now you can save, compile and run the
executable. The execution look like figure 3.

Source Code Download
The source code can be downloaded here for Delphi 7 project, and here for the Turbo
Delphi Explorer source code. Besides contains new source codes for contrast
enhancement, if you compare to our previous brightness modification project's source
codes, you'll see that in the codes for the brightness manipulation codes has also been
updated to accommodate both two different image formats, pf8bit (8 bit
monochrom/gray sacle) and pf24bit (true color). When applied to a monochrome
image, sliding one scroll bar will move other two scroll bars to reflect that
monochrome image doesn't have any separate RGB components.

4.6. Color Inversion
Color inversion in digital image processing is done by inverting all color element. For
monochrome image, the dark pixel in the original image will be the bright pixel in the
inversed image. The effect show horizontal mirroring in the histogram.

http://imageprocessingindelphi.blogspot.com/

The GST function is simple, the Intensity of the output Io=Imax-Ii, where Imax is the
maximum Intensity value, and Ii is the input pixel's intensity. The maximum intensity
value is 255 for 8bit monochrome or 24bit true color. For 24 bit true color, each RGB
elements is operated independently.

4.7. Color Inversion Processing in Delphi
To implement color inversion is very easy, we don't need a special form for user
interface. We can directly implement the code in the main unit.
1. Open our previous contrast enhancement project.
2. Double click the main menu component, and add a menu item 'Invert' under
Image menu (see figure 1).
3. Double click on the menu item, and you'll be directed to the event handler, edit as
shown below:
view plainprint?
1. procedure TMainForm.Invert1Click(Sender: TObject);
2. var
3. i,j:integer;
4. ptr:PByteArray;
5. begin
6. try
7. ImageForm:=TImageForm(ActiveMDIChild);
8. for i:=0 to (ImageForm.Image1.Height-1) do
9. begin
10. ptr:=ImageForm.Image1.Picture.Bitmap.ScanLine[i];
11. for j:=0 to (ImageForm.Image1.Width-1) do
12. begin
13. if ImageForm.Image1.Picture.Bitmap.PixelFormat
14. =pf8bit then ptr[j]:=255-ptr[j];
15. if ImageForm.Image1.Picture.Bitmap.PixelFormat
16. =pf24bit then
17. begin
18. ptr[3*j]:=255-ptr[3*j];
19. ptr[3*j+1]:=255-ptr[3*j+1];
20. ptr[3*j+2]:=255-ptr[3*j+2];
21. end;
22. end;
23. ImageForm.Image1.Refresh;
http://imageprocessingindelphi.blogspot.com/
24. end;
25. except
26. ShowMessage('Cannot complete the operation');
27. end
28. end;

4. Save all files and now you can compile and run the executable. The execution is
shown in Figure 2 and Figure 3.


Figure 1. Invert Menu



Figure 2. Color Inversion of Monochrome Image

http://imageprocessingindelphi.blogspot.com/

Figure 3. Color Inversion on True Color Picture

Source Code Download
You can download the source code for Delphi 7 here and for Turbo Delphi
Explorer here.

4.8. RGB to Gray Scale Conversion
Intensity of an image is the average of the three color elements, so the gray scale
image that represent the original color image can be computed as:
I0=(Ri+Gi+Bi)/3
Io is the output intensity, Ri, Gi, and Bi are the red, green, and the blue element
intensity. The formula for more realistic result is by adding different weight for each
R,G, and B element. We normally percept green color brighter that red color, and red
color brighter than blue color. That's why we usually set the weight higher for red and
higher for green.
Io=(0.299Ri + 0.587Gi + 0.144Bi)/3
Actually there is no absolute reference for each weight values because it depends on
the display technology that might change in the future. The above formula is
standardized by NTSC (National Television System Committee), and its usage is
common in computer imaging.
http://imageprocessingindelphi.blogspot.com/
4.9. RGB to Gray Scale Conversion Using Delphi
We can code an RGB to Gray scale conversion directly in the main unit of our color
inversion project. It is easy, as easy as our color inversion project.
1. Open our previous color inversion project.
2. Double click the main menu component, and add a menu item 'Convert to Gray
Scale' under Image menu (see figure 1).
3. Double click on the menu item, and you'll be directed to the event handler, edit as
shown below:
view plainprint?
1. procedure TMainForm.ConverttoGrayScale1Click(Sender: TObject);
2. var
3. i,j:integer;
4. ptr:PByteArray;
5. begin
6. try
7. ImageForm:=TImageForm(ActiveMDIChild);
8. for i:=0 to (ImageForm.Image1.Height-1) do
9. begin
10. ptr:=ImageForm.Image1.Picture.Bitmap.ScanLine[i];
11. for j:=0 to (ImageForm.Image1.Width-1) do
12. begin
13. if ImageForm.Image1.Picture.Bitmap.PixelFormat
14. =pf24bit then
15. begin
16. ptr[3*j]:=round(0.114* ptr[3*j]
17. +0.587*ptr[3*j+1] + 0.299*ptr[3*j+2]);
18. ptr[3*j+1]:=ptr[3*j];
19. ptr[3*j+2]:=ptr[3*j];
20. end;
21. end;
22. ImageForm.Image1.Refresh;
23. end;
24. except
25. ShowMessage('Cannot complete the operation');
26. end
27. end;

4. Save all files, and now you can compile/run the project. The execution looks like
shown in figure 2.

http://imageprocessingindelphi.blogspot.com/

Figure 1. RGB to Gray Scale Conversion Menu


Figure 2. RGB to Gray Scale Conversion

Source Code Download
You can download the Delphi 7 source code here, and the Turbo Delphi Explorer
source code here.

http://imageprocessingindelphi.blogspot.com/
4.10. Thresholding
Thresholding in image processing is used to convert a gray scale image to binary
format, where only two values are possible for the pixel, zero ore one. Thresholding
can be viewed as the simplest method of image segmentation. Thresholding is
common step in an image analysis, where we need to differentiate the pixel area by
two different brightness area, for example between object and the background.

Thresholding is the simplest method of image segmentation. From a gray scale
image, thresholding can be used to create binary image (Shapiro, et al 2001:83).
During the thresholding process, individual pixels in an image are marked as
object pixels if their value is greater than some threshold value (assuming an
object to be brighter than the background) and as background pixels otherwise.
This convention is known as threshold above. Variants include threshold below,
which is opposite of threshold above; threshold inside, where a pixel is labeled
"object" if its value is between two thresholds; and threshold outside, which is the
opposite of threshold inside (Shapiro, et al 2001:83).
The most important key in the thresholding process is the threshold point.
Manually, the threshold pint can be visually judged by trial and error, adjusting
the value is you don't get the desired background-object separation.

For Automatic thresholding, many methods have been implemented in many
research. You can simply use the mean or median value, or you can analyze the
histogram and find a valley for the threshold value.

4.11. Threshold Below, Threshold Above, and Threshold Inside Implementation in Delphi
Image Format
Image thresholding process change the image to binary value, zero or one. Ideally, this
binary data is stored in the computer memory as bit format, where 1 byte memory
could store 8 pixels. Unfortunately, the modern computer hardware organization and
software (compiler) technology doesn't handle the bit operation as fast and efficient
as byte operation, so it is better to use ordinary 8bit or 24bit for practical reason,
although it use actually only the least significant bit to store zero or one.

http://imageprocessingindelphi.blogspot.com/
The Graphical User Interface (GUI)
To implement threshold various basic thresholding (below, above, and inside
thresholding points), we need to design the graphical user interface first.
1. Open our previous RGB to gray scale conversion project.
2. Create a new form, resize the form to fit the main form. Set the name property to
ThresholdForm, and set the FormStyle to fsMDIChild. Save the unit as
ThresholdUnit.pas.
3. On the menu Project->Options->Forms, select ThresholdForm (in the auto created
form list) and click the > button, so the ThresholdForm will move from auto
created form list to available forms list, then press OK.
4. Add two CheckBoxes (from standard component pallet) to the form, set the name
properties to InvertCheckBox and ThresholdInsideCheckBox. Set the captions to
"Invert" and "Threshold Inside" respectively.
5. Add two ScrollBars (from standard component pallet) to the form. Set the name
properties to LowScrollBar and HighScrollBar. Set their maximum properties to
255. Set their position properties to 127. Add two labels to address them with
"low" and "high" (see figure 1).
6. Add two buttons to the form, set their name properties to OKButton and
CancelButton, and set their caption properties to OK and Cancel accordingly.
To modify the image, it's common to backup the original image, so we can do a cancel
operation after displaying the change on the original image form. To do this, we have
to provide TImage object in the form to temporarily store the image. A procedure
(SetThreshold) to associate the image input to the threshold form is also needed. To
do this, edit the ThresholdForm abstraction (in the ThresholdUnit.pas) to provide
TImage (TemporaryImage and OriginalImage) object and the SetThreshold procedure
declaration. A boolean flag (Applied) is also needed to mark whether a Cancel or OK
button has been pressed. Add ExtCtrls under uses in the Interface section because use
TImage component. After we edit the ThresholdForm abstraction, the code should
look like below:
view plainprint?
1. interface
2.
3. uses
4. ExtCtrls, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For
ms,
5. Dialogs, StdCtrls;
6.
http://imageprocessingindelphi.blogspot.com/
7. type
8. TThresholdForm = class(TForm)
9. LowScrollBar: TScrollBar;
10. HighScrollBar: TScrollBar;
11. InvertCheckBox: TCheckBox;
12. ThresholdInsideCheckBox: TCheckBox;
13. Label1: TLabel;
14. Label2: TLabel;
15. OKButton: TButton;
16. CancelButton: TButton;
17. private
18. TemporaryImage:TImage;
19. OriginalImage:TImage;
20. Applied:boolean;
21. public
22. procedure SetThreshold(Image: TImage);
23. { Public declarations }
24. end;
The Implementation

(to be continued)

You might also like