Last active
January 28, 2021 16:41
-
-
Save ekatrukha/46b928f7d4559771dff69c4c31153177 to your computer and use it in GitHub Desktop.
ImageJ macro for illustration of "Straighten" ROI function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Providing an image and polyline, macro illustrates | |
// (creates a stack with animation) | |
// "Straighten" ROI function of ImageJ | |
// 2021.01.28 Eugene Katrukha / katpyxa at gmail dot com | |
if (nImages<1) | |
{ | |
exit("This macro needs an input image. Open something"); | |
} | |
if(selectionType()!=6) | |
{ | |
exit("Please, first you need to make a polyline selection (ROI)."); | |
} | |
origID=getImageID(); | |
imH=getHeight(); | |
imW=getWidth(); | |
Dialog.create("Create straightening animation") | |
Dialog.addNumber("Final number of frames in the animation (>1):", 12); | |
Dialog.addNumber("Resampling factor in pixels (0.1-1):", 0.5); | |
Dialog.addMessage("Smaller resampling = longer processing, less artifacts"); | |
Dialog.addCheckbox("Pre-fill slides with foreground color (unchecked=black,0)", false); | |
Dialog.addCheckbox("Batch mode? (hide intermediate steps)", false); | |
Dialog.show(); | |
steps=Dialog.getNumber()-1; | |
resampleFactor=Dialog.getNumber(); | |
bFill=Dialog.getCheckbox(); | |
bBatch=Dialog.getCheckbox(); | |
if(bBatch) | |
setBatchMode(bBatch); | |
imTitle=getTitle(); | |
run("Fit Spline"); | |
strrun="interval="+toString(resampleFactor)+" smooth"; | |
run("Interpolate", strrun); | |
Roi.getCoordinates(x2,y2); | |
selectImage(origID); | |
l = x2.length; | |
//orientation of poly line ROI (assumed from left to right, LR), | |
//needs to be reversed, if from right to left | |
bROI_LR=true; | |
if(x2[0]>x2[l-1]) | |
{ | |
bROI_LR=false; | |
} | |
//mean x and y | |
xMean=0; | |
yMean=0; | |
for(i=0;i<l;i++) | |
{ | |
xMean+=x2[i]; | |
yMean+=y2[i]; | |
} | |
xMean=xMean/l; | |
yMean=yMean/l; | |
w=Roi.getStrokeWidth; | |
//makeLine(xMean-l*0.5*resampleFactor, yMean, xMean+l*0.5*resampleFactor, yMean, w); | |
if(imW<(xMean+l*0.5*resampleFactor)) | |
{ | |
imWN=xMean+l*0.5*resampleFactor+5; | |
} | |
else { | |
imWN=imW; | |
} | |
imBit=bitDepth(); | |
if (imBit==24) { | |
newImage("Straighten_"+imTitle, "RGB", imWN, imH, 1, 1, steps+1); | |
} | |
else { | |
newImage("Straighten_"+imTitle, toString(imBit)+"-bit", imWN, imH, 1, 1, steps+1); | |
} | |
anim=getImageID(); | |
selectImage(origID); | |
x0=newArray(l); | |
y0=newArray(l); | |
for(i=0;i<l;i++) | |
{ | |
if(bROI_LR) | |
{x0[i]=xMean-l*0.5*resampleFactor+i*resampleFactor;} | |
else | |
{x0[i]=xMean+l*0.5*resampleFactor-i*resampleFactor;} | |
y0[i]=yMean; | |
} | |
xn = newArray(l); | |
yn = newArray(l); | |
selectImage(anim); | |
showStatus("Making straightening animation..."); | |
showProgress(0.0); | |
for(s=0;s<=steps;s++) | |
{ | |
showStatus("Making straightening animation...frame("+toString(s+1)+"/"+toString(steps+1)+")"); | |
setSlice(s+1); | |
if(bFill) | |
floodFill(1, 1); | |
//building new polyline | |
for(i=0;i<l;i++) | |
{ | |
xn[i]=x2[i]+s*(x0[i]-x2[i])/steps; | |
yn[i]=y2[i]+s*(y0[i]-y2[i])/steps; | |
} | |
//get new line along the width | |
xw=newArray(l); | |
yw=newArray(l); | |
for (dk=0;dk<=w;dk+=resampleFactor) | |
//for (dw=-0.5*w;dw<=0.5*w;dw+=0.5) | |
{ | |
if(dk<=0.5*w) | |
dw=dk; | |
else { | |
dw=dk-0.5*w; | |
dw=(-1)*dw; | |
} | |
//dw=0.5*w; | |
//going through old polyline | |
vals=newArray(l); | |
selectImage(origID); | |
for(i=0;i<(l-1);i++) | |
{ | |
x=x2[i+1]-x2[i]; | |
y=y2[i+1]-y2[i]; | |
lv=sqrt(x*x+y*y); | |
x=x/lv; y=y/lv; | |
//rotate 90 degrees | |
xp=-y; yp=x; | |
x=xp*dw; | |
y=yp*dw; | |
xv=x2[i]+x; | |
yv=y2[i]+y; | |
vals[i]=getPixel(xv, yv); | |
} | |
//last point | |
x=x2[l-2]-x2[l-1]; | |
y=y2[l-2]-y2[l-1]; | |
lv=sqrt(x*x+y*y); | |
x=x/lv; y=y/lv; | |
xp=y; yp=-x; | |
x=xp*dw; y=yp*dw; | |
xv=x2[l-1]+x; | |
yv=y2[l-1]+y; | |
vals[l-1]=getPixel(xv, yv); | |
//going through new polyline | |
selectImage(anim); | |
for(i=0;i<(l-1);i++) | |
{ | |
x=xn[i+1]-xn[i]; | |
y=yn[i+1]-yn[i]; | |
lv=sqrt(x*x+y*y); | |
x=x/lv; y=y/lv; | |
//rotate 90 degrees | |
xp=-y; yp=x; | |
x=xp*dw; | |
y=yp*dw; | |
xt=xn[i]+x; | |
yt=yn[i]+y; | |
setPixel(xt,yt,vals[i]); | |
} | |
//last point | |
x=xn[l-2]-xn[l-1]; | |
y=yn[l-2]-yn[l-1]; | |
lv=sqrt(x*x+y*y); | |
x=x/lv; y=y/lv; | |
xp=y; yp=-x; | |
x=xp*dw; y=yp*dw; | |
xt=xn[l-1]+x; | |
yt=yn[l-1]+y; | |
setPixel(xt,yt,vals[l-1]); | |
if(!bBatch) | |
updateDisplay(); | |
} | |
showProgress(s/steps); | |
} | |
showStatus("Making straightening animation...Done."); | |
if(bBatch) | |
{ | |
selectImage(anim); | |
setBatchMode(false); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment