Changing the histogram for image stack based on numbers from another

I apologize if this topic has already been covered. I may not know the correct terms to use to look it up.

I feel that my description of the problem may be hard to convey as well.

I have two TIF image stacks that have some overlap. Unfortunately, the machine I use to create those images has a glitch that just started. However, I didn’t notice it until I set the specimen back to the client.

I usually reconstruct my imaging using the same histogram numbers based upon the stack that has the densest material. I then stitch those stacks together to create the whole specimen which has the same histogram throughout. This is because the data was gathered with the exact same settings.

The glitch I talked about earlier causes the imaging for the stacks to be created with a different histogram for each stack instead of a consistent one. If I were to stitch the stacks together, they would show a dramatic shift at the stitching point and would skew the data for the researcher.

Seems as if I should be able to find an image in each of the stacks that matches in the way you do if you are stitching them together. Then using the histogram info from one of the images, apply it to the second stack image and then transfer those settings throughout the rest of the second stack.

I think I know how to determine the histogram of the first image by using these steps, https://imagej.nih.gov/ij/docs/menus/analyze.html#hist

The top image is the incorrect histogram, the bottom is the correct one. Need them to match each other and then apply that through the whole stack.


The two image stacks are already reconstructed with the same histogram numbers, so just applying one set of numbers to the whole stack won’t work since the info was gathered with two different histograms.

Thank you for taking the time to help.

Hi @gabriel

Thank you for your reply.

I’m not sure what you are referring to in this link, but if it is histogram matching, the data already has a matched histogram. The original images were obtained with two different background settings, which causes the two stacks to not match even though you put in the same threshold numbers. As you can see in the images, the one obtained with the incorrect background settings is darker. I am looking to set the histogram for the second set based upon matching the histogram settings for just one image that matches the same image in the other stack.

Just for information purposes, I am not a scientist, programmer, or mathematician, so I might not be understanding what you are suggesting.

Hi, Sorry I might have misunderstood the problem, but you said:

and I thought you wanted to match the histogram of one image/stack to another. The link I posted describes the principle to do that. Perhaps somebody else here understands better the issue and will be able to help.

This is so hard to explain and I can’t come up with an analogy. The histograms show as and are matching. The stacks don’t come out the same though as different parameters were used on both. I applied the same histogram in the reconstruction of the TIF stacks and this is the result. The second stack doesn’t have anything in it that is as dense as the part that is the densest in the first stack. So, if you apply the same histogram to both without using the same settings while obtaining the data, you will get skewed values. Does that help? Or do you still have the same answer?

Hi Manon,
Below is a macro that hopefully does what you want. It takes your two images, creates a stack of these two images and aligns them (using Linear Stack Alignment with SIFT). It then creates an XY plot for each pair of pixels on the two images, which is fitted with a linear equation that can then be used to transform the pixel values of an image or image stack. In order to use it, open the two images with the correct and incorrect histogram plus the image stack that needs to be changed.
Run the macro code.
The macro asks you to select the image with the correct and incorrect histogram as well as the image/stack that needs to be corrected.
As the sample images were in RGB format, the images are converted to 8-bit greyscale.
I hope this helps,
Volko

list=getList("image.titles");

Dialog.create("Select Images");
Dialog.addChoice("Correct Histogram", list);
Dialog.addChoice("Incorrect Histogram", list);
Dialog.addNumber("Crop (0-1, 0 = no crop)", 0.1);
Dialog.addChoice("Apply correction to", list);
Dialog.show();
image1=Dialog.getChoice();
image2=Dialog.getChoice();
crop=Dialog.getNumber();
adjustStack=Dialog.getChoice();

selectWindow(image2);
run("Copy");
selectWindow(image1);
run("Duplicate...", "title=[Working Images]");
run("8-bit");
run("Add Slice");
run("Paste");
run("Linear Stack Alignment with SIFT", "initial_gaussian_blur=1.60 steps_per_scale_octave=3 minimum_image_size=64 maximum_image_size=1024 feature_descriptor_size=4 feature_descriptor_orientation_bins=8 closest/next_closest_ratio=0.92 maximal_alignment_error=25 inlier_ratio=0.05 expected_transformation=Translation interpolate");

getDimensions(width, height, channels, slices, frames);
makeRectangle(crop*width, crop*height, width-2*crop*width, height-2*crop*height);
run("Crop");

getDimensions(width, height, channels, slices, frames);
setSlice(1);
image1=newArray(width*height);
for (x = 0; x < width; x++) {
	for (y = 0; y < height; y++) {
		image1[x+(width)*y]=getPixel(x,y);
	};
};
setSlice(2);
image2=newArray(width*height);
for (x = 0; x < width; x++) {
	for (y = 0; y < height; y++) {
		image2[x+(width)*y]=getPixel(x,y);
	};
};

Fit.doFit("Straight Line", image1, image2);
print("a="+d2s(Fit.p(0),6)+", b="+d2s(Fit.p(1),6));
Fit.plot();

selectWindow(adjustStack);
getDimensions(width, height, channels, slices, frames);
run("8-bit");
for (i = 1; i < slices+1; i++) {
	setSlice(i);
	for (x = 0; x < width; x++) {
		for (y = 0; y < height; y++) {
			setPixel(x,y,getPixel(x,y)/Fit.p(1)-Fit.p(0));
		};
	};
};
2 Likes

OK, if I understand it better now, it is histogram matching after all. Note that the above code works when the two images can be aligned (like in the present case), but it cannot be applied to non-alignable images.
I dig out a bit more and found this:
http://imagej.1557.x6.nabble.com/Histogram-Matching-python-script-attached-questions-remain-td5022497.html
The simplified Python code posted by Curtis, works fine in Fiji.

Thank you both for your answers! I’ll give it a go this week hopefully and report back with my results.