//Macros to demonstrate Array.findMaxima() and Array.findMinima() //N. Vischer 07-Mar-2017 macro "Maxima in histogram [1]"{ run("Lena (68K)"); //selectImage("lena-std.tif"); run("8-bit"); getStatistics(area, mean, min, max, std, histogram); Plot.create("Detecting Histogram Peaks", "X", "Y", histogram); Plot.freeze(true); Plot.show; maxLocs= Array.findMaxima(histogram, 500); print("\\Clear"); print("\nMaxima (descending strength):"); for (jj= 0; jj < maxLocs.length; jj++){ x= maxLocs[jj]; y = histogram[x]; print("x= ", x, " y= ", y); toUnscaled(x, y); makeOval(x-5, y-5, 9, 9); run("Invert"); } run ("Select None"); } macro "Minima in TreeRings [2]"{ run("Tree Rings (48K)"); //selectImage("Tree_Rings.jpg"); makeRectangle(727, 31, 45, 46);//demonstrate flat minimum changeValues(0, 255, 56); run("Line Width...", "line=10"); makeLine(558, 47, 849, 54); profile =getProfile; Plot.create("Detecting Minima", "X", "Y", profile); Plot.freeze(true); Plot.show; minLocs= Array.findMinima(profile, 10); print("\\Clear"); print("Minima (descending strength):"); for (jj= 0; jj < minLocs.length; jj++){ x= minLocs[jj]; y = profile[x]; print("x= ", x, " y= ", y); toUnscaled(x, y); makeOval(x-4, y-4 + 1, 8, 8); run("Invert"); } run ("Select None"); } macro "Extrema of current line profile [3]"{ if (selectionType<5 || selectionType > 7) exit("need line selection"); close("Detecting*"); tolerance = 20; profile =getProfile; Plot.create("Detecting Minima and Maxima", "X", "Y", profile); Plot.freeze(true); Plot.show; minLocs= Array.findMinima(profile, tolerance); print("\\Clear"); print("Minima (descending strength):"); for (jj= 0; jj < minLocs.length; jj++){ x= minLocs[jj]; y = profile[x]; print("x= ", x, " y= ", y); toUnscaled(x, y); makeOval(x-4, y-4 + 1, 8, 8); run("Invert"); } maxLocs= Array.findMaxima(profile, tolerance); print("\nMaxima (descending strength):"); for (jj= 0; jj < maxLocs.length; jj++){ x= maxLocs[jj]; y = profile[x]; print("x= ", x, " y= ", y); toUnscaled(x, y); makeRectangle(x-4, y-4 + 1, 8, 8); run("Invert"); } run ("Select None"); } /* Array.FindMaxima(array, tolerance, edgeMode) * edgeMode = 0 (include edges) peak may be separated by one qualified valley and by a border. * edgeMode = 1 (exclude edges) peak must be separated by two qualified valleys * edgeMode = 2 (circular) array is regarded to be circular * @return Positions of peaks, sorted with decreasing amplitude */ macro "EdgeMode Demo [4]"{ sign = 1; //set sign=1 for maxima, sign=-1 for minima close("*EdgeMode*"); print("\\Clear"); print("\nExtrema (descending strength):"); myArray = newArray(720); for (jj = 0; jj < myArray.length; jj++){ myArray[jj] = sign * sin((jj+50)/180*PI) * 2000; } tolerance = 500; yLoc = 100; for (edgeMode = 0; edgeMode <= 2; edgeMode++){ print("\n-- EdgeMode = ", edgeMode); if (sign == -1){ maxLocs= Array.findMinima(myArray, tolerance, edgeMode); Plot.create("FindMinima, EdgeMode = " + edgeMode, "X", "Y", myArray); } if (sign == 1){ maxLocs= Array.findMaxima(myArray, tolerance, edgeMode); Plot.create("FindMaxima, EdgeMode = " + edgeMode, "X", "Y", myArray); } Plot.setColor("blue"); Plot.setFrameSize(220, 100); Plot.show; Plot.freeze(true); setLocation(50, yLoc); yLoc += 180; for (jj= 0; jj < maxLocs.length; jj++){ x= maxLocs[jj]; y = myArray[x]; print("x= ", x, " y= ", y); toUnscaled(x, y); setForegroundColor(255, 0, 0); fillOval(x-5, y-5, 9, 9); } run ("Select None"); } }