// GetROI_CAL_RGB_VIS
//
// ROI calibration based on Histogram treshold on multiple frames
procedure GetROI_CAL_RGB_VIS
(prgb: pRGBTRIPLE;
//Pointer to first pixel
cxImage, cyImage:integer;
//Width, Height of total image
ShowBoundingBox,
//if !0, Bounding Box is drawn
ShowROIHistogram: boolean;
//if !0, ROI Histogram is drawn
roiPosArray: pInteger;
//Array containg ROI positions
roiMask: pBoolean;
//Mask,pixel[i] is in ROI if roiMask[i]
minLeft, maxLeft: pinteger;
//Vertical Bounding Box Scanlines
minTop, maxTopa: pinteger;
//Horizontal Bounding Box Scanlines
numROIPixels: pinteger;
//number of pixels contained in ROI
Check4Rect: boolean;
//1 = check for ellipse and rectangle, 0 just ellipse
fROICutOffLevel: single);
//ROI minimal Histogram presence
//declares
var V:BYTE;
//Brightness (V=Max(R,G,B))
R,G,B:BYTE;
//Red, Green, Blue
Histogram[LENBYTE]: integer;
//={0}; //Brightness Histogram for this frame
const int numPixels = cxImage*cyImage;
//Total number of pixels
BYTE roiTreshold;
//Treshold for non-ROI exclusion
static BYTE roiHistogramMax=0;
//Maximum of times a certain pixel was in ROI
register idx;
//Loop counter for pixels
static BYTE roiHistogram[STATICMASKSIZE] =
{0};
//Times a pixel was included to ROI because of low brightness
RGBTRIPLE* prgb0 = prgb;
//Pointer to pixel (0,0)
const int centerCrossRadius = 5;
//Size of the cross mark representing the center.
int* YPosArray;
//Array containing vertical roi-edges
int* PosArrayRect;
//temp. array containing roi-edges
static bool OTSUMask[STATICMASKSIZE];
//mask containing !0 for each pix>OTSUthreshold
static bool EllipseMask[STATICMASKSIZE];
//mask derived from the ellipse approximation
static bool RectMask[STATICMASKSIZE];
//mask derived from the rectangle approximation
static int ROIBase=0;
//Contains counter for number of frames the roi is based on
begin
//allocate memory for temporary buffers
YPosArray = (int*) calloc(cxImage*2,sizeof(int));
PosArrayRect = (int*) calloc(cyImage*2,sizeof(int));
//Flip Bounding Box fictive values, which are adjusted later on
*minTop=cyImage-1,
*maxTop=0;
*minLeft=cxImage-1;
*maxLeft=0;
//Build Brightness Histogram of this frame only
GetBrightnessHistogram(prgb, numPixels, 0, Histogram);
prgb=prgb0;
//Get Treshold for roi and store it in variable roiTreshold
roiTreshold = (BYTE)(ROISENSE*getTresholdOTSU(Histogram, numPixels));
//Find roi using treshold and create a roi/time histogram
for (prgb=prgb0, idx=0; idx < numPixels; idx++, prgb++)
{
//processing in RGB space, V-channel = max(R,G,B)
GetRGB(prgb,&R,&G,&B);
V=GetTripleMax(R,G,B);
if ((V > roiTreshold) && (V<=MAXBYTE)){
//Store the fact that this pixel was >OSTU threshold
// DO NOT use V >= roiThreshold
// (why? test an image with an image containing only values of 0 and 255)
OTSUMask[idx]=1;
if (roiHistogram[idx] < MAXBYTE){
//Raise number of times this pixel was included in ROI, with a max of MAXBYTE
roiHistogram[idx]++;
if (roiHistogram[idx] > roiHistogramMax)
roiHistogramMax = roiHistogram[idx];
} // roiHistogram<MAXBYTE
}
else
{
OTSUMask[idx]=0;
// added by BF in order to be able to remove errand pixels again from roi:
if (roiHistogram[idx] > 0)
roiHistogram[idx]--;
} // else
//Set this pixel to 1 in the mask if they are more then % of the times
//detected as higher than the treshold
//else added by BF, Jul 11, 2003
if ((roiHistogram[idx] / (float)roiHistogramMax) > fROICutOffLevel)
roiMask[idx] = 1;
else
roiMask[idx] = 0;
}
// for prgb,idx
prgb = prgb0;
ROIBase++;