// Intersect Method for quantitative metallugraphy, // by Christopher Coulon, www.gaiag.net, // for Ali Soleimani Dorcheh, Max Plank Institute for Intelligent Systems. // // This macro is intended to convert a large amount of data from one or more images // to a few meaningful quantitative parameters which helps (in this context) // to understand the three dimensional characteristics of the microstructure of materials. // A manual systematic image analysis can be very time consuming // since it requires a person who can characterize the image visually // via different technics. Computer aided image analysis not only enhances the efficiency // of the method and avoids biased results due to operating errors, // but also enables us to collect enough data to provide statistical conclusions. // // This work provides a macro which utilizes ImageJ tools and provides // an automated quantitative method for phase analysis based on counting method. // The targeted systems are multi-phase alloys which have different phases // with distinct interphase boundaries. A system composed of two phases in Cr-Cr3Si // system is used to evaluate the functionality of the macro in such systems. // // For details of usage, please email Chris (chris@gaiag.net) // or Ali (soleimani.ali@gmail.com). var step =50; var angle =0; var name, title, path, dir, resultsDir; var areaFraction; var gridType; var Width, Height, imageArea = 0; var voxelW, voxelH; var lineCount; var lineTotal = 0, ROItotal = 0; var invertImage = true; var timeString; var ANDlinesPercent = 0, ROIpercent = 0; var distance, unit; var totalSum, totalLineCount, noEdgeSum, noEdgeLineCount, edgeParticles; var intersections, wEdgeLines, noEdgeLines; var options = false, start = true; macro "Grid Tool - C00cT1f1aG" {} macro "Grid Tool Options" { path = File.openDialog("Select a File"); dir = File.getParent(path); name = File.getName(path); list = getFileList(dir); start = true; for (i=0; i 0) run("Invert"); } function sumLines() { run("Set Measurements...", " feret's limit redirect=None decimal=5"); run("Analyze Particles...", " clear"); nr = nResults; wEdgeLines = newArray(nr); totalSum = 0; for (i = 0; i < nr; i++) { totalSum += getResult("Feret", i); wEdgeLines[i] = getResult("Feret", i); } totalMean = totalSum / nr; sumDiff = 0; for (i = 0; i < nr; i++) { x = getResult("Feret", i); sumDiff += (x - totalMean)*(x - totalMean); } totalSD = sqrt(sumDiff / (nr - 1)); totalLineCount = nResults; selectWindow("Results"); // saveAs("Results", resultsDir + name + "_allLines.xls"); run("Analyze Particles...", " exclude clear"); nr = nResults; noEdgeLines = newArray(nr); noEdgeSum = 0; for (i = 0; i < nResults; i++) { noEdgeSum += getResult("Feret", i); noEdgeLines[i] = getResult("Feret", i); } noEdgeMean = noEdgeSum / nr; sumDiff = 0; for (i = 0; i < nr; i++) { x = getResult("Feret", i); sumDiff += (x - noEdgeMean)*(x - noEdgeMean); } noEdgeSD = sqrt(sumDiff / (nr - 1)); noEdgeLineCount = nResults; edgeParticles = totalLineCount - noEdgeLineCount; numberOfIntercepts = noEdgeLineCount + (edgeParticles / 2); selectWindow("Results"); // saveAs("Results", resultsDir + name + "_noEdgeLines.xls"); write ("All intercepts = " + totalLineCount); write ("No edge intercepts = " + noEdgeLineCount); write ("Edge intercepts = " + edgeParticles); write ("\n********** All Intercepts **********"); ne = totalLineCount * 2; write ("Total Overlap Length = " + totalSum); write ("Line Intercepts = " + totalLineCount); write ("Intersections = " + ne); write ("Average Length All = " + totalMean); write ("Standard Deviation All = " + totalSD); write ("****************************************"); write ("\n*********** All with Half Edge Intercepts ***********"); intersections = noEdgeLineCount * 2 + edgeParticles; write ("Total Overlap Length = " + totalSum); write ("Line Intercepts = " + numberOfIntercepts); write ("Intersections = " + intersections); write ("****************************************"); write ("\n********** Only No Edge Intercepts **********"); ne = noEdgeLineCount * 2; write ("No Edge Overlap Length = " + noEdgeSum); write ("Line Intercepts = " + noEdgeLineCount); write ("Intersections = " + ne); write ("\nAverage Length non-Edge = " + noEdgeMean); write ("Standard Deviation non-Edge = " + noEdgeSD); write ("****************************************"); return numberOfIntercepts; } function gridOptions() { Dialog.create("Grid"); Dialog.addNumber("Step (in pixels):", step); Dialog.addNumber("Angle (in degrees):", angle); // Dialog.addCheckbox("Set Grid for All", false); Dialog.show; step = Dialog.getNumber(); angle = Dialog.getNumber(); // options = Dialog.getCheckbox(); } function dumpImages() { selectWindow(title); close("\\Others"); } function closeResults() { if (isOpen("Results")) { selectWindow("Results"); run("Close"); } if (isOpen("ROI Manager")) { selectWindow("ROI Manager"); run("Close"); } if (isOpen("Log")) { selectWindow("Log"); run("Close"); } if (isOpen("Threshold")) { selectWindow("Threshold"); run("Close"); } if (isOpen("Debug")) { selectWindow("Debug"); run("Close"); } }