Binary mask - TfiBinMask class
TfiBinMask have a very simple public interface and provide an easy way to produce binary masks. These masks can be used to define a ROI (Region Of Interest) inside a channel, as structuring elements in morphological operations or to perform match operations.
Creating binary masks
To create masks using TfiBinMask you can define your mask in a string list and call the method MakeFromStrings. Parameters BaseX and BaseY informs the base point of mask related to string list. Character ‘1’ on string list means object, or active pixel. Character ‘0’ means background, or inactive pixel. Any other character means ‘don’t care’. Don’t use the character ‘0’ to create masks for morphological operations or to define a ROI. This option is only for match operations. See the example below that creates a 5x5 diamond mask. You also can create masks manually, point by point directly adding points with Add method. In this case you must calculate the offset of points related to base point. See the discussion in next topic for more details.
var
mask: TfiBinMask;
sts: TStringList;
fImg: TFastImageEx;
begin
[…]
sts:= TStringList.Create;
sts.Add(‘ 1’);
sts.Add(‘ 111’);
sts.Add(‘11111’);
sts.Add(‘ 111’);
sts.Add(‘ 1’);
mask:= TfiBinMask.Create;
mask.MakeFromStrings(sts, 2, 2);
sts.Free;
// mask is ready to use now
fImg.Dilate(fi_ALL_CHANNELS, fi_INPLACE_CHN, 1, mask, true);
mask.Free;
[…]
end;
Public definition of TfiBinMask
Below, the public methods and properties of TfiBinMask. A mask is basically a list of points in a coordinate system with origin in base point (BaseX and BaseY). So, the points store the offset related to base point. When the points are added, the maximum and minimum values from coordinate’s points are stored. These values are used to calculate the rectangle returned by SizeAsRect property and the dimensions of mask returned by properties Width, Height and iSize. Property Items (default) allow access to point’s list.
type
TMaskBinPoint = class
dx, dy: integer;
Value: boolean;
constructor Create(adx, ady: integer; aValue: boolean);
end;
TfiBinMask = class(TList)
public
constructor Create;
function Add(Pt: TMaskBinPoint): integer;
function Get(index: integer): TMaskBinPoint;
procedure AssignChannel(Chn: TfiChannel);
procedure ReleaseChannel;
function Match(x, y: integer): boolean;
function ErodeBin(x,y: integer): single;
function ErodeGray(x,y: integer): single;
function DilateBin(x,y: integer): single;
function DilateGray(x,y: integer): single;
function MakeFromStrings(Sts:TStrings; BaseX, BaseY: integer): boolean;
//
// properties
property Width: integer;
property Height: integer;
property iSize: TfiSize;
property SizeAsRect: TRect;
property Items[index:integer]:TMaskBinPoint; default;
end;
Advanced use
TfiBinMask can be used in basic way to define structuring elements to morphological operations or to define a ROI to statistics calculations. For this is enough creating the mask, passes it in parameters of appropriate methods and then destroy the mask. But is also possible use the mask to perform more advanced functions.
The mask has an internal mechanism to move through a channel running some predefined operations. Actually, that's how most of morphological functions use the mask. To use this feature, you must first associate the mask with a channel of image. After that, you can call the methods available informing the position on channel were the operations must be performed. All these operations are available from images or channels, and to process an entire channel or all channels on image, is better (and faster) to process from channel or image. But if you need process one or few pixels on channel, you can use this feature directly from mask. See the example below.
var
mask: TfiBinMask;
sts: TStringList;
fImg: TFastImageEx;
begin
[…]
// Mask to detect top left corners
sts:= TStringList.Create;
sts.Add(‘000’);
sts.Add(‘011’);
sts.Add(‘011’);
mask:= TfiBinMask.Create;
mask.MakeFromStrings(sts, 1, 1);
sts.Free;
mask.AssignChannel(fImg[fi_BIN]);
if mask.Match(10, 10) then
begin
// there is a top left corner on (10, 10) position
[…]
end;
mask.ReleaseChannel;
mask.Free;
end;
Mask operations
function Match(x, y: integer): boolean;
Test if every point in mask match with pixels on channel at position informed. Is a binary operation, a pixel is considered active if their value is different of zero or inactive if their value is zero. Return true if each point on mask match with corresponding pixel on image.
function ErodeBin(x,y: integer): single;
function DilateBin(x,y: integer): single;
Return the value of binary erosion/dilation on pixel at position informed.
function ErodeGray(x,y: integer): single;
function DilateGray(x,y: integer): single;
Return the value of gray erosion/dilation on pixel at position informed
Gray mask - TfiGrayMask class
This class provides a mask with non-binary values. It’s similar with binary mask, but the points can assume any value and mask can have a weight to divide the result. The main purpose of this mask is support filtering operations. To create a gray mask, you also can use a string list with values of points. The values must be separated by spaces and character ‘x’ means ‘don’t care’. The example below creates two masks with Sobel operators:
var
sobHz, sobVt: TfiGrayMask;
sts: TStringList;
fImg: TFastImageEx;
begin
[…]
// Sobel vertical operator
sts:= TStringList.Create;
sts.Add(‘1 x -1’);
sts.Add(‘2 x -2’);
sts.Add(‘1 x -1’);
sobVt:= TfiGrayMask.Create;
sobVt.MakeFromStrings(sts, 1, 1, 1);
sts.Free;
// Sobel horizontal operator
sts:= TStringList.Create;
sts.Add(‘ 1 2 1’);
sts.Add(‘ x x x’);
sts.Add(‘-1 -2 -1’);
sobHz:= TfiGrayMask.Create;
sobHz.MakeFromStrings(sts, 1, 1, 1);
sts.Free;
[…]
end;
Public definition of TfiGrayMask class
type
TMaskGrayPoint = class
dx, dy: integer;
value: single;
constructor Create(adx, ady: integer; aValue: single);
end;
TfiGrayMaskCustom = class(TfiBaseMask)
public
constructor Create;
function CalcPos(x,y: integer): single;
function ErodeGray(x,y: integer): single;
function DilateGray(x,y: integer): single;
function Add(Pt: TMaskGrayPoint): integer;
function Get(index: integer): TMaskGrayPoint;
function MakeFromStrings(Sts: TStrings; BaseX, BaseY: integer;
Weight: single = 1): boolean;
property Items[index:integer]:TMaskGrayPoint; default;
end;
Gray mask operations
The gray mask works in a manner very similar to the binary mask. The main difference is that the image is always seen in gray level, never binary.
function CalcPos(x,y: integer): single;
The value of each point on the mask is multiplied by the corresponding pixel in the image and the result of the multiplications are summed and then divided by the weight associated with the mask.
function ErodeGray(x,y: integer): single;
Performs gray erosion at the point indicated. The difference between doing the erosion with gray mask and binary mask is that the result with the mask gray is the minimum value obtained by subtracting the pixel with the corresponding point of the mask. Using binary mask the result is the minimum value of the pixels covered by mask.
function DilateGray(x,y: integer): single;
Performs gray dilation at the point indicated. The difference between doing the dilation with gray mask and binary mask is that the result with the mask gray is the maximum value obtained by adding the pixel with the corresponding point of the mask. Using binary mask the result is the maximum value of the pixels covered by mask.