{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} end; macro '([F5] 16 bit arithmetic'; begin 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 SetMemo('frontPid', pidNumber); SelectWindow('Examine Packed 16 bit stack'); LoadMacros; 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; {16 bit arithmetic macros} macro 'rename front image'; begin SetPicName(GetString('new image name',GetPicName)); end; macro 'label front and newer images with PidNumber'; var i, frontPid: integer; begin i := picNumber; while i <= nPics do begin SelectPic(i); SetPicName(-pidNumber:0,' ',GetPicName); i := i + 1; end; end; macro 'add constant to front 16 bit image'; var k: integer; begin k := round(getnumber('integer constant',0)); addK16u(picNumber,picNumber,k); SetPicName(GetPicName,'+',k:0); end; macro 'add 65535-max to front 16 bit image'; var min,max, k: integer; begin minmax16u(picNumber,min,max); k := 65535 - max; addK16u(picNumber,picNumber,k); SetPicName(GetPicName,'+',k:0); end; macro 'subtract constant from front 16 bit image'; var k: integer; begin k := round(getnumber('integer constant',0)); subK16u(picNumber,picNumber,k); SetPicName(GetPicName,'-',k:0); end; macro 'subtract min from front 16 bit image'; var min,max: integer; begin minmax16u(picNumber,min,max); subK16u(picNumber,picNumber,min); SetPicName(GetPicName,'-',min:0); end; macro 'multiply front 16 bit image by rational constant'; var num,den: integer; begin num := round(getnumber('numerator',0)); den := round(getnumber('denominator',0)); muldivK16u(picNumber, picNumber, num, den); SetPicName(GetPicName,'*',num,'div',den:0); end; macro 'add constant to front 16 bit image to new image'; var inPid, k: integer; begin inPid := pidNumber; k := round(getnumber('constant',0)); Duplicate(GetPicName,'+',k:0); addK16u(inPid,picNumber,k); end; macro 'subtract constant from front 16 bit image to new image'; var inPid, k: integer; begin inPid := pidNumber; k := round(getnumber('constant',0)); Duplicate(GetPicName,'-',k:0); subK16u(inPid,picNumber,k); end; macro 'multiply front 16 bit image by rational constant to new image'; var inPid, num,den: integer; begin inPid := pidNumber; num := round(getnumber('numerator',0)); den := round(getnumber('denominator',0)); Duplicate(GetPicName,'*',num,'div',den:0); muldivK16u(inPid, picNumber, num, den); end; macro '-)'; begin end; macro 'front 16 bit image is reference image'; begin referencePid := pidNumber; SetMemo('referencePid', referencePid); end; macro 'add reference image to front 16 bit image'; var name: string; inPid: integer; begin inPid := pidNumber; choosePic(referencePid); name := GetPicName; choosePic(inPid); add16u(inPid, referencePid, inPid); SetPicName(GetPicName,' + ',name); end; macro 'subtract reference image from front 16 bit image'; var name: string; inPid: integer; begin inPid := pidNumber; choosePic(referencePid); name := GetPicName; choosePic(inPid); sub16u(inPid, referencePid, inPid); SetPicName(GetPicName,' - ',name); end; macro 'ratio of front 16 bit image by reference'; var inPid: integer; coef: integer; begin inPid := pidNumber; coef := round(getNumber('integer coefficient',32768)); SetPicName(GetPicName,' *',coef:0,' ratio ', referencePid:0); ratio16u(inPid, referencePid, inPid,coef); end; macro '-)'; begin end; macro 'add reference to front 16 bit image to new image'; var inPid: integer; begin inPid := pidNumber; Duplicate('Add pid ',referencePid:0, ' to ',inPid:0); add16u(inPid, referencePid, picNumber); end; macro 'subtract reference from front 16 bit image to new image'; var inPid: integer; begin inPid := pidNumber; Duplicate('Subtract pid ',referencePid:0,' from ',inPid:0); sub16u(inPid, referencePid, picNumber); end; macro 'ratio of front 16 bit image by reference to new image'; var inPid: integer; coef: integer; begin inPid := pidNumber; coef := round(getNumber('integer coefficient',32768)); Duplicate('Ratio ',inPid:0,' *',coef:0,' by pid ', referencePid:0); ratio16u(inPid, referencePid, picNumber,coef); end; macro '-)'; begin end; macro 'median filter front 16 bit image to new image'; var inPid, outPid: integer; width, height: integer; begin inPid := pidNumber; killRoi; duplicate(GetPicName,' rn'); 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 'repeated median filter front 16 bit image to new image'; var inPid, outPid: integer; width, height: integer; n: integer; begin inPid := pidNumber; killRoi; n := GetNumber('Repeat count',10); duplicate(GetPicName,' rn',n:0,'x'); outPid := pidNumber; duplicate('delete me'); inPid := pidNumber; selectpic(inPid); getpicsize(width,height); makeRoi(2,1,width-4,height-2); selectpic(outPid); makeRoi(2,1,width-4,height-2); if odd(n) then begin median16u(inPid, outPid); n := n - 1; end; while n > 0 do begin median16u(outPid,inPid); median16u(inPid,outPid); n := n - 2; end; selectPic(inPid); dispose; selectPic(outPid); killRoi; end; macro 'min spatial filter front 16 bit image to new image'; var inPid, outPid: integer; width, height: integer; begin inPid := pidNumber; killRoi; duplicate(GetPicName,' minspat'); outPid := pidNumber; selectpic(inPid); getpicsize(width,height); makeRoi(2,1,width-4,height-2); selectpic(outPid); makeRoi(2,1,width-4,height-2); minspat16u(inPid,outPid); selectPic(inPid); killRoi; selectPic(outPid); killRoi; end; macro 'smooth front 16 bit image with kernel to new image'; var kx, ky, kw, kh: integer; width, height, wpix, hpix: integer; x16Pid, sm16Pid: integer; begin if not pidExists(smoothPid) then begin PutMessage('Please run macro "Front image is smoothing kernel"'); Exit; end; SetBackgroundColor(0); SaveState; x16Pid := pidNumber; 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); ChoosePic(flagPid); SelectAll; Clear; KillRoi; SetNewSize(wpix*2, hpix); MakeNewWindow('smoothed 16 bit image from ', x16Pid : 0); sm16Pid := 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; {Mask image must have an ROI same size as image and} {with borders matching kernel, thus:} MakeRoi(kx, ky, wpix, hpix); Convolve16u(flagPid, x16Pid, smoothPid, kx, ky, mask1Pid, sm16Pid); end; procedure smoothArbitrary; var kx, ky, kw, kh: integer; width, height, wpix, hpix: integer; x16Pid, sm16Pid: integer; flagPidx, mask1Pidx: integer; begin if not pidExists(smoothPid) then begin PutMessage('Please run macro "Front image is smoothing kernel"'); Exit; end; SetBackgroundColor(0); SaveState; x16Pid := pidNumber; 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,hpix); MakeNewWindow('deleteme Flag'); flagPidx := pidNumber; ChoosePic(flagPidx); SelectAll; Clear; KillRoi; SetNewSize(wpix + kw - 1,hpix + kh - 1); MakeNewWindow('deleteme Mask1'); mask1Pidx := pidNumber; SetNewSize(wpix*2, hpix); ChoosePic(x16Pid); MakeNewWindow(getPicName,' sm ',kw:0,' x ',kh:0); sm16Pid := PidNumber; RestoreState; ChoosePic(mask1Pidx); MakeRoi(kx, ky, wpix, hpix); Clear; 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); ChoosePic(flagPidx); MakeRoi(0,0,wpix,hpix); {in case wpix is odd, actual width is even} Convolve16u(flagPidx, x16Pid, smoothPid, kx, ky, mask1Pidx, sm16Pid); ChoosePic(flagPidx); Dispose; ChoosePic(mask1Pidx); Dispose; SelectPic(sm16Pid); end; macro 'smooth arbitrary front 16 bit image with kernel to new image'; begin SmoothArbitrary; end; macro 'min spatial repeat then smooth'; var inPid, outPid: integer; width, height, i: integer; begin killRoi; duplicate(GetPicName,' msrep'); outPid := pidNumber; duplicate('delete me'); inPid := pidNumber; i := getNumber('repeat div 2',2); selectpic(inPid); getpicsize(width,height); makeRoi(2,1,width-4,height-2); selectpic(outPid); makeRoi(2,1,width-4,height-2); while (i > 0) do begin; minspat16u(inPid,outPid); minspat16u(outPid,inPid); i := i - 1; end; selectPic(inPid); dispose; selectPic(outPid); killRoi; SmoothArbitrary; end; {Using an 8 bit image as mask, calculate new values} {for all pixels which are nonzero in the mask} procedure MaskedSmooth(x16Pid,x8Pid); var kx, ky, kw, kh: integer; kmin, kdelta, knum, koverlap: integer; k, hist0, yb: integer; width, height, wpix, hpix: integer; sm16Pid: integer; flagPidx, mask1Pidx: integer; begin if not pidExists(smoothPid) then begin PutMessage('Please run macro "Front image is smoothing kernel"'); Exit; end; SetBackgroundColor(0); SaveState; ChoosePic(x16Pid); GetPicSize(width, height); wpix := width div 2; hpix := height; {Use the background kernel not smoothing kernel} 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; MakeRoi(0, 1, kw * 4, kh); SetNewSize(wpix,hpix); MakeNewWindow('deleteme Flag'); flagPidx := pidNumber; ChoosePic(flagPidx); SelectAll; Clear; KillRoi; SetNewSize(wpix + kw - 1,hpix + kh - 1); MakeNewWindow('deleteme Mask1'); mask1Pidx := pidNumber; SetNewSize(wpix*2, hpix); ChoosePic(x16Pid); MakeNewWindow(getPicName,' sm ',kw:0,' x ',kh:0); sm16Pid := PidNumber; RestoreState; ChoosePic(x8Pid); MakeRoi(0, 0, wpix, hpix); Copy; ChoosePic(mask1Pidx); MakeRoi(kx, ky, wpix, hpix); Paste; 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); ChoosePic(flagPidx); MakeRoi(0,0,wpix,hpix); {in case wpix is odd, actual width is even} {Convolve16u(flagPidx, x16Pid, smoothPid, kx, ky, mask1Pidx, sm16Pid);} 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(flagPidx, x16Pid, kernelPid, kx, ky, mask1Pidx, sm16Pid); {Check for complete} ChoosePic(flagPidx); 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'); ChoosePic(flagPidx); {Dispose;} ChoosePic(mask1Pidx); {Dispose;} SelectPic(sm16Pid); end; macro 'smooth reference 16 bit image less front 8 bit mask to new'; begin MaskedSmooth(referencePid,pidNumber); end; macro 'GGErode 16 bit image to new image'; var kx, ky, kw, kh: integer; width, height, wpix, hpix: integer; x16Pid, sm16Pid: integer; begin if not pidExists(rbKerPid) then begin PutMessage('Please run macro "Front image is rolling ball kernel"'); Exit; end; SetBackgroundColor(0); SaveState; x16Pid := pidNumber; GetPicSize(width, height); wpix := width div 2; hpix := height; ChoosePic(rbKerPid); kx := getPixel(0, 0); ky := getPixel(1, 0); kw := getPixel(2, 0); kh := getPixel(3, 0); MakeRoi(0, 1, kw * 2, kh); SetNewSize(wpix*2, hpix); SetBackGroundColor(255); MakeNewWindow('GG Erode 16 bit from ', x16Pid : 0); SetBackgroundColor(0); sm16Pid := PidNumber; RestoreState; ChoosePic(sm16Pid); MakeRoi(0, 0, wpix*2, hpix); GGErode16u(x16Pid, rbKerPid, kx, ky, sm16Pid); end; macro 'GGDilate 16 bit image to new image'; var kx, ky, kw, kh: integer; width, height, wpix, hpix: integer; x16Pid, sm16Pid: integer; begin if not pidExists(rbKerPid) then begin PutMessage('Please run macro "Front image is rolling ball kernel"'); Exit; end; SetBackgroundColor(0); SaveState; x16Pid := pidNumber; GetPicSize(width, height); wpix := width div 2; hpix := height; ChoosePic(rbKerPid); kx := getPixel(0, 0); ky := getPixel(1, 0); kw := getPixel(2, 0); kh := getPixel(3, 0); MakeRoi(0, 1, kw * 2, kh); SetNewSize(wpix*2, hpix); SetBackGroundColor(0); MakeNewWindow('GG Dilate 16 bit from ', x16Pid : 0); SetBackgroundColor(0); sm16Pid := PidNumber; RestoreState; ChoosePic(sm16Pid); MakeRoi(0, 0, wpix*2, hpix); GGDilate16u(x16Pid, rbKerPid, kx, ky, sm16Pid); end; macro 'convert front 16 bit image to 8 bits'; var i, j, x, y: integer; inPid, outPid: integer; width, height: integer; min, max: integer; begin RequiresUser('pixel16u', 1); inPid := pidNumber; GetPicSize(width, height); SaveState; ChoosePic(xlate16uTo8P); MakeRoi(0, 0, 256, 256); SetNewSize(width div 2, height); MakeNewWindow('8 bit image from ', inPid : 0); outPid := pidNumber; RestoreState; MakeRoi(0,0,width div 2, height); Cnvrt16uto8(inPid, xlate16uTo8P, outPid); end; macro '[m] Mark selected pixels and advance color'; var fg, lower,upper: integer; begin fg := pidNumber; GetThreshold(lower,upper); SetDensitySlice(0,0); KillRoi; RestoreRoi; Clear; ChoosePic(MarkupPicNumber('mark')); SetBackgroundColor(0); SetForegroundColor(fore); RestoreRoi; fill; fore := fore + 1; if fore > 250 then fore := 1; SetMemo('fore', fore); SetForegroundColor(fore); {MarkupShow;} SelectPic(fg); ShowMessage('Foreground color is ',fore); SetDensitySlice(lower,upper); end; macro 'Hilight marked areas in sequence'; var i: integer; begin killRoi; measure for i := 1 to 254 do begin if histogram[i] <> 0 then begin setDensitySlice(i,i); showMessage('Mark number ',i:0); KillDelay(1); StartDelay(1,1.0); WaitDelay(1); end; end; end; macro '[g] Prev color' begin {ChoosePic(MarkupPicNumber('mark'));} SetBackgroundColor(0); fore := fore - 1; if fore < 1 then fore := 250; SetMemo('fore', fore); SetForegroundColor(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 > 250 then fore := 1; SetMemo('fore', fore); SetForegroundColor(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 > 250 then foredef := 1; SetMemo('foredef', foredef); fore := foredef; SetMemo('fore', fore); SetForegroundColor(fore); {MarkupShow;} ShowMessage('Default Foreground color is ',foredef); 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; macro 'movie of front 16 bit stack'; var frontPid, moviePid: integer; width, height: integer; i, n: integer; begin frontPid := pidNumber; killRoi; GetPicSize(width, height); SaveState; SetNewSize(width div 2, height); MakeNewWindow('movie'); moviePid := pidNumber; RestoreState; MakeRoi(0,0,width div 2, height); choosePic(frontPid); n := nSlices; i := 1; while not button do begin choosePic(frontPid); chooseSlice(i); Cnvrt16uto8(frontPid, xlate16uTo8P, moviePid); selectPic(moviePid); i := i + 1; if i > n then i := 1; end; choosePic(moviePid); dispose; selectPic(frontPid); selectSlice(1); end;