How to Stitch 25 images with different dynamic range
Show older comments
Hi all,
Actually the question about how to take care of already stitched picture. I don't have any questions about the stitched process itself, I know how to do it. However after I do stitch I see the transition between the pictures. I would like to make a smooth transition between the pictures (see red arrows).

Every picture has 768X768 pixels. Every picture has a different dynamic rangle. So first of all I'd like to bring all the pictures to the same dynamic range, then to make slope compenstation on each picture and maybe then to stitch all of them. See the picture above one of the 25 pictures. I did mesh (X,Y,Z) and turned around this picture to show you the slope. I'd like to remove that slope.

I saw in one of the topics (https://www.mathworks.com/matlabcentral/answers/86498-how-to-blend-image) Image Analyst suggested to "You can use conv2() to blur the edge zone of the stitched pair, or you can stitch with a weighted average so that each edge has a ramp where it goes from full strength to zero." But how exactly to do this? Can you give me some example how to do it?
Here I attached 2 matrices for example to show you the slope and different dynamic ranges between them. So I'd like to bring all the matrices I have (25) to the same dynamic range and make slope compensation of each matrix I have.
Thank you very much.
P.S. If you want to stitch these two matrices you should put them as following:

Answers (3)
Bjorn Gustavsson
on 26 Jan 2021
You could do something like this to level the regions:
dI = mean(Im(row_above,:)-Im(row_above+1,:)); % Perhaps median works better, depends on intensity variance
Im(1:row_above,:) = Im(1:row_above,:) - dI/2;
Im(row_below:end,:) = Im(row_below:end,:) + dI/2;
Then you simply have to step through all the seams to level the entire image. You should also keep track of all the dIs to know where the absolute intensity-correction goes.
HTH
4 Comments
Dimani4
on 26 Jan 2021
Bjorn Gustavsson
on 26 Jan 2021
No, not exactly. In the image you show above it seems as if you have stitched together 5 rows of images above each other, right?
That would make the boundaries be on row-numbers:
Rows_above = 768*[1:4];
for iRow = 1:numel(Rows_above)
row_above = Rows_above(iRow);
row_below = row_above + 1;
dI = mean(Im(row_above,:)-Im(row_above+1,:)); % Perhaps median works better, depends on intensity variance
Im(1:row_above,:) = Im(1:row_above,:) - dI/2;
Im(row_below:end,:) = Im(row_below:end,:) + dI/2;
end
This would take the mean (or median if that works better...) of the difference between intensities above and below the stitching, and then shift the two parts half of that. This works if you have a constand zero-level offset for each different image. Then you have to repeat the procedure for each stitching. You can also use more than one line above and below - just check that you get a good scalar off-set to work with
Bjorn Gustavsson
on 27 Jan 2021
OK, so your spiky higher-intensity-regions vary much between the sub-images, while the smoother low-intensity-bands are reasonably similar. After looking at the 2 matrices in your files it is not exactly clear to me what you want to achieve...
Here's the 2 stitched images with columns 190 and 300 to the right and rows 768 and 769 below.

and here's a zoom in on a part of the intersection-region:

If you want to level the low-intensity regions you have to adapt my snipped to also select only the low-intensity-regions (here columns ~140-218 etc and calculate the average difference between the pixels in those regions...)
If you want something else you have to give a more detailed explanation.
Dimani4
on 28 Jan 2021
3 Comments
Bjorn Gustavsson
on 28 Jan 2021
OK, now I understand that part of the problem. Since your columns of bright-spots are not aligned with the columns this becomes a more labour-intensive task. I'd go about it something like this:
1, rotate the 768x768 images such that the spike-columns align with the image-columns, you can use imrotate, see the help and documentation for that function. I'd use 'bicubic' for method, and 'loose' for the bbox.
2, do your adjustments column-by-column to your hearts content. (I havent fully understood what you want to do to what purpose, but I'm happy to assume you have a plan.)
3, rotate back to the original orientation. It seems to me that you'll have to do that to get the stitching right.
4, crop that rotated-back image to your initial 768x768 size.
5, stitch.
6, celebrate?
Bjorn Gustavsson
on 30 Jan 2021
If that gives you a correction you're happy with, then all's well that ends well?
9 Comments
Bjorn Gustavsson
on 1 Feb 2021
If you want to normalize max and min of each image to 0 to 1, you can do this:
ImNorm = (Im-min(Im(:)))/(max(Im(:))-min(Im(:)));
Dimani4
on 2 Feb 2021
Dimani4
on 2 Feb 2021
Image Analyst
on 2 Feb 2021
How were the images captured in the first place? Did you take a "blank shot" so that you can do a background correction to flatten it? All cameras have shading where it's darker at the endge than at the center and you need to take a photo of a uniform field to know the percentage of light at each pixel and to correct for that (in most cases division but for some cases, such as x-ray or fluorescence, subtraction).
Dimani4
on 2 Feb 2021
Bjorn Gustavsson
on 2 Feb 2021
Stay off the histogram-matching. That is not the right way to solve this problem.
Image Analysts suggestion to make a proper background correction is important.
However, you now seem to be back at the initial problem-description. Meaning that you now have intensity-transitions at the stitchings. I suggested that you can remove these transitions by leveling the dark bands. Something like this:
Rows_above = 768*[1:4];
for iRow = 1:numel(Rows_above)
row_above = Rows_above(iRow);
row_below = row_above + 1;
dI = mean(Im(row_above,idx_darkBands{iRow}))-...
Im(row_above+1,idx_darkBands{iRow}))); % Perhaps median works better, depends on intensity variance
Im(1:row_above,:) = Im(1:row_above,:) - dI/2;
Im(row_below:end,:) = Im(row_below:end,:) + dI/2;
end
I suggest you do this on each individual column of images before stitching the columns together. You also have to create the cell-array of indices, idx_darkBands,to the dark bands for each image-pair.
This should get rid of the horizontal intensity-steps at the stitches.
Dimani4
on 3 Feb 2021
Bjorn Gustavsson
on 3 Feb 2021
In my comment from "27 Jan 2021 at 16:06" I have a horizontal line-plot in the embedded figure. In that one there are 2 rows plotted, one from just above the stitch, one from just below. In those lines you have low-intensity-regions at (approximately) 150-215, 370-430 and 590-660. Removing the intensity-difference between regions would be my first step. Since your bands have a slight slope you will have to save these indices for each stitching. So in order to run my attempt you would have to make a cell-array with those indices for each stitching. Perhaps a 2-D cell-array would be best, organized to match your image-stitching. Something like this:
iRow = 1;
iCol = 1;
idx_darkBands{iRow,iCol} = [150:215,370:430,590:660];
Then you'd have to add the indices for the dark bands at each stitching in the vertical direction between the first column of images by incremental iRow and then start over with the second column of images. If you do this you'll have to modify my snippet to account for the cell-array being 2D.
Dimani4
on 4 Feb 2021
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






















