home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-07 | 40.0 KB | 613 lines | [TEXT/PJMM] |
- unit Background;
- {************************************************************************}
- {* by Michael Castle and Janice Keller *}
- {* University of Michigan Mental Health Research Institute (MHRI) *}
- {* e-mail address: mike.castle@med.umich.edu *}
- {**************** xval := xpt - patchwidth + ptsbelowlastpatch;
- xpt2 := ptsbelowlastpatch;
- ballpt := ballpt + ptsbelowlastpatch;
- backgrpt := ybackgrpt + (xval - left + 1) * shrinkfactor;
- while xpt2 <= patchwidth do begin {for all the points in the ball patch}
- if ((xval >= left) and (xval <= right) and (yval >= top) and (yval <= bottom)) then begin
- p1 := ptr(ballpt);
- zadd := zctr + BAND(p1^, 255);
- p1 := ptr(backgrpt);
- if (zadd > BAND(p1^, 255)) then {keep largest adjustment}
- p1^ := zadd;
- end;
- ballpt := ballpt + 1;
- xval := xval + 1;
- xpt2 := xpt2 + 1;
- backgrpt := backgrpt + shrinkfactor; {move to next point in x}
- end; {while xpt2}
- yval := yval + 1;
- ypt2 := ypt2 + 1;
- ybackgrpt := ybackgrpt + ybackgrinc; {move to next point in y}
- end; {while ypt2}
- end; {for xpt }
- if ((ypt mod 5) = 0) or not FasterBackgroundSubtraction then begin
- UpdateMeter(20 + ((ypt - top) * 70) div (bottom + patchwidth - top), 'Finding Background...');
- if CommandPeriod then begin
- beep;
- Aborting := true;
- Exit(RollBall);
- end;
- end;
- end; {for ypt}
- end;
-
-
- function MinIn2DMask {(xmaskmin,ymaskmin: integer)}
- : integer;
- {*******************************************************************************}
- {* MinInMask finds the minimum pixel value in a shrinkfactor X shrinkfactor mask. *}
- {*******************************************************************************}
- var
- i, j, {loop indices to step through mask}
- thispixel, {value at current pixel in mask}
- min, {temporary minimum value in mask}
- nextrowoffset: integer; {distance in memory from end of mask in this row to beginning in next}
- paddr: longint; {address of current mask pixel}
- p: ptr; {pointer to current pixel in mask}
- begin
- with info^ do begin
- min := 255;
- nextrowoffset := bytesperrow - shrinkfactor;
- paddr := ord4(PicBaseAddr) + longint(ymaskmin) * bytesperrow + xmaskmin;
- for j := 1 to shrinkfactor do begin
- for i := 1 to shrinkfactor do begin
- p := ptr(paddr);
- thispixel := BAND(p^, 255);
- if (thispixel < min) then
- min := thispixel;
- paddr := paddr + 1;
- end; {for i}
- paddr := paddr + nextrowoffset;
- end; {for j}
- MinIn2DMask := min;
- end; {with}
- end;
-
-
- procedure GetRollingBall;
- {******************************************************************************}
- {* This procedure computes the location of each point on the rolling ball patch relative to the center of the *}
- {* sphere containing it. The patch is located in the top half of this sphere. The vertical axis of the sphere *}
- {* passes through the center of the patch. The projection of the patch in the xy-plane below is a square. *}
- {******************************************************************************}
- var
- rsquare, {rolling ball radius squared}
- xtrim, {# of pixels trimmed off each end of ball to make patch}
- xval, yval, {x,y-values on patch relative to center of rolling ball}
- smallballradius, diam, {radius and diameter of rolling ball}
- temp, {value must be >=0 to take square root}
- halfpatchwidth: integer; {distance in x or y from center of patch to any edge}
- i, {index into rolling ball patch memory}
- ballsize: Size; {size of rolling ball memory}
- p: ptr; {pointer to current point on the ball patch}
- begin
- smallballradius := ballradius div shrinkfactor; {operate on small-sized image with small-sized ball}
- if smallballradius < 1 then
- smallballradius := 1;
- rsquare := smallballradius * smallballradius;
- diam := smallballradius * 2;
- xtrim := (ArcTrimPer * diam) div 100; {only use a patch of the rolling ball}
- patchwidth := diam - xtrim - xtrim;
- halfpatchwidth := smallballradius - xtrim; {this is half the patch width}
- ballsize := longint(patchwidth + 1) * longint(patchwidth + 1);
- ballptr := NewPtrToClearBuf(ballsize);
- p := ballptr;
- for i := 0 to ballsize - 1 do begin
- xval := i mod (patchwidth + 1) - halfpatchwidth;
- yval := i div (patchwidth + 1) - halfpatchwidth;
- temp := rsquare - (xval * xval) - (yval * yval);
- if (temp >= 0) then
- p^ := round(sqrt(temp))
- else
- p^ := 0;
- p := ptr(ord4(p) + 1);
- end;
- end;
-
-
- procedure InterpolateBackground2D; {(leftroll, rightroll, toproll, bottomroll: integer; backgroundaddr: longint)}
- {******************************************************************************}
- {* This procedure uses bilinear interpolation to find the points in the full-scale background given the points *}
- {* from the shrunken image background. Since the shrunken background is found from an image composed of *}
- {* minima (over a sufficiently large mask), it is certain that no point in the full-scale interpolated *}
- {* background has a higher pixel value than the corresponding point in the original image. *}
- {******************************************************************************}
- var
- i, ii, {horizontal loop indices}
- j, jj, {vertical loop indices}
- hloc, vloc, {position of current pixel in calculated background}
- vinc, {memory offset from current calculated pos to current interpolated pos}
- lastvalue, nextvalue: integer; {calculated pixel values between which we are interpolating}
- p, {pointer to current interpolated pixel value}
- bglastptr, bgnextptr: ptr; {pointers to calculated pixel values between which we are interpolating}
- begin
- vloc := 0;
- with BoundRect do begin
- for j := 1 to bottomroll - toproll - 1 do begin {interpolate to find background interior}
- hloc := 0;
- vloc := vloc + shrinkfactor;
- for i := 1 to rightroll - leftroll do begin
- hloc := hloc + shrinkfactor;
- bgnextptr := ptr(backgroundaddr + vloc * longint(right - left) + hloc);
- bglastptr := ptr(ord4(bgnextptr) - shrinkfactor);
- nextvalue := BAND(bgnextptr^, 255);
- lastvalue := BAND(bglastptr^, 255);
- for ii := 1 to shrinkfactor - 1 do begin {interpolate horizontally}
- p := ptr(ord4(bgnextptr) - ii);
- p^ := lastvalue + (shrinkfactor - ii) * (nextvalue - lastvalue) div shrinkfactor;
- end; {for ii}
- for ii := 0 to shrinkfactor - 1 do begin {interpolate vertically}
- bglastptr := ptr(backgroundaddr + (vloc - shrinkfactor) * longint(right - left) + hloc - ii);
- bgnextptr := ptr(backgroundaddr + vloc * longint(right - left) + hloc - ii);
- lastvalue := BAND(bglastptr^, 255);
- nextvalue := BAND(bgnextptr^, 255);
- vinc := 0;
- for jj := 1 to shrinkfactor - 1 do begin
- vinc := vinc - right + left;
- p := ptr(ord4(bgnextptr) + vinc);
- p^ := lastvalue + (shrinkfactor - jj) * (nextvalue - lastvalue) div shrinkfactor;
- end; {for jj}
- end; {for ii}
- end; {for i}
- end; {for j}
- end; {with boundrect}
- end;
-
-
- procedure ExtrapolateBackground2D; {(leftroll, rightroll, toproll, bottomroll: integer; backgroundaddr: longint)}
- {******************************************************************************}
- {* This procedure uses linear extrapolation to find pixel values on the top, left, right, and bottom edges of *}
- {* the background. First it finds the top and bottom edge points by extrapolating from the edges of the *}
- {* calculated and interpolated background interior. Then it uses the edge points on the new calculated, *}
- {* interpolated, and extrapolated background to find all of the left and right edge points. If extrapolation yields *}
- {* values below zero or above 255, then they are set to zero and 255 respectively. *}
- {******************************************************************************}
- var
- ii, jj, {horizontal and vertical loop indices}
- hloc, vloc, {position of current pixel in calculated/interpolated background}
- edgeslope, {difference of last two consecutive pixel values on an edge}
- pvalue, {current extrapolated pixel value}
- lastvalue, nextvalue: integer; {calculated pixel values from which we are extrapolating}
- p, {pointer to current extrapolated pixel value}
- bglastptr, bgnextptr: ptr; {pointers to calculated pixel values from which we are extrapolating}
- begin
- with BoundRect do begin
- for hloc := shrinkfactor to shrinkfactor * (rightroll - leftroll) - 1 do begin {extrapolate on top and bottom}
- bglastptr := ptr(backgroundaddr + shrinkfactor * longint(right - left) + hloc);
- bgnextptr := ptr(backgroundaddr + (shrinkfactor + 1) * longint(right - left) + hloc);
- lastvalue := BAND(bglastptr^, 255);
- nextvalue := BAND(bgnextptr^, 255);
- edgeslope := nextvalue - lastvalue;
- p := bglastptr;
- pvalue := lastvalue;
- for jj := 1 to shrinkfactor do begin
- p := ptr(ord4(p) - right + left);
- pvalue := pvalue - edgeslope;
- if (pvalue < 0) then
- p^ := 0
- else if (pvalue > 255) then
- p^ := 255
- else
- p^ := pvalue;
- end; {for jj}
- bglastptr := ptr(backgroundaddr + (shrinkfactor * (bottomroll - toproll - 1) - 1) * longint(right - left) + hloc);
- bgnextptr := ptr(backgroundaddr + shrinkfactor * (bottomroll - toproll - 1) * longint(right - left) + hloc);
- lastvalue := BAND(bglastptr^, 255);
- nextvalue := BAND(bgnextptr^, 255);
- edgeslope := nextvalue - lastvalue;
- p := bgnextptr;
- pvalue := nextvalue;
- for jj := 1 to (bottom - top - 1) - shrinkfactor * (bottomroll - toproll - 1) do begin
- p := ptr(ord4(p) + right - left);
- pvalue := pvalue + edgeslope;
- if (pvalue < 0) then
- p^ := 0
- else if (pvalue > 255) then
- p^ := 255
- else
- p^ := pvalue;
- end; {for jj}
- end; {for hloc}
- for vloc := top to bottom - 1 do begin {extrapolate on left and right}
- bglastptr := ptr(backgroundaddr + (vloc - top) * longint(right - left) + shrinkfactor);
- bgnextptr := ptr(ord4(bglastptr) + 1);
- lastvalue := BAND(bglastptr^, 255);
- nextvalue := BAND(bgnextptr^, 255);
- edgeslope := nextvalue - lastvalue;
- p := bglastptr;
- pvalue := lastvalue;
- for ii := 1 to shrinkfactor do begin
- p := ptr(ord4(p) - 1);
- pvalue := pvalue - edgeslope;
- if (pvalue < 0) then
- p^ := 0
- else if (pvalue > 255) then
- p^ := 255
- else
- p^ := pvalue;
- end; {for ii}
- bgnextptr := ptr(backgroundaddr + (vloc - top) * longint(right - left) + shrinkfactor * (rightroll - leftroll - 1) - 1);
- bglastptr := ptr(ord4(bgnextptr) - 1);
- lastvalue := BAND(bglastptr^, 255);
- nextvalue := BAND(bgnextptr^, 255);
- edgeslope := nextvalue - lastvalue;
- p := bgnextptr;
- pvalue := nextvalue;
- for ii := 1 to (right - left - 1) - shrinkfactor * (rightroll - leftroll - 1) + 1 do begin
- p := ptr(ord4(p) + 1);
- pvalue := pvalue + edgeslope;
- if (pvalue < 0) then
- p^ := 0
- else if (pvalue > 255) then
- p^ := 255
- else
- p^ := pvalue;
- end; {for ii}
- end; {for vloc}
- end; {with BoundRect}
- end;
-
-
- procedure SubtractBackground2D;
- {*****************************************************************************}
- {* This procedure subtracts each pixel from the calculated/interpolated/extrapolated background from the *}
- {* corresponding pixel value in the original image. The resulting image is stored in place of the original *}
- {* image. Any pixel subtractions with results below zero are given the value zero. *}
- {*****************************************************************************}
- var
- hloc, vloc, {current pixel location in image and background}
- pvalue: integer; {difference at current pixel location}
- offset, {offset in memory from beginning of original image to current scan line}
- backgrpt: LongInt; {offset to current point in background}
- p: ptr; {temporary pointer to image or background points}
- Databand: Linetype; {current scan line in image}
- ControlKey: boolean;
- begin
- backgrpt := 0;
- ControlKey := ControlKeyDown;
- with Info^, BoundRect do begin
- for vloc := top to bottom - 1 do begin
- GetLine(0, vloc, pixelsperline, Databand);
- for hloc := left to right - 1 do begin
- p := ptr(backgroundaddr + backgrpt);
- pvalue := Databand[hloc] - BAND(p^, 255);
- if ControlKey then
- pvalue := BAND(p^, 255);
- if pvalue < 0 then
- Databand[hloc] := 0
- else
- Databand[hloc] := pvalue;
- backgrpt := backgrpt + 1;
- end; {for}
- offset := LongInt(vloc) * BytesPerRow;
- p := ptr(ord4(PicBaseAddr) + offset);
- BlockMove(@Databand, p, pixelsperline);
- end; {for}
- end; {with}
- end;
-
-
- procedure Background2D;
- {******************************************************************************}
- {* This procedure implements a rolling-ball algorithm for the removal of smooth continuous background *}
- {* from a two-dimensional gel image. It rolls the ball (actually a square patch on the top of a sphere) on a *}
- {* low-resolution (by a factor of 'shrinkfactor' times) copy of the original image in order to increase speed *}
- {* with little loss in accuracy. It uses interpolation and extrapolation to blow the shrunk image to full size. *}
- {******************************************************************************}
- var
- tport: Grafptr;
- i, {loop index for shrunk image memory}
- backgroundsize, {size of the background memory}
- smallimagesize: Size; {size of the shrunk image memory}
- p: ptr; {pointer to current pixel in shrunk image memory}
- table: FateTable; {not used}
- begin
- ShowWatch;
- UpdateMeter(0, 'Building Rolling Ball...');
- GetPort(tPort);
- with Info^ do begin
- SetPort(GrafPtr(osPort));
- BoundRect := roiRect;
- end;
- GetRollingBall; {precompute the rolling ball}
- UpdateMeter(3, 'Building Rolling Ball...');
- balladdr := ord4(ballptr);
- with BoundRect do begin
- leftroll := left div shrinkfactor; {left and right edges of shrunken image or roi}
- rightroll := right div shrinkfactor - 1; {on which to roll ball}
- toproll := top div shrinkfactor;
- bottomroll := bottom div shrinkfactor - 1;
- backgroundsize := longint(right - left) * longint(bottom - top);
- backgroundptr := NewPtrToClearBuf(backgroundsize);
- Aborting := backgroundptr = nil;
- backgroundaddr := ord4(backgroundptr);
- smallimagesize := longint(rightroll - leftroll + 1) * longint(bottomroll - toproll + 1);
- smallimageptr := NewPtrToClearBuf(smallimagesize);
- Aborting := Aborting or (smallimageptr = nil);
- smallimageaddr := ord4(smallimageptr);
- if not aborting then begin
- UpdateMeter(6, 'Smoothing Image ');
- filter(unweightedAvg, 1, table); {smooth image before shrinking}
- UpdateMeter(10, concat('Shrinking Image ', long2str(shrinkfactor), ' times...'));
- for i := 0 to smallimagesize - 1 do begin {create a lower resolution image for ball-rolling}
- p := ptr(smallimageaddr + i);
- xmaskmin := left + shrinkfactor * (i mod (rightroll - leftroll + 1));
- ymaskmin := top + shrinkfactor * (i div (rightroll - leftroll + 1));
- p^ := MinIn2DMask; {each point in small image is minimum of its neighborhood}
- end;
- if not aborting then begin
- Undo; {restore original unsmoothed image}
- RollBall;
- end;
- end
- else
- beep;
- if not Aborting then begin
- UpdateMeter(90, 'Interpolating Background...');
- InterpolateBackground2D; {interpolate to find background interior}
- UpdateMeter(95, 'Extrapolating Background...');
- ExtrapolateBackground2D; {extrapolate on top and bottom}
- UpdateMeter(98, 'Subtracting Background...');
- SubtractBackground2D; {subtract background from original image}
- UpdateMeter(100, 'Subtracting Background...');
- end;
- end; {with boundrect}
- DisposPtr(backgroundptr); {free up background, rolling ball, shrunk image memory}
- DisposPtr(ballptr);
- DisposPtr(smallimageptr);
- DisposeWindow(MeterWindow);
- MeterWindow := nil;
- SetPort(tPort);
- end;
-
-
- procedure RollArc (left, rightminusone, diam: integer; var background, ballpoints: IntRow; var Dataline: Linetype);
- var
- xpt, xpt2, xval, ydif, ymin, yctr, bpt, yadd: integer;
- begin
- for xpt := left to rightminusone do begin
- background[xpt] := -255; {init background curve to minimum values}
- end;
- yctr := 0; {start y-center at the x axis}
- for xpt := left to (rightminusone + diam - 1) do {while semicircle is tangent to edges or within curve...}
- begin {xpt is far right edge of semi-circle}
- {do we have to move the circle?...}
- ymin := 256; {highest could ever be 255}
- bpt := 0;
- xpt2 := xpt - diam; {xpt2 is far left edge of semi-circle}
- while xpt2 <= xpt do {check every point on semicircle}
- begin
- if ((xpt2 >= left) and (xpt2 <= rightminusone)) then begin {only examine points on curve}
- ydif := dataline[xpt2] - (yctr + ballpoints[bpt]); {curve minus circle points}
- if (ydif < ymin) then begin {keep most negative, since ball should always be below curve}
- ymin := ydif;
- end;
- end; {if xpt2 }
- bpt := bpt + 1;
- xpt2 := xpt2 + 1;
- end; {while xpt2 }
- if (ymin <> 256) then{if we found a new minimum...}
- yctr := yctr + ymin; {move circle up or down}
- {now compare every point on semi with background, and keep highest number}
- xval := xpt - diam;
- xpt2 := 0;
- while xpt2 <= diam do begin {for all the points in the semicircle}
- if ((xval >= left) and (xval <= rightminusone)) then begin
- yadd := yctr + ballpoints[xpt2];
- if (yadd > background[xval]) then {keep largest adjustment}
- background[xval] := yadd;
- end;
- xval := xval + 1;
- xpt2 := xpt2 + 1;
- end; {while xpt2}
- end; {for xpt }
- end;
-
-
- function MinIn1DMask (var Databand: LineType; xcenter: integer): integer;
- {*******************************************************************************}
- {* MinIn1DMask finds the minimum pixel value in a (2*shrinkfactor-1) mask about the point xcenter in the *}
- {* current line. This code must run FAST because it gets called OFTEN! *}
- {*******************************************************************************}
- var
- i, {index to pixels in the mask}
- temp: integer; {temporary minimum value}
- begin
- temp := Databand[xcenter - shrinkfactor + 1];
- for i := xcenter - shrinkfactor + 2 to xcenter + shrinkfactor - 1 do
- if (Databand[i] < temp) then
- temp := Databand[i];
- MinIn1DMask := temp;
- end;
-
-
- {******************************************************************************}
- {* This procedure computes the location of each point on the rolling arc relative to the center of the circle *}
- {* containing it. The arc is located in the top half of this circle. The vertical axis of the circle passes through *}
- {* the midpoint of the arc. The projection of the arc on the x-axis below is a line segment. *}
- {******************************************************************************}
- procedure GetRollingArc (var arcpoints: IntRow; var arcwidth: integer);
- var
- xpt, {x-point along arc}
- xval, {x-point in arc array}
- rsquare, {shrunken arc radius squared}
- xtrim, {points to be trimmed off each end of arc}
- smallballradius, {radius of shrunken arc which actually rolls}
- diam: integer; {diameter of shrunken arc's circle}
- begin
- smallballradius := ballradius div shrinkfactor; { operate on small-sized image with small-sized ball}
- rsquare := smallballradius * smallballradius;
- for xpt := -smallballradius to smallballradius do { find the ballpoints for arc based at (x,y)=(0,0) }
- begin
- xval := xpt + smallballradius; {offset, can't have negative index}
- arcpoints[xval] := round(sqrt(abs(rsquare - (xpt * xpt)))); {Ys are positive, top half of circle}
- end;
- diam := smallballradius * 2;
- xtrim := (ArcTrimPer * diam) div 100; {how many points to trim off each end}
- arcwidth := diam - xtrim - xtrim;
- for xpt := -smallballradius to smallballradius - xtrim - xtrim do begin
- xval := xpt + smallballradius;
- arcpoints[xval] := arcpoints[xval + xtrim];
- end;
- for xpt := smallballradius - xtrim - xtrim + 1 to smallballradius do begin
- xval := xpt + smallballradius;
- arcpoints[xval] := 0;
- end;
- end;
-
-
- procedure ExtrapolateBackground1D (var Backline, Dataline: LineType; background: IntRow; leftroll, rightroll: integer);
- {******************************************************************************}
- {* This procedure uses linear extrapolation to find pixel values on the left and right edges of the current *}
- {* line of the background. It finds the edge points by extrapolating from the edges of the calculated and *}
- {* interpolated background interior. If extrapolation yields values below zero or above 255, then they are set *}
- {* to zero and 255 respectively. *}
- {********* umpixels); {fast whole line write}
- end;
- RollingVerticalArc:
- PutColumn(vloc, 0, numpixels, Dataline); {slow whole column write}
- end; {case}
- if ((vloc mod 8) = 0) and (vloc > 16) then begin
- UpdateMeter((LongInt(vloc - top) * 100) div (bottom - top - 1), str);
- if CommandPeriod then begin
- beep;
- Aborting := true;
- leave;
- end;
- end;
- end;
- UpdateMeter(100, str);
- DisposeWindow(MeterWindow);
- MeterWindow := nil;
- SetPort(tPort);
- end;
-
- procedure SetUpGel;
- var
- frame: rect;
- AutoSelectAll: boolean;
- p: ptr;
- begin
- if NotinBounds or NotRectangular then
- exit(SetUpGel);
- StopDigitizing;
- AutoSelectAll := not Info^.RoiShowing;
- if AutoSelectAll then
- SelectAll(false);
- SetupUndoFromClip;
- with info^ do begin
- frame := roiRect;
- if ((LutMode = GrayScale) or (LutMode = CustomGrayscale)) and (not IdentityFunction) then
- ApplyLookupTable;
- changes := true;
- end;
- case BackSubKind of
- RollingHorizontalArc, RollingVerticalArc:
- Background1D; {--------------> call background subtract <-------------------}
- RollingBall:
- Background2D;
- RollingBothArcs: begin
- BackSubKind := RollingHorizontalArc; {remove horizontal streaks}
- Background1D;
- BackSubKind := RollingVerticalArc; {remove vertical streaks}
- if not aborting then
- Background1D;
- BackSubKind := RollingBothArcs; {leave BackSubKind as we found it}
- end;
- end; {case}
- UpdatePicWindow;
- SetUpRoiRect;
- WhatToUndo := UndoFilter;
- Info^.changes := true;
- ShowWatch;
- if AutoSelectAll then
- KillRoi;
- if Aborting then begin
- Undo;
- WhatToUndo := NothingToUndo;
- UpdatePicWindow;
- end;
- end;
-
-
- procedure GetBallRadius;
- var
- SaveRadius: integer;
- canceled: boolean;
- begin
- SaveRadius := BallRadius;
- BallRadius := GetInt('Rolling BallRadius:', BallRadius, canceled);
- if (BallRadius < 1) or (BallRadius > 319) or canceled then begin
- BallRadius := SaveRadius;
- if not canceled then
- beep;
- end;
- end;
-
-
- procedure DoBackgroundMenuEvent (MenuItem: integer);
- var
- map_array: Ptr;
- begin
- MeterWindow := nil;
- Aborting := false;
- case MenuItem of
- HorizontalItem, VerticalItem: begin
- if FasterBackgroundSubtraction then begin
- ArcTrimPer := 20;
- shrinkfactor := 4;
- end
- else begin
- ArcTrimPer := 10;
- shrinkfactor := 2;
- end;
- if MenuItem = HorizontalItem then
- BackSubKind := RollingHorizontalArc
- else
- BackSubKind := RollingVerticalArc;
- SetUpGel;
- end;
- Sub2DItem: begin
- if FasterBackgroundSubtraction then begin
- if BallRadius > 15 then begin
- ArcTrimPer := 20; {trim 40% in x and y}
- shrinkfactor := 8;
- end
- else begin
- ArcTrimPer := 16; {trim 32% in x and y}
- shrinkfactor := 4;
- end
- end
- else begin {faster not checked}
- if BallRadius > 15 then begin
- ArcTrimPer := 16; {trim 32% in x and y}
- shrinkfactor := 4;
- end
- else begin
- ArcTrimPer := 12; {trim 24% in x and y}
- ShrinkFactor := 2;
- end
- end;
- BackSubKind := RollingBall;
- SetUpGel;
- end;
- RemoveStreaksItem: begin
- ArcTrimPer := 20;
- shrinkfactor := 4;
- BackSubKind := RollingBothArcs;
- SetUpGel;
- end;
- FasterItem:
- FasterBackgroundSubtraction := not FasterBackgroundSubtraction;
- RadiusItem:
- GetBallRadius;
- end; {case}
- end;
-
-
- end.