Batch process about color balance? Channel is always the same!

Sample image and/or macro code

run(“Make Composite”);
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Stack to RGB”);.

(If this is your first post, you may not be able to attach images, in which case make a post with a link or a first post without the image attachment and a second one with)

Background

Analysis goals

I just want to batch processsing some images which are uncalibrated. First step is make composite. The second step is auto adjust contrast in the Color balance.

Challenges

There are three channel of my images, but whatever the channel is the marco records always showing the same thing. So the other two channel still not change.

Hi @NaN,

After the “Make Composite” command, you have a hyperstack with 3 channels. The “Enhance Contrast” command will be applied to the active (selected) channel. Since you never change the selected channel, it is applied 3 times to the same channel.
You can change the selected channel with Stack.setChannel(n), where n is the index of the channel starting with 1.

Best regards,
Volker

Hi volker,
Thanks so much for your reply, I did it again according to your advice. It worked well in first and last images but the left were not that good. Some of them changed nothing and some are changed one or two channel.
Here are my marcos:
run(“Make Composite”);
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(2)
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(3)
run(“Enhance Contrast”, “saturated=0.35”);
run(“Stack to RGB”);

Yours sincerely,
NaN

Could it be that the contrast enhancement is simply not visible in some cases? Saturated=0.35 means that the line that maps the intensity values to display values is chosen, so that 0.35% of the pixels are allowed to become saturated. Depending on your image it may not change at all.
Maybe you could try with a very high value for ‘saturated’ (50 or 95), just to check that it works technically.
Best regards,
Volker

Thank you again for your advices! The Saturated=0.35 is a fixed value if you choose auto in color balance when operated manually. So I recorded it. But when batch-processing some images seems not worked well. And there is a image which was mishandled.

Yours sincerely,
NaNlate stage of eggs (2).tif (5.5 MB)

I guess the problem is the processed images which were not closed could influence the next images. And I did a experiment which confirmed it. So I want to know if there is any
marco can close the previous images in batch-processing.

The close() command, closes the active image, see:
https://imagej.nih.gov/ij/developer/macro/functions.html#close

You can close the active image before opening the next one.

Hi,
Here are my marcos:
run(“Make Composite”);
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Close”);
run(“Color Balance…”);
Stack.setChannel(2)
run(“Enhance Contrast”, “saturated=0.35”);
run(“Close”);
Stack.setChannel(3)
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Close”);
run(“Stack to RGB”);
run(“Save”);
close();

The truth is that the previous images never closed and I guess it should be selected first.
But the Selectwindow() coomand is a liitle bit difficult to me. So what should I do to select the images or make it actived. Thanks a lot for your advices!

Hi @NaN,

you start with one rgb-image, right? “Make Composite” transforms it into one image that is a hyperstack with 3 channels. run(“Close”) will close the hyperstack and there will be no image open anymore, so the Stack.setChannel(2) will fail. If you remove all the run(“Close”); commands it should be fine. The close at the end will close the only open image.

To answer your question of how to select (and close images). In your macro just after the image is created or opened, get it’s image ID (id = getImageID()). When you want to select the image (make it active) use selectImage(id).

Hi, volker
Thank you so much for your advices. Actually there is a bug comes when I put this marcos in. And the debug window shows:

Memory * 187MB of 6041MB (3%)
nImages() 3
getTitle() “early stage of eggs.tif (RGB).tif”
i 0
id * -302


Error: Image -302 not found in line 11:
selectImage ( ) ;

What should I do to solve this bug? I’d appreciate it if you could give me some advices.

And my marcos here:

id=getImageID();
run(“Make Composite”);
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(2);
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(3);
run(“Enhance Contrast”, “saturated=0.35”);
run(“Stack to RGB”);
run(“Save”);
selectImage(id);
close();

Yours sincerely,
NaN

Hi,
this occurs because the “Make Composite” will create a new image with a new id and close the original image. You can move the line

id=getImageID();

below the “Make Composite” command.

If your aim is just to close all open images at the end, you can just use run("Close All"); at the end of the macro, so you do not have to select.

You could also provide a path for the save-command so that the user does not have to select one manually.

Hi,
Thank you again for your advices. After one failure after another, I decided to delete the “Stack to RGB” command which created the second images. And this command would be used in next batch-processing. Here are my marcos:

run(“Make Composite”);
run(“Color Balance…”);
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(2);
run(“Enhance Contrast”, “saturated=0.35”);
Stack.setChannel(3);
run(“Enhance Contrast”, “saturated=0.35”);
saveAs(“Tiff”, “G:\NEW1\NEW(2)\TEST”);
run(“Close All”);

And unfortunately there is a bug comes:

Memory * 68MB of 6041MB (1%)
nImages() 1
getTitle() “early stage of eggs.tif”
i 0


Error: ‘)’ expected in line 9:

	<run> ( "Close All" ) ; 

Sorry I’m not good at this technical matter. Could you give me some advices?

Yours sincerely,
NaN

Hi @NaN,

it’s probably related to the backslash characters in the path. The backslash is also an escape character for strings, so you need to use two backslashes (\) to represent one without its escape function. I think you can also use slashes instead of backslashes in java, even on windows.

Best,
Volker

Hi volker,
Thank you so much for your advices.
The marcos record when batch-processing seems like this:

run("Macro… ", “output_format=TIFF file= text1=[run(“Color Balance…”);\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nrun(“Color Balance…”);\nStack.setChannel(2)\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nStack.setChannel(3)\nrun(“Color Balance…”);\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nsaveAs(“Tiff”, “G:/NEW1/NEW(2)/TEST2”);\nclose();\n\n\n\n]”);
run("Macro… ", “input=[G:/NEW1/NEW(2)/embryo images of Boettcherisca peregrina/] output=G:/NEW1/NEW(2)/TEST/ output_format=TIFF file= text1=[run(“Color Balance…”);\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nrun(“Color Balance…”);\nStack.setChannel(2)\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nStack.setChannel(3)\nrun(“Color Balance…”);\nrun(“Enhance Contrast”, “saturated=0.35”);\nrun(“Close”);\nsaveAs(“Tiff”, “G:/NEW1/NEW(2)/TEST2”);\nclose();\n\n\n\n]”);
run("Macro… ");

Is there any ways I could do to solve this problem?

Yours sincerely,
NaN

What is the problem? Running

run("Make Composite");
run("Enhance Contrast", "saturated=0.35");
Stack.setChannel(2);
run("Enhance Contrast", "saturated=0.35");
Stack.setChannel(3);
run("Enhance Contrast", "saturated=0.35");
run("Stack to RGB");

with the Batch Processor (Process>Batch>Macro…) seems to work fine.
Note: You do not need the run("Color Balance…"); which only opens the dialog for manual adjustment.

Hi, volker,

Thanks for your reply. The problem is that batch-processing can not close image one by one in this situation. Even though I put the close() command in, images still act on each other. The final result is always not the same as processing images manually.

Yours sincerely,
NaN

Hi @NaN,

can you make your series of input-images available?

Best regards,
Vokler

Hi, volker,

Thank you for your reply,

embryo images of Boettcherisca peregrina.zip (9.0 MB)

As you can see, these images need to be processed. whatever I did, the results of batch-processing are not that good.

Yours sincerely,
NaN

Hi @NaN,
I could reproduce the problem. There seems to be a bug in ImageJ. Try this macro as a work-around. You can use it with the Batch-Processor.

run("Make Composite");
imageID = getImageID();
Stack.setChannel(1);
resetMinAndMax();
enhanceContrast();
Stack.setChannel(2);
resetMinAndMax();
enhanceContrast();
Stack.setChannel(3);
resetMinAndMax();
enhanceContrast();
run("Stack to RGB");
selectImage(imageID);
close();

function enhanceContrast() {
	AUTO_THRESHOLD = 5000;
	getRawStatistics(nPixels, mean, min, max, std, histogram);
	limit = nPixels/10;
	threshold = nPixels/AUTO_THRESHOLD;
	i = -1;
	found = false;
	count = 0;
	do {
		i++;
		count = histogram[i];
		if (count>limit) count = 0;
	    found = count> threshold;
	} while (!found && i<255)
	hmin = i;
	i = 256;
	do {
	    i--;
	    count = histogram[i];
	    if (count>limit) count = 0;
	    found = count > threshold;
	} while (!found && i>0);
	hmax = i;
	if (hmax>=hmin) {
		min = min+hmin*1;
	    max = min+hmax*1;
	    if (min==max) {
	    	min=stats.min; max=stats.max;
	    }
	    setMinAndMax(min, max);
	}
}

Pressing the “Auto”-button on the B&C-Adjuster, does not give the same result as the macro command run("Enhance Contrast", "saturated=0.35") that is recorded. The macro command gives the same result as the “Enhance Contrast…” menu command. Both have their own implementation. The difference is rather small, but if the range of values in the image is small the results can be drastically different.