{from Globals.header} var Raw16Pid, Raw8Pid, RawANDPid, RawB16Pid: integer; RawHeight, RawMaskPid, RawWidth, rawDirID, rawVRefNum: integer; frameType, firstFrame, lastFrame, nextFrame, skipFrame: integer; fore, foredef, cropheight, cropwidth, maskheight: integer; maskwidth, b16Pid, i16Pid, s16Pid, m16Pid: integer; o16Pid, i8Pid, referencePid, smoothPid, markPid: integer; maskPid, mask1Pid, mask2Pid, mask3Pid, dilatePid: integer; flagPid, kernelPid, rbKerPid, xlate16uTo8P, std65535Pid: integer; std8191Pid, customLUTPid, xmax, xmin, ymax: integer; ymin, pack16Pid, packDirID, packMarkPid, packVRefNum: integer; {initialize global variables} begin requiresUser('Pixel16u',2); requiresUser('GetPutPixel',1); requiresUser('timer',1); requiresUser('utilities',1); requiresUser('markup',1); {info about the raw data} Raw16Pid := GetMemo('Raw16Pid'); Raw8Pid := GetMemo('Raw8Pid'); RawANDPid := GetMemo('RawANDPid'); RawB16Pid := GetMemo('RawB16Pid'); RawHeight := GetMemo('RawHeight'); RawMaskPid := GetMemo('RawMaskPid'); RawWidth := GetMemo('RawWidth'); rawDirID := GetMemo('rawDirID'); rawVRefNum := GetMemo('rawVRefNum'); {raw data frame numbers} frameType := GetMemo('frameType'); firstFrame := GetMemo('firstFrame'); lastFrame := GetMemo('lastFrame'); nextFrame := GetMemo('nextFrame'); skipFrame := GetMemo('skipFrame'); {mark color} fore := GetMemo('fore'); foredef := GetMemo('foredef'); {cropped image dimensions} cropheight := GetMemo('cropheight'); cropwidth := GetMemo('cropwidth'); maskheight := GetMemo('maskheight'); maskwidth := GetMemo('maskwidth'); {scratch image pidNumbers} b16Pid := GetMemo('b16Pid'); i16Pid := GetMemo('i16Pid'); s16Pid := GetMemo('s16Pid'); m16Pid := GetMemo('m16Pid'); o16Pid := GetMemo('o16Pid'); i8Pid := GetMemo('i8Pid'); referencePid := GetMemo('referencePid'); smoothPid := GetMemo('smoothPid'); markPid := GetMemo('markPid'); maskPid := GetMemo('maskPid'); mask1Pid := GetMemo('mask1Pid'); mask2Pid := GetMemo('mask2Pid'); mask3Pid := GetMemo('mask3Pid'); dilatePid := GetMemo('dilatePid'); flagPid := GetMemo('flagPid'); {kernel information} kernelPid := GetMemo('kernelPid'); rbKerPid := GetMemo('rbKerPid'); xlate16uTo8P := GetMemo('xlate16uTo8P'); std65535Pid := GetMemo('std65535Pid'); std8191Pid := GetMemo('std8191Pid'); customLUTPid := GetMemo('customLUTPid'); xmax := GetMemo('xmax'); xmin := GetMemo('xmin'); ymax := GetMemo('ymax'); ymin := GetMemo('ymin'); {packed stack info} pack16Pid := GetMemo('pack16Pid'); packDirID := GetMemo('packDirID'); packMarkPid := GetMemo('packMarkPid'); packVRefNum := GetMemo('packVRefNum'); if pidExists(GetMemo('frontPid')) then selectPic(GetMemo('frontPid')); {end from Globals.header} {options automatically selected for this macro file} SetOptions('User1,User2'); ResetCounter; MarkupHide; SetBackgroundColor(0); if fore < 1 then fore := 1; if fore > 20 then fore := 20; SetMemo('fore', fore); SetForegroundColor(fore); SetDensitySlice(fore,fore); end; macro '[F5] 16 bit arithmetic'; begin SetMemo('frontPid', pidNumber); SelectWindow('16 bit arithmetic'); LoadMacros; end; macro '[F6] Adjust 16 bit LUT'; begin SetMemo('frontPid', pidNumber); SelectWindow('Adjust 16 bit LUT'); LoadMacros; end; macro '[F7] Calculate Intensity'; begin SetMemo('frontPid', pidNumber); SelectWindow('Calculate Intensity'); LoadMacros; end; macro '[F8] Create Kernels'; begin SetMemo('frontPid', pidNumber); SelectWindow('Create Kernels'); LoadMacros; end; macro '[F9] Examine Old 16 bit Stacks'; begin SetMemo('frontPid', pidNumber); SelectWindow('Examine Old 16 bit Stacks'); LoadMacros; end; macro '([F10] Examine Packed 16 bit stack'; begin end; macro '[F11] Examine Raw Data'; begin SetMemo('frontPid', pidNumber); SelectWindow('Examine Raw Data'); LoadMacros; end; macro '[F12] Front Image Is ...'; begin SetMemo('frontPid', pidNumber); SelectWindow('Front Image Is ...'); LoadMacros; end; macro '(-'; begin end; procedure checkPids; var width, height: integer; begin RequiresUser('Pixel16u', 1); if not pidExists(smoothPid) then begin PutMessage('Please run macro "Front image is smoothing kernel"'); Exit; end; if not pidExists(kernelPid) then begin PutMessage('Please run macro "Front image is background kernel"'); Exit; end; if not pidExists(maskPid) then begin PutMessage('Please run macro "Front image is mask image"'); Exit; end; if not pidExists(pack16Pid) then begin {PutMessage('Please run macro "Front image is packed 16 bit stack"');} {Exit;} end; if not pidExists(xlate16uTo8P) then begin PutMessage('Please run macro "Front image is 16 to 8 conversion table"'); Exit; end; if not pidExists(i8Pid) then begin selectPic(maskPid); GetPicSize(width, height); SetNewSize(width, height); MakeNewWindow('8 bit image'); i8Pid := pidNumber; SetMemo('i8Pid', i8Pid); end; if not pidExists(i16Pid) then begin selectPic(maskPid); GetPicSize(width, height); SetNewSize(2 * width, height); MakeNewWindow('16 bit image'); i16Pid := pidNumber; SetMemo('i16Pid', i16Pid); end; if not pidExists(b16Pid) then begin selectPic(maskPid); GetPicSize(width, height); SetNewSize(2 * width, height); MakeNewWindow('16 bit background -- trash'); b16Pid := pidNumber; SetMemo('b16Pid', b16Pid); end; if not pidExists(markPid) then begin selectPic(maskPid); GetPicSize(width, height); SetNewSize(width, height); MakeNewWindow('8 bit mark image -- trash'); markPid := pidNumber; SetMemo('markPid', markPid); end; end; macro 'Dispose packed 16 bit stack CAREFUL!'; begin if pidExists(maskPid) then begin choosePic(maskPid); dispose; end; if pidExists(pack16Pid) then begin choosePic(pack16Pid); dispose; end; if pidExists(packMarkPid) then begin choosePic(packMarkPid); dispose; end; end; macro '-)'; begin end; macro 'Use 65535 LUT -- 16 bits'; begin xlate16uTo8P := std65535Pid; SetMemo('xlate16uTo8P', xlate16uTo8P); end; macro 'Use 8191 LUT -- 13 bits'; begin xlate16uTo8P := std8191Pid; SetMemo('xlate16uTo8P', xlate16uTo8P); end; macro 'Use Custom LUT'; begin xlate16uTo8P := customLUTPid; SetMemo('xlate16uTo8P', xlate16uTo8P); end; macro 'Front image is packed 16 bit stack'; begin pack16Pid := pidNumber; SetMemo('pack16Pid', pack16Pid); end; macro '[o] Open packed 16 bit stack'; var n: integer; begin if pidExists(maskPid) or pidExists(pack16Pid) or pidExists(packMarkPid) then begin putmessage('dispose of old packed stack first'); exit; end; {Find the folder} GetFolder; {Open the 'Mask Image' file} Open('Mask Image'); {Make sure name of front image is 'Mask Image'} SelectWindow('Mask Image'); maskPid := pidNumber; SetMemo('maskPid', maskPid); ChoosePic(maskPid); Open('packed 16 bit stack'); SelectWindow('packed 16 bit stack'); pack16Pid := pidNumber; SetMemo('pack16Pid', pack16Pid); Open('packed mark stack'); SelectWindow('packed mark stack'); packMarkPid := pidNumber; SetMemo('packMarkPid', packMarkPid); CheckPids; choosePic(pack16Pid); n := sliceNumber; choosePic(packMarkPid); SelectSlice(n); CnvMsk16uTo8(pack16Pid, xlate16uTo8P, maskPid, i8Pid); ExpMask16u(pack16Pid, maskPid, i16Pid); ExpMask8u(packMarkPid, maskPid, markPid); choosePic(markPid); SelectAll; selectPic(i8Pid); end; macro 'Show markup'; var frontPid: integer; begin frontPid := pidNumber; if PidExists(frontPid) then begin SelectPic(frontPid); KillRoi; end; checkPids; ChoosePic(i8Pid); KillRoi; MarkupData8(picNumber); ChoosePic(i16Pid); KillRoi; MarkupData16(picNumber); ChoosePic(b16Pid); KillRoi; MarkupBkg(picNumber); ChoosePic(markPid); KillRoi; MarkupMarks(picNumber); if PidExists(frontPid) then SelectPic(frontPid); MarkupShow; SetForegroundColor(fore); SetDensitySlice(fore,fore); end; macro '[m] play packed 16 bit movie'; var i, n, fps: integer; begin CheckPids; selectPic(i8Pid); choosePic(pack16Pid); n := nSlices; KillDelay(1); fps := GetNumber('Frames per second', 20); while not button do begin StartElapsed(1); for i := 1 to n do begin StartDelay(1, 1 / fps); choosePic(pack16Pid); chooseSlice(i); choosePic(packMarkPid); chooseSlice(i); CnvMsk16uTo8(pack16Pid, xlate16uTo8P, maskPid, i8Pid); {ExpMask8u(packMarkPid,maskPid,markPid);} selectPic(i8Pid); {selectPic(markPid);--way too slow} WaitDelay(1); end; ShowMessage(concat(n / MeasureElapsed(1) : 0 : 2, ' frames per second\hold mouse button to stop.')); end; ExpMask8u(packMarkPid, maskPid, markPid); SelectPic(markPid); end; macro '[F3]Copy mark changes into mark stack'; var n: integer; begin CheckPids; choosePic(pack16Pid); n := sliceNumber; choosePic(packMarkPid); SelectSlice(n); SqzMask8u(markPid, maskPid, packMarkPid); end; macro '[g] Prev color' begin ChoosePic(MarkupPicNumber('mark')); SetBackgroundColor(0); fore := fore - 1; SetMemo('fore', fore); if fore < 1 then fore := 20; SetMemo('fore', fore); SetForegroundColor(fore); SetDensitySlice(fore,fore); MarkupShow; ShowMessage('Foreground color is ',fore); end; macro '[h] Next color' begin ChoosePic(MarkupPicNumber('mark')); SetBackgroundColor(0); fore := fore + 1; SetMemo('fore', fore); if fore > 20 then fore := 1; SetMemo('fore', fore); SetForegroundColor(fore); SetDensitySlice(fore,fore); MarkupShow; ShowMessage('Foreground color is ',fore); end; macro '[j] Next default color'; begin ChoosePic(MarkupPicNumber('mark')); SetBackgroundColor(0); foredef := foredef + 1; SetMemo('foredef', foredef); if foredef > 20 then foredef := 1; SetMemo('foredef', foredef); fore := foredef; SetMemo('fore', fore); SetForegroundColor(fore); SetDensitySlice(fore,fore); MarkupShow; ShowMessage('Default Foreground color is ',foredef); end; macro '[n] next slice'; var n: integer; begin CheckPids; choosePic(pack16Pid); if sliceNumber < nSlices then SelectSlice(sliceNumber + 1); n := sliceNumber; choosePic(packMarkPid); SelectSlice(n); CnvMsk16uTo8(pack16Pid, xlate16uTo8P, maskPid, i8Pid); ExpMask16u(pack16Pid, maskPid, i16Pid); ExpMask8u(packMarkPid, maskPid, markPid); choosePic(markPid); SelectAll; selectPic(i8Pid); end; macro '[b] back to previous slice'; var n: integer; begin CheckPids; choosePic(pack16Pid); if sliceNumber > 1 then selectSlice(sliceNumber - 1); n := sliceNumber; choosePic(packMarkPid); SelectSlice(n); CnvMsk16uTo8(pack16Pid, xlate16uTo8P, maskPid, i8Pid); ExpMask16u(pack16Pid, maskPid, i16Pid); ExpMask8u(packMarkPid, maskPid, markPid); choosePic(markPid); SelectAll; selectPic(i8Pid); end; procedure smooth16New; var i, n: integer; kx, ky, kw, kh: integer; width, height, wpix, hpix: integer; sm16Pid, smpk16Pid: integer; begin CheckPids; SetBackgroundColor(0); SaveState; selectPic(i16Pid); GetPicSize(width, height); wpix := width div 2; hpix := height; ChoosePic(smoothPid); kx := getPixel(0, 0); ky := getPixel(1, 0); kw := getPixel(2, 0); kh := getPixel(3, 0); MakeRoi(0, 1, kw * 4, kh); SetNewSize(wpix*2, hpix); MakeNewWindow('smoothed 16 bit Image'); sm16Pid := pidNumber; choosePic(pack16Pid); n := nSlices; GetPicSize(width, height); SetNewSize(width, height); MakeNewStack('smoothed packed 16 bit stack'); smpk16Pid := pidNumber; RestoreState; ChoosePic(maskPid); SelectAll; Copy; KillRoi; ChoosePic(mask1Pid); MakeRoi(kx, ky, wpix, hpix); Paste; ChangeValues(1, 255, 255); Invert; SetForegroundColor(255); MakeRoi(0, 0, kx, hpix + kh); Fill; MakeRoi(kx + wpix, 0, kw - kx - 1, hpix + kh) Fill; MakeRoi(kx, 0, wpix, ky); Fill; MakeRoi(kx, ky + hpix, wpix, kh - ky - 1); Fill; ChoosePic(mask1Pid); {Mask image must have an ROI same size as image and} {with borders matching kernel, thus:} MakeRoi(kx, ky, wpix, hpix); for i := 1 to n do begin choosePic(pack16Pid); chooseSlice(i); choosePic(smpk16Pid); chooseSlice(nSlices); if i > nSlices then addSlice; chooseSlice(i); choosePic(flagPid); SelectAll; Clear; KillRoi; if doMedian then begin ExpMask16u(pack16Pid, maskPid, sm16Pid); choosePic(i16Pid); makeRoi(2,1,wpix*2-4,hpix-2); {does this leave garbage in border?} choosepic(sm16Pid); makeRoi(2,1,wpix*2-4,hpix-2); median16u(sm16Pid, i16Pid); choosepic(sm16Pid); killRoi; choosepic(i16Pid); killRoi; Convolve16u(flagPid, i16Pid, smoothPid, kx, ky, mask1Pid, sm16Pid); SqzMask16u(sm16Pid, maskPid, smpk16Pid); end else begin ExpMask16u(pack16Pid, maskPid, i16Pid); Convolve16u(flagPid, i16Pid, smoothPid, kx, ky, mask1Pid, sm16Pid); SqzMask16u(sm16Pid, maskPid, smpk16Pid); end; end; choosePic(sm16Pid); dispose; selectPic(smpk16Pid); selectSlice(2); selectSlice(1); end; procedure median16New; var i, n: integer; width, height, wpix, hpix: integer; sm16Pid, smpk16Pid: integer; begin CheckPids; SetBackgroundColor(0); SaveState; selectPic(i16Pid); killRoi; GetPicSize(width, height); wpix := width div 2; hpix := height; SetNewSize(wpix*2, hpix); MakeNewWindow('Median Filter 16 bit image'); sm16Pid := pidNumber; choosePic(pack16Pid); n := nSlices; GetPicSize(width, height); SetNewSize(width, height); MakeNewStack('Median filter packed 16 bit stack'); smpk16Pid := pidNumber; RestoreState; choosePic(maskPid); killRoi; for i := 1 to n do begin choosePic(pack16Pid); chooseSlice(i); killRoi; choosePic(smpk16Pid); chooseSlice(nSlices); if i > nSlices then addSlice; chooseSlice(i); killRoi; choosePic(i16Pid) killRoi; ExpMask16u(pack16Pid, maskPid, i16Pid); choosePic(i16Pid); makeRoi(2,1,wpix*2-4,hpix-2); choosepic(sm16Pid); makeRoi(2,1,wpix*2-4,hpix-2); median16u(i16Pid, sm16Pid); choosepic(sm16Pid); killRoi; SqzMask16u(sm16Pid, maskPid, smpk16Pid); end; choosePic(sm16Pid); dispose; {work around choose/select bug} selectPic(pack16Pid); killRoi; selectSlice(2); selectSlice(1); selectPic(smpk16Pid); killRoi; selectSlice(2); selectSlice(1); selectPic(i16Pid); killRoi; selectPic(smpk16Pid); {leave output stack selected} end; macro 'median filter packed 16 bit stack to new stack'; begin median16New; end; macro 'smooth packed 16 bit stack with kernel to new stack'; var doMedian: Boolean; begin doMedian := false; smooth16New; end; macro 'median then smooth to new stack'; var doMedian: Boolean; begin doMedian := true; smooth16New; end; procedure rollBall16New; var kx, ky, kw, kh: integer; i, n: integer; width, height, wpix, hpix: integer; erode16Pid, dilate16Pid, rbpk16Pid: integer; minimg,maximg,minker,maxker: integer; begin CheckPids; ChoosePic(rbKerPid); kx := getPixel(0, 0); ky := getPixel(1, 0); kw := getPixel(2, 0); kh := getPixel(3, 0); MakeRoi(0, 1, kw * 2, kh); minmax16u(rbKerPid, minker, maxker); SetBackgroundColor(0); SaveState; selectPic(i16Pid); killRoi; GetPicSize(width, height); wpix := width div 2; hpix := height; SetNewSize(wpix*2, hpix); SetBackGroundColor(255); MakeNewWindow('GGErode 16 bit image'); erode16Pid := pidNumber; SetBackGroundColor(0); MakeNewWindow('GGDilate 16 bit image'); dilate16Pid := pidNumber; choosePic(pack16Pid); n := nSlices; GetPicSize(width, height); SetNewSize(width, height); MakeNewStack('Rolling Ball packed 16 bit stack'); rbpk16Pid := pidNumber; RestoreState; choosePic(maskPid); killRoi; for i := 1 to n do begin choosePic(pack16Pid); chooseSlice(i); killRoi; choosePic(rbpk16Pid); chooseSlice(nSlices); if i > nSlices then addSlice; chooseSlice(i); killRoi; choosePic(i16Pid) killRoi; ExpMask16u(pack16Pid, maskPid, i16Pid); choosePic(i16Pid); selectAll; minmax16u(i16Pid, minimg, maximg); if minimg < maxker then begin if 65536 - maximg < maxker - minimg then showmessage('cannot properly scale slice ',i); addk16u(i16Pid, i16Pid, maxker - minimg); end; choosepic(erode16Pid); selectAll; setForeGroundColor(255); fill; selectAll; GGErode16u(i16Pid, rbKerPid, kx, ky, erode16Pid); choosePic(erode16Pid); {clear border to zero} {left,top,width,height} makeRoi(0,0,wpix*2,ky);{top row} setBackgroundColor(0); clear; makeRoi(0,0,kx*2,hpix);{left column} clear; makeRoi((wpix-kw+kx)*2,0,(kw-kx)*2,hpix);{right column} clear; makeRoi(0,hpix-kh+ky,wpix*2,kh-ky);{bottom row} clear; selectAll; choosepic(dilate16Pid); selectAll; clear; selectAll; GGDilate16u(erode16Pid, rbKerPid, kx, ky, dilate16Pid); sub16u(i16Pid, dilate16Pid, erode16Pid); choosepic(erode16Pid); killRoi; SqzMask16u(erode16Pid, maskPid, rbpk16Pid); end; choosePic(erode16Pid); dispose; choosePic(dilate16Pid); dispose; {work around choose/select bug} selectPic(pack16Pid); killRoi; selectSlice(2); selectSlice(1); selectPic(rbpk16Pid); killRoi; selectSlice(2); selectSlice(1); selectPic(i16Pid); killRoi; selectPic(rbpk16Pid); {leave output stack selected} SetForegroundColor(fore); SetDensitySlice(fore,fore); end; macro 'Rolling Ball to new stack'; begin rollBall16New; end; macro '(-'; begin end; macro 'Front image is background kernel'; begin kernelPid := PidNumber; SetMemo('kernelPid', kernelPid); end; macro 'Select data image'; begin SelectPic(MarkupPicNumber('data')); end; macro 'Select data16 image'; begin SelectPic(MarkupPicNumber('data16')); end; macro 'Select marks image'; begin SelectPic(MarkupPicNumber('mark')); end; macro 'Select bkg image'; begin SelectPic(MarkupPicNumber('bkg')); end; macro '-)'; begin end; macro 'Display front 8 bit image as markup data pixels'; begin killRoi; MarkupData8(picNumber); MarkupShow; end; macro 'Display front 8 bit image as markup mark pixels'; begin killRoi; MarkupMarks(picNumber); MarkupShow; end; macro 'Display front 16 bit image as markup foreground graph'; begin killRoi; MarkupData16(picNumber); MarkupShow; end; macro 'Display front 16 bit image as markup background graph'; begin killRoi; MarkupBkg(picNumber); MarkupShow; end; macro 'Restore normal markup display'; begin ChoosePic(i8Pid); killRoi; MarkupData8(picNumber); ChoosePic(i16Pid); killRoi; MarkupData16(picNumber); ChoosePic(b16Pid); killRoi; MarkupBkg(picNumber); ChoosePic(markPid); killRoi; MarkupMarks(picNumber); MarkupShow; end; procedure ClearPic(p: integer); begin SetBackgroundColor(0); ChoosePic(p); SelectAll; Clear; KillRoi; end; {mark image is from markup, indicates segmentation} {mask image: zero pixels in mask are invalid and cannot } {contribute to the background calculation. (no data there)} {The "mask" image used with CnvMsk16uTo8} {is opposite polarity from mask used with Convolve16u,} {zero means no data for CnvMsk,} {nonzero means no data for Convolve.} macro 'calculate integrated intensities'; var width, height, wpix, hpix: integer; k, kx, ky, kw, kh, x, y, yb, hist0: integer; kmin, kdelta, knum, koverlap: integer; begin SelectPic(picNumber); SetBackgroundColor(0); ClearPic(mask1Pid); ClearPic(mask2Pid); ClearPic(mask3Pid); ClearPic(b16Pid); SaveState; ChoosePic(kernelPid); kmin := getPixel(0, 0); kdelta := getPixel(1, 0); knum := getPixel(2, 0); koverlap := getPixel(3, 0); kx := kmin + kdelta * (knum - 1); ky := kmin + kdelta * (knum - 1); kw := kx * 2 + 1; kh := ky * 2 + 1; ChoosePic(i16Pid); KillRoi; GetPicSize(width, height); wpix := width div 2; hpix := height; if wpix * 2 <> width then begin putmessage('16 bit input image width is odd'); Exit; end; ChoosePic(markPid); KillRoi; GetPicSize(width, height); if wpix <> width then begin putmessage('mark width is incorrect'); Exit; end; if hpix <> height then begin putmessage('mark height is incorrect'); Exit; end; ChoosePic(maskPid); KillRoi; GetPicSize(width, height); if wpix <> width then begin putmessage('mask width is incorrect'); Exit; end; if hpix <> height then begin putmessage('mask height is incorrect'); Exit; end; ChoosePic(flagPid); SelectAll; Clear; KillRoi; RestoreState; { Smooth the input image } {may be some trouble with kernel dimensions...} ChoosePic(smoothPid); kx := getPixel(0, 0); ky := getPixel(1, 0); kw := getPixel(2, 0); kh := getPixel(3, 0); MakeRoi(0, 1, kw * 4, kh); ChoosePic(maskPid); SelectAll; Copy; KillRoi; ChoosePic(mask1Pid); MakeRoi(kx, ky, wpix, hpix); Paste; ChangeValues(1, 255, 255); Invert; SetForegroundColor(255); MakeRoi(0, 0, kx, hpix + kh); Fill; MakeRoi(kx + wpix, 0, kw - kx - 1, hpix + kh) Fill; MakeRoi(kx, 0, wpix, ky); Fill; MakeRoi(kx, ky + hpix, wpix, kh - ky - 1); Fill; {Mask image must have an ROI same size as image and} {with borders matching kernel, thus:} MakeRoi(kx, ky, wpix, hpix); Convolve16u(flagPid, i16Pid, smoothPid, kx, ky, mask1Pid, s16Pid); {Done smoothing input image} {reset kx,ky,kw,kh for background calculation} {ought to use different variables above...} kx := kmin + kdelta * (knum - 1); ky := kmin + kdelta * (knum - 1); kw := kx * 2 + 1; kh := ky * 2 + 1; {copy mark image into scratch area and circular dilate} { with radius of 3 pixels.} {This dilation operator retains mark pixel values.} ChoosePic(markPid); SelectAll; Copy; ChoosePic(mask3Pid); MakeRoi(kx, ky, wpix, hpix); Paste; MakeRoi(kx, ky, wpix, hpix); ChoosePic(dilatePid); MakeRoi(kx, ky, wpix, hpix); {dilate with radius of 3, retaining pixel values} Dilate8Circular(mask3Pid, dilatePid, 3); {Copy dilated mark image to flag image and adjust values} ChoosePic(dilatePid); MakeRoi(kx, ky, wpix, hpix); Copy; {Flag image should be zero only in marked pixels} {These are the pixels that get an output value calculated.} {It is a waste of time to calculate values for other pixels.} ChoosePic(flagPid); KillRoi; Paste; KillRoi; ChangeValues(1, 255, 255); Invert; {maskPid is used with packed data, nonzero = data present} {mask2Pid and mask3Pid have extra pixels around border,} {used with convolve, and nonzero = do not use data.} {Maskn images indicate which pixels do not contribute } {to background. This includes foreground pixels, and } {pixels which have no value (outside image). These} {pixels have nonzero mask values. Zero mask pixels} {will contribute to the background calculation.} ChoosePic(markPid); SelectAll; Copy; ChoosePic(mask3Pid); MakeRoi(kx, ky, wpix, hpix); Paste; MakeRoi(kx, ky, wpix, hpix); changeValues(1, 255, 255); ChoosePic(mask2Pid); MakeRoi(kx, ky, wpix, hpix); {dilate with radius of 5} Dilate8Circular(mask3Pid, mask2Pid, 5); ChoosePic(maskPid); SelectAll; Copy; KillRoi; ChoosePic(mask3Pid); MakeRoi(kx, ky, wpix, hpix); Paste; ChangeValues(1, 255, 255); Invert; MakeRoi(kx, ky, wpix, hpix); Copy; ChoosePic(mask2Pid); MakeRoi(kx, ky, wpix, hpix); SetForegroundColor(255); SetBackgroundColor(0); Paste; doOr; {doesn't work if foreground not 255} {Pixels outside of the input image must be nonzero} {in the mask image. The pixels in question should } {already nonzero but change them just in case.} ChoosePic(mask2Pid); SetForegroundColor(255); MakeRoi(0, 0, kx, hpix + kh); Fill; MakeRoi(kx + wpix, 0, kw - kx - 1, hpix + kh) Fill; MakeRoi(kx, 0, wpix, ky); Fill; MakeRoi(kx, ky + hpix, wpix, kh - ky - 1); Fill; {Mask image must have an ROI same size as image and} {with borders matching kernel, thus:} MakeRoi(kx, ky, wpix, hpix); {Create the background 16 bit image} SetBackgroundColor(0); {Finally, do the convolution to calculate the background} SelectPic(b16Pid); SelectAll; Clear; KillRoi; hist0 := 1; kx := kmin; ky := kmin; yb := 1; SetOptions('User1,User2'); {turn off unneeded measurements} {'Area', 'Mean', 'Std. Dev.', 'X-Y Center', 'Mode', } {'Perimeter'(or 'Length'), 'Major', 'Minor', 'Angle', } {'Int. Den.', 'Min/Max', 'User1', or 'User2'. } for k := 1 to knum do begin kw := kx * 2 + 1; kh := ky * 2 + 1; if hist0 <> 0 then begin ChoosePic(kernelPid); MakeRoi(0, yb, kw * 4, kh); Convolve16u(flagPid, s16Pid, kernelPid, kx, ky, mask2Pid, b16Pid); {Check for complete} ChoosePic(flagPid); SelectAll; {Recalculate any pixels which depended on less than 4 } ChangeValues(1, 4, 0); Measure; hist0 := histogram[0]; end; kx := kx + kdelta; ky := ky + kdelta; yb := yb + kh; end; if hist0 <> 0 then PutMessage('Incomplete convolution -- Results not reliable'); SelectPic(mask2Pid); {choosePic as last operation in macro causes marching ants bug} {Now calculate the results} kx := kmin + kdelta * (knum - 1); ky := kmin + kdelta * (knum - 1); kw := kx * 2 + 1; kh := ky * 2 + 1; SelectPic(s16Pid); KillRoi; SelectPic(b16Pid); KillRoi; SelectPic(o16Pid); KillRoi; SelectPic(dilatePid); MakeRoi(kx, ky, wpix, hpix); Sub16u(s16Pid,b16Pid,o16Pid); SetNewSize(32,32); MakeNewWindow('Results'); Sum16sMark(o16Pid,dilatePid,pidNumber); ResetCounter; x := 0; for k := 1 to 256 do begin y := GetPixVec32s(pidNumber,k); if y <> 0 then begin x := x + 1; SetCounter(x); rUser1[x] := k; rUser2[x] := y; end; end; Dispose; SetUser1Label('mark'); SetUser2Label('intensity'); ShowResults; RestoreState; SetForegroundColor(fore); SetDensitySlice(fore,fore); end; macro 'median filter front 16 bit image to new image'; var inPid, outPid: integer; width, height: integer; begin inPid := pidNumber; killRoi; duplicate('Median Filter of ',inPid:0); outPid := pidNumber; selectpic(inPid); getpicsize(width,height); makeRoi(2,1,width-4,height-2); selectpic(outPid); makeRoi(2,1,width-4,height-2); median16u(inPid,outPid); selectPic(inPid); killRoi; selectPic(outPid); killRoi; end; macro 'Dispose all images newer than front image'; var frontPid: integer; begin frontPid := pidNumber; selectPic(nPics); while frontPid <> pidNumber do begin dispose; selectPic(nPics); end; end;