{ AUTOMATCH v3.0b Swidbert R OTT (1995-97) еееееееееееееееееееееееееееееееееееееееееееееееееееееееееее This macro-file must be loaded into NIH Image to run. Please press command-9 to load AutoMatch, and command-W to close this window. Then press F1 to start AutoMatch, or select "AutoMatch" from the "Special" menu. еееееееееееееееееееееееееееееееееееееееееееееееееееееееееее } VAR ImgCount,FrameCount:integer; BuildPath:string; CameraXdim,CameraYdim,FFTdim:integer; BackGrOffset,ScreenX,ScreenY,Yclip:integer; FSName, PrefsPath, FSPath:string; ScreenXstring,ScreenYstring,FFTdimString,BGOstring,AverageString,YclipString,FrameString,ThisString,ThatString,WhoString:string; FileFound, AutoBGO: boolean; MX,MY:integer; {########################################################} FUNCTION CheckFile(FileName:string):boolean; BEGIN BuildPath:=concat(PrefsPath,FileName); GetFileInfo(BuildPath,FileType,FileSize); IF FileSize=-1 THEN BEGIN PutMessage('Initialization failed: Could not find file "',BuildPath,'"'); CheckFile:=FALSE END ELSE CheckFile:=TRUE; END; PROCEDURE WhereIsThePrefsFolder; var FileType:string; FileSize:integer; BEGIN PrefsPath:=GetPath('pref'); PrefsPath:=concat(PrefsPath,'AM Prefs ─:'); FileFound:=CheckFile('CWIN'); FileFound:=CheckFile('MM Prefs'); FileFound:=CheckFile('Mean(7x7)'); FSPath:=concat(PrefsPath,'FrameStacks ─:'); END; {########################################################} PROCEDURE GetNrLines; BEGIN ChoosePic(LogPID); NrLines:=0; WHILE 255<>GetPixel(0,NrLines) DO NrLines:=NrLines+1; END; PROCEDURE GetLogLine(Line:integer); var LineBIndex:integer; BEGIN ChoosePic(LogPID); GetRow(0,Line-1,34); LineBIndex:=0; aLine:=''; REPEAT aLine:=concat(aLine,chr(LineBuffer[LineBIndex])); LineBIndex:=LineBIndex+1; UNTIL LineBuffer[LineBIndex]=255; ChoosePic(CPID); END; PROCEDURE UpdateCWin(startL,stopL:integer); var LineCount,PosCount:integer; BEGIN SetBackGroundColor(2); SetForeGroundColor(255); MakeRoi(22,80,387,299); Clear; IF stopL>NrLines THEN stopL:=NrLines; FOR LineCount:=startL TO stopL DO BEGIN PosCount:=PosCount+1; GetLogLine(LineCount); MoveTo(30,75+10*PosCount); Write(aLine); END; END; PROCEDURE RefreshWin(startHere:integer); BEGIN GetNrLines; SelectPic(CPID); SetPalette('System'); IF NrLines<30 THEN MarkAreaYLim:=(NrLines*10)+80 ELSE MarkAreaYLim:=380; SetFont('Courier'); SetFontSize(10); SetText('plain'); UpdateCWin(StartHere,StartHere+29); END; PROCEDURE WriteString(TheString:string;Row:integer); var LineBIndex:integer; BEGIN LineBIndex:=0; REPEAT LineBuffer[LineBIndex]:=ord(TheString); Delete(TheString,1,1); LineBIndex:= LineBIndex+1; UNTIL ord(TheString)=-1; LineBuffer[LineBIndex]:=255; PutRow(0,Row,50); END; PROCEDURE ReadString(TheString:string;Row:integer); var LineBIndex:integer; BEGIN GetRow(0,Row,50); LineBIndex:=0; TheString:=''; REPEAT TheString:=concat(TheString,chr(LineBuffer[LineBIndex])); LineBIndex:=LineBIndex+1; UNTIL LineBuffer[LineBIndex]=255; IF Row=1 THEN FSName:=TheString ELSE IF Row=2 THEN ScreenXstring:=TheString ELSE IF Row=3 THEN ScreenYstring:=TheString ELSE IF Row=4 THEN FFTdimString:=TheString ELSE IF Row=5 THEN BGOstring:= TheString ELSE IF Row=6 THEN AverageString:=TheString ELSE IF Row=7 THEN YclipString:=TheString ELSE IF Row=8 THEN FrameString:=TheString; IF Row=9 THEN ThisString:=TheString; IF Row=10 THEN ThatString:=TheString; IF Row=11 THEN WhoString:=TheString; END; PROCEDURE ReadPrefs(CallByPrefMacro:boolean); BEGIN Open(PrefsPath,'MM prefs'); ReadString(FSName,1); ReadString(ScreenXstring,2); ReadString(ScreenYstring,3); ReadString(FFTdimString,4); ReadString(BGOstring,5); ReadString(AverageString,6); ReadString(YclipString,7); ReadString(FrameString,8); ReadString(ThisString,9); ReadString(ThatString,10); ReadString(WhoString,11); IF CallByPrefMacro THEN Dispose; END; PROCEDURE Preferences; BEGIN ReadPrefs(FALSE); SetFont('Courier'); SetFontSize(12); AutoBGO:=FALSE; IF BGOString='auto' THEN AutoBGO:= TRUE ELSE BackGrOffset:=StringToNum(BGOstring); ScreenX:=StringToNum(ScreenXstring); ScreenY:=StringToNum(ScreenYstring); Yclip:=StringToNum(YclipString); Dispose; END; {еееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее} FUNCTION Enable(Xcoor,Ycoor:integer):boolean; BEGIN ChoosePic(AWinPID); MakeROI(Xcoor,Ycoor,173,20); IF GetPixel(Xcoor,Ycoor)=0 THEN Invert; KillROI; Enable:=True; END; FUNCTION Disable(Xcoor,Ycoor:integer):boolean; BEGIN ChoosePic(AWinPID); MakeROI(Xcoor,Ycoor,173,20); IF GetPixel(Xcoor,Ycoor)=255 THEN Invert; Disable:=False; END; PROCEDURE DisposeItAll; BEGIN IF PidExists(CorrPID) THEN BEGIN ChoosePic(CorrPID); Dispose; END; IF PidExists(LastPID) THEN BEGIN ChoosePic(LastPID); Dispose; END; IF PidExists(PenultPID) THEN BEGIN ChoosePic(PenultPID); Dispose; END; IF PidExists(NewPID) THEN BEGIN ChoosePic(NewPID); Dispose; END; IF PidExists(StackPID) THEN BEGIN ChoosePic(StackPID); Dispose; END; IF PidExists(CameraPID) THEN BEGIN ChoosePic(CameraPID); Dispose; END; IF PidExists(AWinPID) THEN BEGIN ChoosePic(AwinPID); Dispose; END; END; PROCEDURE AverageShot; BEGIN SetCursor('Watch'); SetPalette('grayscale'); StartCapturing; repeat until BUTTON; SetCursor('Arrow'); Beep; IF ClipNScale THEN MakeROI(0,YClip,CameraYdim-YClip,CameraYdim-YClip) ELSE MakeROI(0,YClip,CameraXdim,CameraYdim-YClip); AverageFrames('average',Averages); END; PROCEDURE AquireNewFrame; var interimPID,xdim,ydim: integer; BEGIN IF NOT NFrame THEN beep ELSE BEGIN FrameCount:=FrameCount+1; IF FrameCount>=2 THEN BEGIN SelectPic(LastPID); GetPicSize(xdim,ydim); IF ScreenX < (2*xdim+2) THEN BEGIN SetScaling('Bilinear'); ScaleAndRotate((ScreenX-xdim-4)/xdim,(ScreenX-xdim-4)/xdim,0); SetPicName('Previously captured'); MoveWindow(1,35+Yclip); InterimPID:=PidNumber; ChoosePic(LastPID); Dispose; LastPID:=InterimPID; END ELSE MoveWindow(ScreenX-2*xdim-2,35+Yclip); END; IF FrameCount>=2 THEN BEGIN IF Framecount>=3 THEN BEGIN IF PidExists(PenultPID) THEN BEGIN ChoosePic(PenultPID); Dispose; END; END; PenultPID:= LastPID; SelectPic(LastPID); END; AverageShot; Duplicate('Previously Captured'); LastPID:= PidNumber; IF ClipNScale THEN ScaleAndRotate((FFTdim+6)/(CameraYdim-YClip),(FFTdim+6)/(CameraYdim-YClip),0) ELSE duplicate(''); NewPID:=PidNumber; ImageMath('sub',NewPID,CorrPID,1,BackGrOffset,'Temp'); SelectAll; Copy; Dispose; ChoosePic(NewPID); GetPicSize(xdim,ydim); Dispose; IF FrameCount>=2 THEN BEGIN ChoosePic(StackPID); AddSlice; Paste; END ELSE BEGIN IF ClipNScale THEN SetNewSize(FFTdim+6,FFTdim+6) ELSE SetNewSize(xdim,ydim); MakeNewStack('Accumulation Stack'); StackPID:=PidNumber; Paste; END; MouseChoice:=TRUE; IF NOT RLast THEN RLast:=Enable(183,25); IF NOT NImage THEN NImage:=Enable(7,48); IF NOT FAcq THEN FAcq:=Enable(7,71); END; END; PROCEDURE SaveAndNew; var j,SerialNumber:integer; LeadingNulls:string; BEGIN IF NOT NImage THEN beep ELSE BEGIN ImgCount:=ImgCount+1; FrameCount:=0; ChoosePic(DirPID); SerialNumber:=GetPixel(0,1)+1; PutPixel(0,1,SerialNumber); IF SerialNumber>99 THEN LeadingNulls:='' ELSE IF SerialNumber>9 THEN LeadingNulls:='0' ELSE LeadingNulls:='00'; j:=0; WHILE GetPixel(j,0)<>255 DO j:=j+1; PutPixel(j,0,0); ChoosePic(StackPID); SaveAs(FSPath,'FS',j:3); Dispose; ChoosePic(LogPID); WriteString(concat(' ',FSName,' ',LeadingNulls,SerialNumber:0:0),NrLines); PutPixel(35,NrLines,j); NrLines:=NrLines+1; IF PidExists(LastPID) THEN BEGIN ChoosePic(LastPID); Dispose; END; IF PidExists(PenultPID) THEN BEGIN ChoosePic(PenultPID); Dispose; END; MouseChoice:=TRUE; IF RLast THEN RLast:=Disable(183,25); IF NImage THEN NImage:=Disable(7,48); IF FAcq THEN FAcq:=Disable(7,71); END; END; PROCEDURE BGroundShot; BEGIN AverageShot; IF ClipNScale THEN BEGIN ScaleAndRotate((FFTdim+6)/(CameraYdim-YClip),(FFTdim+6)/(CameraYdim-YClip),0); SetPicName('Correction Window'); END ELSE duplicate('Correction Window'); MoveWindow(554,515); CorrPID:=PidNumber; MouseChoice:=TRUE; IF AutoBGO THEN BEGIN Measure; BackGrOffset:=rMean[rCount]; END; END; PROCEDURE finish; BEGIN IF NOT FAcq THEN beep ELSE BEGIN SaveAndNew; DisposeItAll; WannaExit:=TRUE; MouseChoice:=TRUE; END; END; PROCEDURE redolast; var kill1,kill2: integer; BEGIN IF NOT RLast THEN beep ELSE BEGIN ChoosePic(StackPID); IF nSlices>1 THEN DeleteSlice ELSE Dispose; FrameCount:=FrameCount-1; kill1:=PenultPID; kill2:=LastPID; AquireNewFrame; IF PidExists(kill1) THEN BEGIN ChoosePic(kill1); Dispose; END; IF PidExists(kill2) THEN BEGIN ChoosePic(kill2); Dispose; END; MouseChoice:=TRUE; END; END; PROCEDURE newback; BEGIN IF PidExists(CorrPID) THEN BEGIN ChoosePic(CorrPID); Dispose; END; BGroundShot; MouseChoice:=TRUE; IF NOT NFrame THEN NFrame:=Enable(7,25); END; PROCEDURE abort; BEGIN DisposeItAll; MouseChoice:=TRUE; WannaExit:=TRUE; END; PROCEDURE CaptureFrames; var CorrPID,LastPID,PenultPID,NewPID,StackPID,CameraPID,AwinPID:integer; Averages:integer; WannaExit,MouseChoice,ClipNScale: boolean; NFrame,NImage,FAcq,RLast: boolean; BEGIN ChoosePic(LogPID); IF GetPixel(0,255)<>255 THEN BEGIN PutMessage('You have already cached 256 images. Please dispose some old images before aquiring new ones.'); SelectPic(CPID); END ELSE BEGIN NFrame:=FALSE; NImage:=FALSE; FAcq:=FALSE; RLast:=FALSE; Open(PrefsPath,'AWIN'); MoveWindow(85,20); AwinPID:=PidNumber; Preferences; Averages:=StringToNum(AverageString); IF FrameString='n' THEN ClipNScale:=TRUE ELSE ClipNScale:=FALSE; IF FFTdimString='small' THEN FFTdim:=128 ELSE IF FFTdimString='normal' THEN FFTdim:=256 ELSE IF FFTdimString='large' THEN FFTdim:=512; FrameCount:=0; ImgCount:=0; StartCapturing; GetPicSize(CameraXdim,CameraYdim); CameraPID:=PidNumber; IF ClipNScale THEN MoveWindow(ScreenX-CameraYdim+Yclip,35) ELSE MoveWindow(ScreenX-CameraXdim,35); StopCapturing; SetScaling('bilinear,New Window'); REPEAT ChoosePic(LogPID); IF (GetPixel(0,255)<>255) THEN BEGIN PutMessage('You have already cached 256 images. Please dispose some old images before aquiring new ones.'); DisposeItAll; WannaExit:=TRUE; END ELSE BEGIN WannaExit:=FALSE; SelectPic(AwinPID); SetPalette('System'); MouseChoice:=FALSE; REPEAT SetCursor('Arrow'); GetMouse(MX,MY); IF BUTTON THEN BEGIN REPEAT UNTIL NOT BUTTON; IF (MX>6) AND (MX<182) THEN BEGIN IF (MY>24) AND (MY<47) THEN AquireNewFrame; IF (MY>47) AND (MY<70) THEN SaveAndNew; IF (MY>70) AND (MY<93) THEN finish; END; IF (MX>182) AND (MX<358) THEN BEGIN IF (MY>24) AND (MY<47) THEN redolast; IF (MY>47) AND (MY<70) THEN newback; IF (MY>70) AND (MY<93) THEN abort; END; END; UNTIL MouseChoice; END; UNTIL WannaExit; ChoosePic(LogPID); SaveAs(FSPath,'**LogFile**'); ChoosePic(DirPID); SaveAs(FSPath,'**DirFile**'); RefreshWin(TopLineC); END; END; {########################################################} PROCEDURE RowToNum; var LineBIndex:integer; BEGIN GetRow(0,RowCounter,5); IF LineBuffer[0]=2 THEN TheValue:=9999 ELSE BEGIN TheValue:=0; FOR LineBIndex:=1 TO 4 DO TheValue:=TheValue+LineBuffer[LineBIndex]; IF LineBuffer[0]=1 THEN TheValue:=-TheValue; END; RowCounter:=RowCounter+1; END; PROCEDURE DataFromDisk; var RowCounter,rUserIndex:integer; TheValue:integer; BEGIN rUserIndex:=0; REPEAT rUserIndex:=rUserIndex+1; RowToNum; rUser1[rUserIndex]:=TheValue; RowToNum; rUser2[rUserIndex]:=TheValue; UNTIL rUser1[rUserIndex]=9999; Dispose; END; PROCEDURE NumToRow(aValue:integer); BEGIN LineBIndex:=0; IF aValue=9999 THEN LineBuffer[LineBIndex]:=2 ELSE {## 2 im ersten Byte codiert 9999 ##} BEGIN IF aValue<0 THEN LineBuffer[LineBIndex]:=1 ELSE LineBuffer[LineBIndex]:=0; {## 1 im ersten Byte: negativ} LineBIndex:=LineBIndex+1; aValue:=abs(aValue); WHILE aValue>255 DO BEGIN LineBuffer[LineBIndex]:=255; aValue:=aValue-255; LineBIndex:=LineBIndex+1; END; LineBuffer[LineBIndex]:=aValue; END; END; PROCEDURE DataToDisk; var RowCounter,rUserIndex:integer; LineBIndex:integer; {wert stammt aus CalcPicRow} ResName:string; BEGIN SetNewSize(5,ArrayPntr*2+1); {## --> maximal abspeicherbare grЪsse:+/-1020 ##} SetBackGroundColor(0); MakeNewWindow('Results'); rUserIndex:=0; RowCounter:=0; REPEAT rUserIndex:=rUserIndex+1; NumToRow(rUser1[rUserIndex]); PutRow(0,RowCounter,LineBIndex+1); NumToRow(rUser2[rUserIndex]); PutRow(0,RowCounter+1,LineBIndex+1); RowCounter:=RowCounter+2; UNTIL rUser1[rUserIndex]=9999; SaveAs(FSPath,'data',FSCode:3); Dispose; END; PROCEDURE InitiateProgressWin; BEGIN SetBackgroundColor(0); SetForegroundColor(255); SetNewSize(200,50); MakeNewWindow('Total Progress'); MoveWindow(610,100); SetLineWidth(1); MoveTo(12,42); SetFont('Times'); SetFontSize(10); Write('Estimation assumes images of similar size'); SetFontSize(12); END; PROCEDURE DrawProgress(BarLength:integer); var PIDBuffer:integer; BEGIN PIDBuffer:=PidNumber; IF FirstTickCount THEN InitiateProgressWin; SelectWindow('Total Progress'); MakeRoi(0,0,200,19); SetBackgroundColor(0); Clear; MakeRoi(20,20,160,10); DrawBoundary; MakeRoi(20,20,160*BarLength,10); Fill; KillRoi; MoveTo(5,10); IF FirstTickCount THEN Write('Total ???') ELSE Write ('Total',trunc(EstTotalT/3600),':',trunc((EstTotalT-(trunc(EstTotalT/3600))*3600)/60):2:0,':',round(EstTotalT-3600* trunc(EstTotalT/3600)-60* trunc((EstTotalT-(trunc(EstTotalT/3600))*3600)/60)):2:0); MoveTo(100,10); IF FirstTickCount THEN Write('Remaining ???') ELSE BEGIN Write ('Remaining',trunc((EstTotalT-ElapsedT)/3600),':',trunc(((EstTotalT-ElapsedT)-(trunc((EstTotalT-ElapsedT)/3600))*3600)/60):2:0,':',round((EstTotalT-ElapsedT)-3600* trunc((EstTotalT-ElapsedT)/3600)-60* trunc(((EstTotalT-ElapsedT)-(trunc((EstTotalT-ElapsedT)/3600))*3600)/60)):2:0); ChoosePic(PIDBuffer); END; END; PROCEDURE EstimateTime(Ticks:integer); var Ratio:integer; BEGIN IF FirstTickCount THEN BEGIN AverageT:=0; CountLaps:=0; FirstTickCount:=false; END; Time:=(TickCount-Ticks)/60; AverageT:=((AverageT*CountLaps)+Time)/(CountLaps+1); EstTotalT:=AverageT*FramesInStack*TotalImgs*2; ElapsedT:=ElapsedT+Time; CountLaps:=CountLaps+1; IF ElapsedT/EstTotalT>1 THEN Ratio:=1 ELSE Ratio:=ElapsedT/EstTotalT; DrawProgress(Ratio); END; PROCEDURE FFTTransformFrame; var localPID,woswasiiPID:integer; BEGIN Ticks:=TickCount; ChoosePic(StackPID); ChooseSlice(FrameCount); woswasiiPID:=PIDnumber; IF NOT ScaledOriginals THEN BEGIN ScaleAndRotate(((FFTdim+6)/xdim),((FFTdim+6)/ydim),0); woswasiiPID:=PIDNumber; END; Duplicate('temp'); Convolve(BuildPath); localPID:=PidNumber; ChoosePic(woswasiiPID); Filter('smooth'); ImageMath('sub',woswasiiPID,LocalPID,20,50,LocalPID); MakeROI(3,3,FFTdim,FFTdim); ResetCounter; Measure; SetBackground(round(rMean[1])); Copy; Dispose; SetNewSize(2*FFTdim,2*FFTdim); MakeNewWindow('dummy'); dummyPID:=PidNumber; MakeRoi(0,0,FFTdim,FFTdim); Paste; KillROI; fft('foreward'); localPID:=PidNumber; ChoosePic(dummyPID); Dispose; IF NOT ScaledOriginals THEN BEGIN SelectPic(woswasiiPID); dispose; END; ChoosePic(localPID); FrameCount:=FrameCount+1; EstimateTime(Ticks); END; PROCEDURE FindCorrelation(pic1,pic2:integer); var spotX, spotY:integer; BEGIN Ticks:=TickCount; ImageMath('cmul',pic1,pic2,1,0,'cross'); {# calculate cross-corr #} fft('inverse'); fft('Swap Quadrants'); ResetCounter; Measure; SetThreshold(rMax[1]); MakeBinary; SetScale(1,'pixel'); AnalyzeParticles('include,reset'); Dispose; ArrayPntr:=ArrayPntr+1; rUser1[ArrayPntr]:=round(rX[1]-FFTdim); rUser2[ArrayPntr]:=round(rY[1]-FFTdim); IF NOT ScaledOriginals THEN rUser1[ArrayPntr]:=rUser1[ArrayPntr]*xdim/(FFTdim+6); IF NOT ScaledOriginals THEN rUser2[ArrayPntr]:=rUser2[ArrayPntr]*ydim/(FFTdim+6); EstimateTime(Ticks); END; PROCEDURE GetNrSelections; BEGIN ChoosePic(LogPID); NrSelections:=0; FOR i:=0 TO NrLines DO BEGIN IF GetPixel(0,i)=165 THEN NrSelections:=NrSelections+1; IF (GetPixel(0,i)=165) AND NOT(GetPixel(1,i)=195) THEN INVALIDSELECTION:=TRUE; END; END; PROCEDURE Match; var fft1PID,fft2PID,dummyPID:integer; xshift,yshift,xdim,ydim:integer; fstROIx,fstROIy:integer; sndROIx,sndROIy:integer; StackPID,FramesInStack,FStackNr:integer; TotalImgs,ArrayPntr:integer; FirstTickCount, ScaledOriginals:boolean; Ticks:integer; CountLaps:integer; Time,AverageT,EstTotalT,ElapsedT:real; BEGIN GetNrSelections; IF NrSelections=0 THEN BEGIN PutMessage('There are no items selected'); SelectPic(CPID); END ELSE BEGIN Preferences; BuildPath:=concat(PrefsPath,'Mean(7x7)'); TotalImgs:=NrSelections; ImgCount:=1; FrameCount:=1; FirstTickCount:=true; DrawProgress(0); ImgCount:=0; i:=0; REPEAT ArrayPntr:=0; ChoosePic(LogPID); WHILE GetPixel(0,i)<>165 DO i:=i+1; FSCode:=GetPixel(35,i); open(FSPath,'FS',FSCode:3); IF nSlices>1 THEN BEGIN GetPicSize(FFTdim,FFTdim); FFTdim:=FFTdim-6; IF ((FFTdim=128) OR (FFTdim=256) OR (FFTdim=512)) THEN ScaledOriginals:=TRUE ELSE BEGIN ScaledOriginals:=FALSE; GetPicSize(xdim,ydim); IF FFTdimString='small' THEN FFTdim:=128 ELSE IF FFTdimString='normal' THEN FFTdim:=256 ELSE IF FFTdimString='large' THEN FFTdim:=512; END; FStackNr:=StringToNum(WindowTitle); StackPID:=PidNumber; SetOptions('max,Area,Mean,X-Y Center,User1,User2'); FramesInStack:=nSlices; FFTTransformFrame; fft1PID:=PidNumber; FFTTransformFrame; fft2PID:=PidNumber; FindCorrelation(fft1PID,fft2PID); WHILE FrameCount<=FramesInStack DO BEGIN ChoosePic(fft1PID); Dispose; fft1PID:=fft2PID; FFTTransformFrame; fft2PID:=pidNumber; FindCorrelation(fft1PID,fft2PID); END; ChoosePic(fft1PID); Dispose; ChoosePic(fft2PID); Dispose; ChoosePic(stackPID); Dispose; END ELSE BEGIN ResetCounter; rUser1[1]:=0; rUser2[1]:=0; ArrayPntr:=1; Dispose; END; FrameCount:=1; ImgCount:=ImgCount+1; ArrayPntr:= ArrayPntr+1; rUser1[ArrayPntr]:=9999; {## 9999 in rUser1 indicates end of "file" ##} DataToDisk; ChoosePic(LogPID); PutPixel(1,i,195); i:=i+1; UNTIL ImgCount=TotalImgs; SelectWindow('Total Progress'); Dispose; ChoosePic(LogPID); SaveAs(FSPath,'**LogFile**'); ChoosePic(DirPID); SaveAs(FSPath,'**DirFile**'); RefreshWin(TopLineC); END; END; {##################################################################################} PROCEDURE CalculateImgDimension; var TempMaxX,TempMaxY:integer; BEGIN TempMaxX:=0; TempMaxY:=0; maxXpos:=0; maxXneg:=0; maxYpos:=0; maxYneg:=0; FrameCount:=1; REPEAT TempMaxX:=TempMaxX + rUser1[FrameCount]; IF TempMaxX>maxXpos THEN maxXpos:=TempMaxX; IF TempMaxXmaxYpos THEN maxYpos:=TempMaxY; IF TempMaxY165 DO i:=i+1; FSCode:=GetPixel(35,i); Open(FSPath,'data',FSCode:3); DataFromDisk; GetLogLine(i+1); Delete(aLine,1,3); Open(FSPath,'FS',FSCode:3); GetPicSize(xdim,ydim); ResetCounter; StackPID:=PidNumber; IF nSlices>=2 THEN BEGIN CalculateImgDimension; AssembleFrames; END ELSE BEGIN SelectAll; Copy; Dispose; SetNewSize(xdim,ydim); MakeNewWindow('img'); SetPicName(aline); Paste; StackCount:=StackCount+1; END; i:=i+1; UNTIL StackCount=NrOfStacks; END; ChoosePic(LogPID); SaveAs(FSPath,'**LogFile**'); ChoosePic(DirPID); SaveAs(FSPath,'**DirFile**'); RefreshWin(TopLineC); END; END; {###############################################################################} PROCEDURE ScrollUp; BEGIN IF TopLineC<(NrLines-29) THEN BEGIN TopLineC:=TopLineC+1; MakeRoi(22,91,387,290); Copy; Clear; MoveRoi(0,-10); Paste; GetLogLine(TopLineC+29); MoveTo(30,375); Write(aLine); END; END; PROCEDURE ScrollDn; BEGIN IF TopLineC>1 THEN BEGIN TopLineC:=TopLineC-1; MakeRoi(22,80,387,288); Copy; Clear; MoveRoi(0,10); Paste; GetLogLine(TopLineC); MoveTo(30,85); Write(aLine); END; END; PROCEDURE PgUP; BEGIN IF TopLineC<(NrLines-29) THEN BEGIN IF TopLineC<(NrLines-59) THEN TopLineC:=TopLineC+29 ELSE TopLineC:=NrLines-29; UpdateCWin(TopLineC,TopLineC+29); END; END; PROCEDURE PgDN; BEGIN IF TopLineC>1 THEN BEGIN IF TopLineC>30 THEN TopLineC:=TopLineC-29 ELSE TopLineC:=1; UpdateCWin(TopLineC,TopLineC+29); END; END; PROCEDURE Mark; var TheLine,TempX,TempY,TempYold:integer; BEGIN TheLine:=(TopLineC+trunc((MY-80)/10))-1; ChoosePic(LogPID); IF GetPixel(0,TheLine)=165 THEN BEGIN PutPixel(0,TheLine,0); ChoosePic(CPID); SetBackgroundColor(2); MakeRoi(30,80+10*trunc((MY-80)/10),5,8);Clear;KillRoi; END ELSE BEGIN PutPixel(0,TheLine,165); ChoosePic(CPID); MoveTo(30,85+10*trunc((MY-80)/10)); Write(chr(165)); END; REPEAT GetMouse(TempX,TempY) UNTIL Button=FALSE OR(((TempY<(80+10*trunc((MY-80)/10)))OR(TempY>(90+10*trunc((MY-80)/10))))); END; PROCEDURE QuitNBye; BEGIN ChoosePic(LogPid); SaveAs(FSPath,'**LogFile**'); Dispose; ChoosePic(DirPid); SaveAs(FSPath,'**DirFile**'); Dispose; ChoosePic(CPID); Dispose; RestoreState; HellFreezesOver:=TRUE; END; PROCEDURE Dsps; var MiniDummyPID: integer; BEGIN GetNrSelections; IF NrSelections=0 THEN BEGIN PutMessage('There are no items selected'); SelectPic(CPID); END ELSE BEGIN SetBackgroundColor(255); i:=NrLines-1; SetNewSize(1,1); MakeNewWindow('MiniDummy'); MiniDummyPID:=PidNumber; REPEAT ChoosePic(LogPID); IF GetPixel(0,i)=165 THEN BEGIN FSCode:=GetPixel(35,i); MakeRoi(0,i+1,36,255-i); Copy; Clear; MoveRoi(0,-1); Paste; KillROI; ChoosePic(DirPID); PutPixel(FSCode,0,255); ChoosePic(MiniDummyPID); SaveAs(FSPath,'FS',FSCode:3); END; i:=i-1; UNTIL i<0; RefreshWin(TopLineC); ChoosePic(MiniDummyPID); Dispose; END; END; {########################################################################} PROCEDURE OffsetPref; BEGIN ReadPrefs(FALSE); BGOString:=GetString('Set BGr Offset to╔ ("auto" or value)',BGOString); WriteString(BGOString,5); SaveAs(PrefsPath,'MM prefs'); Dispose; END; PROCEDURE ScreenPref; BEGIN ReadPrefs(FALSE); ScreenXstring:=GetString('Monitor screen width (pixel)',ScreenXstring); WriteString(ScreenXstring,2); ScreenYstring:=GetString('Monitor screen height (pixel)',ScreenYstring); WriteString(ScreenYstring,3); YclipString:=GetString('AV-Macs only: Camera Y clipping in pixels', YclipString); WriteString(YclipString,7); SaveAs(PrefsPath,'MM prefs'); Dispose; END; PROCEDURE FramePref; BEGIN ReadPrefs(FALSE); REPEAT FrameString:=GetString('Use original frames for mosaic (y/n)', FrameString); UNTIL (FrameString='y') OR (FrameString='n'); WriteString(FrameString,8); REPEAT FFTdimString:=GetString('Choose "small", "normal", or "large"', FFTdimString) UNTIL ((FFTdimString='small') OR (FFTdimString='normal') OR (FFTdimString='large')); WriteString(FFTdimString,4); SaveAs(PrefsPath,'MM prefs'); Dispose; END; PROCEDURE NamePref; BEGIN ReadPrefs(FALSE); FSName:=GetString('Enter new name for composite images',FSName); WriteString(FSName,1); SaveAs(PrefsPath,'MM prefs'); Dispose; ChoosePic(DirPID); PutPixel(0,1,0); SaveAs(FSPath,'**DirFile**'); END; PROCEDURE AverPref; BEGIN ReadPrefs(FALSE); AverageString:=GetString('Average how many frames',AverageString); WriteString(AverageString,6); SaveAs(PrefsPath,'MM prefs'); Dispose; END; PROCEDURE ThePrefs; BEGIN ReadPrefs(FALSE); IF (ThisString<>ThatString) OR (ThisString=WhoString) THEN BEGIN PutMessage('This copy is not registered yet. Please register, AM is free. I would just like to know who is using it.'); ThatString:=GetString('Please enter Registration Number:','not registered'); IF (ThisString<>ThatString) OR (ThisString=WhoString) THEN BEGIN WhoString:='Unregistered Copy'; PutMessage('This is no valid code. Please email me at sro21@cam.ac.uk for a valid Registration Number. Cheers!'); END ELSE BEGIN WhoString:=GetString('Personalize this copy to','Name/Organization'); WriteString(ThatString,10); WriteString(WhoString,11); END; SaveAs(PrefsPath,'MM prefs'); END; Dispose; END; PROCEDURE ShowPrefs; BEGIN ReadPrefs(TRUE); NewTextWindow('MatchMacros Preference Settings',500,120); Writeln('е Compound Images saved as: ',FSName,' 001-XXX'); Writeln('е Background offset set to ',BGOString); Writeln('е Screen dimensions set to ',ScreenXstring,'x',ScreenYstring); Writeln('е Camera Y clipping set to ',YclipString); Writeln('е Size of detail frames set to "',FFTdimString,'"'); Writeln('е Averaging set to ',AverageString,' frames'); IF FrameString='y' THEN Writeln('е Using original frames for mosaics') ELSE Writeln('е Using scaled square frames for mosaics'); REPEAT UNTIL button; Dispose; RefreshWin(TopLineC); END; PROCEDURE PrefsArea; BEGIN IF ((MX>428)AND(MX<518)AND(MY>104)AND(MY<209)) THEN BEGIN ChoosePic(LogPID); SaveAs(FSPath,'**LogFile**'); ChoosePic(DirPID); SaveAs(FSPath,'**DirFile**'); IF MY<125 THEN NamePref ELSE IF ((MY>125)AND(MY<146)) THEN OffsetPref ELSE IF ((MY>146)AND(MY<167)) THEN ScreenPref ELSE IF ((MY>167)AND(MY<188)) THEN FramePref ELSE IF ((MY>188)AND(MY<209)) THEN AverPref END ELSE IF ((MX>422)AND(MX<520)AND(MY>231)AND(MY<273)) THEN ShowPrefs; ChoosePic(CPID); END; {########################################################################} PROCEDURE MainLoop; var CPID,LogPID,DirPID:integer; TopLineC,NrLines,NrSelections:integer; MarkAreaYLim:integer; aLine:string; HellFreezesOver:boolean; i,FSCode:integer; INVALIDSELECTION:boolean; BEGIN RequiresVersion(1.60); SaveState; WhereIsThePrefsFolder; IF FileFound=FALSE THEN EXIT; {#### E X I T if paths are incorrect ###} Preferences; ThePrefs; Open(FSPath,'**DirFile**'); DirPID:=PidNumber; Open(FSPath,'**LogFile**'); LogPID:=PidNumber; Open(PrefsPath,'CWIN'); MoveWindow(85,20); CPID:=PidNumber; SetForegroundColor(253); SetFont('Times'); SetFontSize(10); SetText('plain'); MoveTo(190,8); WriteLn('This copy is registered to:'); Write(WhoString); InvertY(FALSE); SetBackgroundColor(158); TopLineC:=1; SetBackgroundColor(2); RefreshWin(TopLineC); REPEAT SetCursor('Arrow'); GetMouse(MX,MY); IF (BUTTON AND((MY>59)AND(MY<401)AND(MX>22)AND(MX<409))) THEN REPEAT GetMouse(MX,MY); IF (BUTTON AND((MY>80)AND(MY22)AND(MX<409))) THEN Mark ELSE IF (BUTTON AND((MY>69)AND(MY<79)AND(MX>21)AND(MX<120))) THEN ScrollDn ELSE IF (BUTTON AND((MY>59)AND(MY<69)AND(MX>21)AND(MX<120))) THEN PgDn ELSE IF (BUTTON AND((MY>382)AND(MY<391)AND(MX>21)AND(MX<120))) THEN ScrollUp ELSE IF (BUTTON AND((MY>391)AND(MY<401)AND(MX>21)AND(MX<120))) THEN PgUp UNTIL BUTTON=FALSE ELSE IF (BUTTON AND ((MY>104)AND(MY<273)AND(MX>422)AND(MX<520))) THEN PrefsArea ELSE BEGIN IF (BUTTON AND((MY>30)AND(MY<53)AND(MX>21)AND(MX<121))) THEN CaptureFrames ELSE IF (BUTTON AND((MY>30)AND(MY<53)AND(MX>121)AND(MX<221))) THEN Match ELSE IF (BUTTON AND((MY>30)AND(MY<53)AND(MX>221)AND(MX<321))) THEN Build ELSE IF (BUTTON AND((MY>30)AND(MY<53)AND(MX>321)AND(MX<421))) THEN Dsps ELSE IF (BUTTON AND((MY>409)AND(MY<432)AND(MX>21)AND(MX<421))) THEN QuitNBye; END; UNTIL HellFreezesOver; RestoreState; END; MACRO'еееееееееееееееееее'; BEGIN END; MACRO'AutoMatch 3.0b [F1]'; BEGIN MainLoop; END; MACRO'еееееееееееееееееее'; BEGIN END; MACRO'(-' BEGIN END; MACRO'Oh bugger, it crashed'; BEGIN DisposeAll; MainLoop; END;