Forked from ekatrukha/straighten_animation_v2(20210128).ijm
Created
January 15, 2021 15:57
-
-
Save mutterer/d0eddb91db10cf2fbdb6fa34f6e1432c 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.15 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; | |
//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++) | |
{ | |
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