//////////////////////////////////////////////////// // ImageJ macros for non-linear LSM style correction of ellipical deformation. // Note: function assumes regular nonagon deformed by 1 (only) symmetrical ellipse. // Any other deformation: forget it! // // Largely replaces functions scripted in NIH. // // Scripted by Bill Wickstead //////////////////////////////////////////////////// // GLOBAL VARIABLES // // constants var pi=3.1415926536; // button-click variables var leftButton=16; var rightButton=4; var shift=1, ctrl=2, alt=8; var altClick=24, shiftClick=17; var pencilWidth=1, brushWidth=10; // variables associated with ellipse correction / polar transformation var T=0.000001; var axoScale=500; var thetaStep=pi/30; var alphaStep=pi/30; var minHit=4; var itMax=50; var firstUse=1; var cropImage=true; var cropSize=800; function PictureType() { info=getImageInfo(); index1=indexOf(info, 'Bits per pixel: '); index1 += 16; index2=indexOf(info, '(', index1); type=substring(info, index1, index2-1)+'-bit'; print(substring(info, index2+1, index2+4)); if (substring(info, index2+1, index2+4)=='RGB') { type='RGB'; } return type; } //////////////////////////////////////////////////// // Spectral addition tools // // Written by Bill Wickstead Jan 2006 macro ' --spectral addition--' {} macro 'Nine-fold rotation [n]' { run("Select All"); run("Copy"); if (getWidth()>getHeight()) { size=getWidth(); } else { size=getHeight(); } type=PictureType(); newImage('temp', type, size, size, 9); for (i=1; i<=9; i++) { setSlice(i); run("Paste"); } for (i=2; i<=9; i++) { setSlice(i); angle=(i-1)*40; run("Arbitrarily...", "slice angle="+angle+" interpolate"); } oldPic=getImageID(); run("Z Project...", "start=1 stop=9 projection=[Average Intensity]"); selectImage(oldPic); close; } // End of 'Nine-fold rotation' macro macro 'Ellipse correction [e]' { // Capture 9-fold points // if (firstUse==1) { // showMessage('Select 9 points for ellipse fitting\n(alt+click to Undo a point)'); firstUse=0; } setTool(7); x=newArray(9); y=newArray(9); // set arrays flagsOld=-1; i=0; while (i<9) { getCursorLoc(x1, y1, z1, flags); if (flags != flagsOld) { if (flags==altClick) { if (i>0) { i--; pointX=newArray(i); pointY=newArray(i); for (n=0; n0) { theta=atan((x[0]-x0)/(y[0]-y0)); } else if (y[0]-y0<0) { theta=pi+atan((x[0]-x0)/(y[0]-y0)); } else { if (x[0]-x0)>0) { theta=pi/2; } else { theta=3*pi/2; } } maxN=0; minN=0; for (i=0; i<9; i++) { d=sqrt(pow(x[i]-x0, 2) + pow(y[i]-y0, 2)); if (i==0) { a=d; b=d; } else { if (d>b) { b=d; maxN=i; } if (d0) { alpha=atan((x[maxN]-x0)/(y[maxN]-y0)); } else if (y[maxN]-y0<0) { alpha=pi+atan((x[maxN]-x0)/(y[maxN]-y0)); } else { if (x[maxN]-x0)>0) { alpha=pi/2; } else { theta=3*pi/2; } } aStep=a/20; bStep=b/20; xStep=a/500; yStep=xStep; alStep=alphaStep; thStep=thetaStep; // place permenant options into temp holders // output to Log window print("Ellipse Correction: ", name); print("Datapoints:"); for (i=0; i<9; i++) { print(' ',x[i], ' ', y[i]); } print('\nInitial values:'); print('x0: ', x0, ' y0: ', y0, '\ntheta: ', theta, '(', theta*180/pi, ') alpha: ', alpha, '(', alpha*180/pi, ')'); print('a: ', a, ' (dblt: ', minN+1, ')', ' b: ', b, ' (dblt: ', maxN+1, ')'); print('\nFitting...'); // fitting procedure SrOld=Nono(x0, y0, theta, alpha, a, b, x, y); hitCount=0; iterationCount=1; while (hitCountitMax) { exit("No convergence within itMax"); } } //end parameters output if (b