{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 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 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; procedure autoDispose(p); begin if pidExists(p) then begin choosePic(p); dispose; end; end; procedure createSmoothKernel; var x, y: integer; sum: real; begin RequiresUser('getputpixel', 1); AutoDispose(smoothPid); SaveState; SetNewSize(kw * 4, kh + 1); MakeNewWindow('kernel ', kx : 0, 'x ', ky : 0, 'y ', kw : 0, 'w ', kh : 0, 'h'); smoothPid := pidNumber; SetMemo('smoothPid', smoothPid); RestoreState; putPixel(0, 0, kx); putPixel(1, 0, ky); putPixel(2, 0, kw); putPixel(3, 0, kh); sum := 0.0; for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin sum := sum + exp(-sqrt(sqr(x) + sqr(y))); end; end; sum := 32000.0 / sum; {nearly maximum before overflow on 65535 pixel} for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin putPixel32s(smoothPid, x + kx, y + ky + 1, sum * exp(-sqrt(sqr(x) + sqr(y)))); end; end; sum := 0.0; for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin sum := sum + getPixel32s(smoothPid, x + kx, y + ky + 1); end; end; showmessage('kernel sum = ', sum); SelectPic(smoothPid); MakeRoi(0, 1, kw * 4, kh); end; macro 'Create standard 5x5 smoothing kernel'; var kx, ky, kw, kh: integer; begin kx := 2; ky := 2; kw := 5; kh := 5; createSmoothKernel; end; macro 'Create arbitrary smoothing kernel'; var kx, ky, kw, kh: integer; begin kw := GetNumber('kernel width',5); kh := GetNumber('kernel height',5); kx := GetNumber('kernel x center',kw div 2); ky := GetNumber('kernel y center',kh div 2); createSmoothKernel; end; {this kernel didn't do very well, use new radMedian16u instead} macro 'Create ad-hoc low pass filter smoothing kernel'; var kx, ky, kw, kh: integer; x, y, i, n: integer; sum, theta, pi, r: real; begin kx := 10; ky := 10; kw := 2*kx+1; kh := 2*ky+1; n := 16; r := kx; pi := StringToNum('3.1415926'); RequiresUser('getputpixel', 1); AutoDispose(smoothPid); SaveState; SetNewSize(kw * 4, kh + 1); SetBackgroundColor(0); MakeNewWindow('low pass kernel ',kx:0,'x ',ky:0,'y ',kw:0,'w ',kh:0,'h ',n:0,'n ',r:0,'r'); smoothPid := pidNumber; SetMemo('smoothPid', smoothPid); RestoreState; putPixel(0, 0, kx); putPixel(1, 0, ky); putPixel(2, 0, kw); putPixel(3, 0, kh); sum := 0.0; theta := 0.0; for i := 1 to n do begin theta := i / n * 2 * pi; x := round(r * cos(theta)); y := round(r * sin(theta)); sum := sum + exp(-sqrt(sqr(x) + sqr(y))); end; sum := 32000.0 / sum; {nearly maximum before overflow on 65535 pixel} for i := 1 to n do begin theta := i / n * 2 * pi; x := round(r * cos(theta)); y := round(r * sin(theta)); putPixel32s(smoothPid, x + kx, y + ky + 1, sum * exp(-sqrt(sqr(x) + sqr(y)))); end; sum := 0.0; for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin sum := sum + getPixel32s(smoothPid, x + kx, y + ky + 1); end; end; showmessage('kernel sum = ', sum); SelectPic(smoothPid); MakeRoi(0, 1, kw * 4, kh); end; procedure createBkgKernel; var k, kx, ky, kw, kh, x, y, yb: integer; sum, dist, dmin: real; kww, kwh: integer; {kernel window size} kmin, kdelta, knum, koverlap: integer; begin RequiresUser('getputpixel', 1); kmin := 2; kdelta := 2; knum := 10; koverlap := 1; kmin := trunc(GetNumber('minimum kernel diameter', kmin)); kdelta := trunc(GetNumber('kernel delta', kdelta)); knum := trunc(GetNumber('number of kernels', knum)); koverlap := trunc(GetNumber('kernel overlap',koverlap)); SaveState; kww := 0; kwh := 1; {top line saves info about kernel} kx := kmin; ky := kmin; for k := 1 to knum do begin kww := kx * 2 + 1; kwh := kwh + ky * 2 + 1; kx := kx + kdelta; ky := ky + kdelta; end; SetNewSize(kww * 4, kwh); MakeNewWindow('kernel ', kmin : 0, 'min ', kdelta : 0, 'delta ', knum : 0, 'number ',koverlap:0,'overlap'); kernelPid := pidNumber; SetMemo('kernelPid', kernelPid); RestoreState; putPixel(0, 0, kmin); putPixel(1, 0, kdelta); putPixel(2, 0, knum); putPixel(3, 0, koverlap); kx := kmin; ky := kmin; yb := 1; dmin := trunc(GetNumber('blank center diameter', 0.0)); for k := 1 to knum do begin sum := 0.0; kw := kx * 2 + 1; kh := ky * 2 + 1; for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin dist := sqrt(sqr(x) + sqr(y)); if dist >= dmin then if dist <= kx then sum := sum + exp(-dist) end; end; sum := 32000.0 / sum; {nearly maximum before overflow on 65535 pixel} for x := -kx to kw - kx - 1 do begin for y := -ky to kh - ky - 1 do begin dist := sqrt(sqr(x) + sqr(y)); putPixel32s(kernelPid, x + kx, y + ky + yb, 0); if dist < dmin then begin putPixel32s(kernelPid, x + kx, y + ky + yb, 0) end else begin if dist <= kx then begin putPixel32s(kernelPid, x + kx, y + ky + yb, sum * exp(-dist)) end else begin putPixel32s(kernelPid, x + kx, y + ky + yb, 0) end end; end; end; dmin := kx - koverlap; kx := kx + kdelta; ky := ky + kdelta; yb := yb + kh; end; end; macro 'create background Kernel'; begin createBkgKernel; end; procedure GGMorphSE; var x, y: integer; r: real; kx, ky, kw, kh, rad, z, dx, dy: integer; begin RequiresUser('getputpixel', 1); rad := 10; rad := GetNumber('ball radius',rad); z := 100; z := GetNumber('z/rad ratio',z); kx := 20; kx := GetNumber('patch half width',kx); ky := kx; kw := 2*kx+1; kh := kw; dx := 1; dx := GetNumber('sample spacing',dx); dy := dx; SaveState; SetNewSize(kw * 2, kh + 1); MakeNewWindow('rolling ball kernel ', kx : 0, 'x ', ky : 0, 'y ', kw : 0, 'w ', kh : 0, 'h ', rad : 0,'r ', z : 0, 'zr ', dx : 0, 'dx'); rbKerPid := pidNumber; SetMemo('rbKerPid', rbKerPid); RestoreState; putPixel(0, 0, kx); putPixel(1, 0, ky); putPixel(2, 0, kw); putPixel(3, 0, kh); putPixel(4, 0, rad); x := -kx; while x < kw - kx do begin y := -ky; while y < kh - ky do begin r := sqr(rad) - sqr(x) - sqr(y); if r < 0 then r := 0 else r := round(sqrt(r)*z) + 1; putPixel16u(rbKerPid, x + kx, y + ky + 1, r); y := y + dy; end; x := x + dx; end; SelectPic(rbKerPid); MakeRoi(0, 1, kw * 2, kh); end; macro 'create gray scale morphology structure element'; begin GGMorphSE; end; macro '[z] Create default kernels etc.'; var kx, ky, kw, kh: integer; begin kx := 2; ky := 2; kw := 5; kh := 5; createSmoothKernel; createBkgKernel; GGMorphSE; ymin := 0; SetMemo('ymin', ymin); ymax := 255; SetMemo('ymax', ymax); xmin := 0; SetMemo('xmin', xmin); xmax := 65535; SetMemo('xmax', xmax); if false then begin ymin := GetNumber('minimum 8 bit pixel value', ymin); SetMemo('ymin', ymin); ymax := GetNumber('maximum 8 bit pixel value', ymax); SetMemo('ymax', ymax); xmin := GetNumber('minimum 16 bit pixel value', xmin); SetMemo('xmin', xmin); xmax := GetNumber('maximum 16 bit pixel value', xmax); SetMemo('xmax', xmax); end; SaveState; SetNewSize(256, 256); SetBackgroundColor(0); MakeNewWindow('std65535LUT'); std65535Pid := pidNumber; SetMemo('std65535Pid', std65535Pid); linLUT16uto8(std65535Pid, 0, 65535, 1, 254); MakeNewWindow('std8191LUT'); std8191Pid := pidNumber; SetMemo('std8191Pid', std8191Pid); linLUT16uto8(std8191Pid, 0, 8191, 1, 254); MakeNewWindow('CustomLUT'); customLUTPid := pidNumber; SetMemo('customLUTPid', customLUTPid); RestoreState; xlate16uTo8P := customLUTPid; SetMemo('xlate16uTo8P', xlate16uTo8P); {xmin and xmax are arbitrary, 0 <= ymin <= ymax <= 255} if ymin > ymax then begin swap := ymin; ymin := ymax; SetMemo('ymin', ymin); ymax := swap; SetMemo('ymax', ymax); swap := xmin; xmin := xmax; SetMemo('xmin', xmin); xmax := swap; SetMemo('xmax', xmax); end; linLUT16uto8(customLUTPid, xmin, xmax, ymin, ymax); end; macro 'save standard kernels'; begin choosePic(smoothPid); killRoi; saveas('standardSmoothKernel'); choosePic(kernelPid); killRoi; saveas('standardBkgKernel'); choosePic(rbKerPid); killRoi; saveas('standardMorphKernel'); end; macro 'open standard kernels'; begin open('standardSmoothKernel'); smoothPid := pidNumber; SetMemo('smoothPid', smoothPid); open('standardBkgKernel'); kernelPid := pidNumber; SetMemo('kernelPid', kernelPid); open('standardMorphKernel'); rbKerPid := pidNumber; SetMemo('rbKerPid', rbKerPid); SaveState; SetNewSize(256, 256); SetBackgroundColor(0); MakeNewWindow('std65535LUT'); std65535Pid := pidNumber; SetMemo('std65535Pid', std65535Pid); linLUT16uto8(std65535Pid, 0, 65535, 1, 254); MakeNewWindow('std8191LUT'); std8191Pid := pidNumber; SetMemo('std8191Pid', std8191Pid); linLUT16uto8(std8191Pid, 0, 8191, 1, 254); MakeNewWindow('CustomLUT'); customLUTPid := pidNumber; SetMemo('customLUTPid', customLUTPid); RestoreState; xlate16uTo8P := customLUTPid; SetMemo('xlate16uTo8P', xlate16uTo8P); end; macro 'create new structure element based on front 8 bit window'; var i: integer; inPid, xlatePid: integer; x, y, kx, ky, kw, kh: integer; left,top,width,height: integer; begin inPid := pidNumber; GetRoi(left,top,width,height); kw := width; kh := height; kx := kw div 2; kx := GetNumber('center x coordinate',kx); ky := kh div 2; ky := GetNumber('center y coordinate',ky); SaveState; SetNewSize(512, 1); SetBackgroundColor(0); MakeNewWindow('8 to 16 conversion table'); xlatePid := pidNumber; for i := 0 to 255 do putpixel(i * 2, 0, i); MakeRoi(0, 0, 512, 1); SetNewSize(kw * 2, kh + 1); MakeNewWindow('morphology structure element ', kx : 0, 'x ', ky : 0, 'y ', kw : 0, 'w ', kh : 0, 'h '); rbKerPid := pidNumber; SetMemo('rbKerPid', rbKerPid); RestoreState; putPixel(0, 0, kx); putPixel(1, 0, ky); putPixel(2, 0, kw); putPixel(3, 0, kh); SelectPic(rbKerPid); MakeRoi(0, 1, kw * 2, kh); Cnvrt8to16u(inPid, xlatePid, rbKerPid); choosePic(xlatePid); Dispose; end;