Displaying a sub-mask through the whole image using Macro

Description and analysis goal

  • Description: Similarly to the way the kernel is displayed through the whole image to apply a given filters (1), I would like to use a mask for which I segment the portion covered by the mask and so on (see my try in the bottom). The center of the mask should move by a step of 1 pixel.

example_cylindrical_rock.tif (1.9 MB)

(1) @haesleinhuepf has atatched an excellent animation to one of his presentations. Animation source: Dominic Waithe, Oxford University https://github.com/dwaithe/generalMacros/tree/master/convolution_ani
(if it’s not working see: https://github.com/dwaithe/generalMacros/ )

  • Analysis goals: I am interested in measuring the caracteristics of the image portion covered by the mask at each iteration.

What I would expect from you?

  • As I am not a programmer and this is my first month using Macro, I would like to use Macro and some of its functions to reproduce the same algorithm, so I can inspire from and apply for my case. After then, I will follow back by the next step. Here after is what I could’ve done and the associated challenges.
  • How can I select the thresholding method, or the limits. I tried but couldn’t succeed.
  • How can I make an interactive plot.
  • Actually, I want to know also how can I adort the opperation in the middle.
  • How can I add to the results two columns, the x and y (coord of the mask center)?

Challenges

I think the borders of the global image will be challenging to identify. After that, I would like to apply it for a variety of images selected from different folders.
A shown message displays: ROI is outside image!!

Hereafter what I am thinking will be the general skeleton of the algothim:

// @File(label = "Where are your vertical input images?)", style = "directory") input
// @File(label = "Output directory to save your results", style = "directory") output

run("Clear Results");
// --------- Read Image Properties ---------------------
//Select the image you want to treat
 open( "" );
 
    setBatchMode(true); // Keep operations runnin gin the background
    
	original = getImageID();
	
	//Configure Scale and Measurements
	run("Set Scale...", "distance=1 known=26 unit=um");
	run("Set Measurements...", "area standard centroid center perimeter area_fraction limit redirect=None decimal=3");

 // select manually the representative element by the user!
 waitForUser
	run("Duplicate...", "title=Original1");
	Original1 = getImageID();
 	// read image properties
 	width = getWidth(); // i
 	height = getHeight(); // j
 	print("The image is " + width + " times " + height + " pixels wide");

	// initialise parameters
	
	// floor ==> Get integer values!
	Wa = floor(width/10);
	Ha = floor(height/15);
	
	x = floor(Wa/2);  
	y = floor(Ha/2);
	step=1;
	Xlim = width - Wa/2; 
	Ylim= height - Ha/2;
	
	//start the work!!
	for (i = 0; i < Xlim; i++) {
				
				print("===================================================================");
				print("i= " + i +"   from   " + width + ", ------------------- Wa=" + Wa);
				print("===================================================================");
				
		for (j = 0; j < Ylim; j++) {
							

				ThreshElement(x , y);
				print("j= " + j + "   from   " + height + ", ----------- Ha=" + Ha + " ---------------- Center ( x=" + x + ", y=" + y + ")");
				y =y + step;
					
		}
		

		x = x + step;
		y = floor(Ha/2);
	}

	//saves results for all images in a single file
	saveAs("Results", output + "/Results2.csv");

	//still I need to print the values in real time; an interactive plot, but this is not!
	Plot.create("Plot of Results", "x", "%Area");
	Plot.add("Line", Table.getColumn("%Area", "Results"));
	Plot.setStyle(0, "blue,#a0a0ff,1.0,Line");



function ThreshElement(x , y) { 
// function's operations and steps applied to the mask
				//apply to original cropped image!
				selectImage(Original1);
				
				//makeRectangle(x, y, width, height);
				makeRectangle(x, y, Wa , Ha);
				run("Duplicate...", "title=mask"); //title=[""mask" + "(" + i + "," + j + ")"]
				Cropped = getTitle();
				run("8-bit");
				setAutoThreshold("Otsu"); // or a specific limits: setThreshold(119, 255); 
				//setOption("BlackBackground", true);
				run("Convert to Mask");
				run("Measure");
}


//close();

It is supposed to be simple, but I am confused!! Any suggestion or feedback would be so valuable, many thanks in advance!