Skip to content

Instantly share code, notes, and snippets.

@mutterer
Last active September 23, 2021 11:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mutterer/4a8e226fbe55e8e682a1 to your computer and use it in GitHub Desktop.
Save mutterer/4a8e226fbe55e8e682a1 to your computer and use it in GitHub Desktop.
// yet another multichannel profile plotter
// with smart(?) lookuptables
// 20181114 : works as a macro Tool thanks to Sophie Allart
// plot x-axis is calibrated thanks to Christian Rouviere
// works with 16-bit images thanks to Tiago Ferreira (https://gist.github.com/tferr/863b630d7da2dbcdbed0/revisions)
// Add Image popup menu with Inverted Background command to get dark mode plots (Christian Rouvière)
// Add standard line adjusting behavior (Christian Rouvière)
// Works with RGB or Composite images
macro "multichannel profile plotter Tool - Cf00D02D13D14D24D25D26D27D38D46D47D56D65D75D85D95Da5Db5Dc5Dc6Dd6Dd7Dd8De7De8Df6Df7C00fD09D1aD1bD2cD2dD2eD3eD3fD4dD4eD5cD6bD7bD7cD8bD9aDabDbaDcaDdbDdcDddDecDedDfbC000T06102"{
specialCase = 0; // 1= startpoint; 2= endpoint; 3= middlepoint
getCursorLoc(x, y, z, flags);
if (selectionType()==5) {
getLine(ax, ay, bx, by, lineWidth);
print(dist(ax,x,ay,y));
if (dist(ax,ay,x,y) <5 ) {
specialCase = 1;
} else if (dist(bx,by,x,y) <5 ) {
specialCase = 2;
} else if (dist((ax+bx)/2,(ay+by)/2,x,y) <5 ) {
specialCase = 3;
}
}
id=getImageID;
run("Select None");
getStatistics(null, null, min, max);
getPixelSize(unit, pixelWidth, pixelHeight);
Plot.create("Multi-Channel Profile Plot", "Distance ("+unit+")", "Value");
Plot.update();
selectImage(id);
setBatchMode(1);
run("Select None");
run("Duplicate...","title=temp duplicate");
setBatchMode("hide");
if (bitDepth==24) run ("Make Composite");
id2=getImageID;
autoUpdate(false);
while (flags&16!=0) {
selectImage(id);
getCursorLoc(x1, y1, z, flags);
if (specialCase==0) {
makeLine(x,y,x1,y1);
} else if (specialCase==1) {
makeLine(x1,y1,bx,by);
} else if (specialCase==2) {
makeLine(ax,ay,x1,y1);
} else if (specialCase==3) {
dx = x1-x; dy = y1-y;
makeLine(ax+dx,ay+dy,bx+dx,by+dy);
}
getLine(ax2, ay2, bx2, by2, lineWidth);
selectImage(id2);
makeLine(ax2, ay2, bx2, by2);
Stack.getDimensions(w, h, c, z, t);
p1 = getProfile();
for (i=0;i<p1.length;i++) p1[i] = i*pixelWidth;
Plot.create("Multi-Channel Profile Plot", "Distance ("+unit+")", "Value");
Plot.setLimits(0,p1[p1.length-1],min,max);
for (i=1;i<=c;i++) {
selectImage(id2);
makeLine(ax2, ay2, bx2, by2);
Stack.setChannel(i);
p = getProfile();
Plot.setColor(getLutColorName());
Plot.add("line", p1,p);
}
Plot.update();
}
Stack.setDisplayMode("Composite");
function getLutColorName() {
colors = newArray("black","blue","green", "cyan", "red", "magenta", "yellow", "black");
getLut(reds, greens, blues);
col = round(reds[255]/200)<<2+round(greens[255]/200)<<1+round(blues[255]/200);
return colors[col];
}
}
var pmCmds = newMenu("Popup Menu", newArray("Invert Background", "-"));
macro "Popup Menu" {
cmd = getArgument();
if (cmd=="Invert Background") {
run("Duplicate...", "title=Inverted_Background");
selectImage(nImages);
run("Invert");
run("HSB Stack");
run("Macro...", "code=v=(v+128)%256 slice");
run("RGB Color");
}
}
function dist(a,b,c,d) {
return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
@tferr
Copy link

tferr commented Nov 19, 2014

@mutterer This is really the neatest of all the "multichannel profile plotters".
I just extended it to 16/32-bit images and added a mention that the X-axis does not use calibrated units.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment