Filter löschen
Filter löschen

Find the average of two images

54 Ansichten (letzte 30 Tage)
Marcus Johnson
Marcus Johnson am 16 Nov. 2023
Bearbeitet: DGM am 17 Nov. 2023
Hello,
I have these two dark images and I was wondering how to get the average of them.
Thanks!

Akzeptierte Antwort

DGM
DGM am 16 Nov. 2023
Bearbeitet: DGM am 16 Nov. 2023
% all GIF files are indexed color
% you must read the maps
[im1 map1] = imread('Im1.GIF');
[im2 map2] = imread('Im2.GIF');
% apply the maps
rgb1 = ind2rgb(im1,map1);
rgb2 = ind2rgb(im2,map2);
% the images must be floating-point for this to work
% otherwise, truncation is very likely to occur during addition
% bear in mind that im1 and im2 are going to be integer-class
imAvg = (rgb1 + rgb2)/2;
% show the image
imshow(imAvg)
% it's not exactly constant-valued
imhist(imAvg)
While in this specific case, both images use the same gray map, that's not generally something that we can expect. Similarly, while they're both gray and could be reduced from RGB to I, that's not generally true. We could reduce it if we knew that were appropriate.
if all(~diff(imAvg,2,3),'all')
imAvgGray = imAvg(:,:,1);
imagesc(imAvgGray)
colormap(jet)
end
  2 Kommentare
Image Analyst
Image Analyst am 16 Nov. 2023
I think this is the preferred, more robust answer. However you can convert to double, even if they are already double though I haven't heard of a gif that is already double.
imAvg = (double(rgb1) + double(rgb2))/2; % Cast to double to ensure sums don't clip at 255.
% Show the image. Must use [] if showing a gray scale double image.
imshow(imAvg, [])
Or you can cast back to the nearest integer if you want
imAvg = uint8(imAvg);
and then you wouldn't have to use [] in imshow. If the image is RGB, then the [] does not apply but the values have to either be floating point in the range 0-1, OR uint8 in the range 0-255, otherwise you'll likely have large areas of all black or all white in the image.
DGM
DGM am 16 Nov. 2023
Bearbeitet: DGM am 16 Nov. 2023
Ignoring the specific example above, the problem with generally using double() on the way in to operations is that you will need to keep track of what the input class was and conditionally re-cast or re-scale the ouput, something that's inconvenient because there is no equivalent to imcast() in IPT.
% this will be wrong if the input classes are not both uint8
imAvg = (double(rgb1) + double(rgb2))/2;
imAvg = uint8(imAvg);
% or you could use cast(), but they'd still need to match
imAvg = (double(rgb1) + double(rgb2))/2;
imAvg = cast(imAvg,class(rgb1));
This could be solved by using im2double() on the way in and asserting any fixed output class, but in the given case, the outputs from ind2rgb() are going to be double.
How would I do it?
% class agnostic, output class is inherited from BG
% inputs can be I/IA/RGB/RGBA, single or multiframe
% most modes are parametric, so weighted averages are available
outpict = imblend(FG,BG,0.5,'normal'); % 50% FG, 50% BG
outpict = imblend(FG,BG,1,'average'); % 50% FG, 50% BG
outpict = imblend(FG,BG,1,'average',1.5); % 75% FG, 25% BG
... but really, for 50% average, imfuse() would also work.
Maybe all that doesn't matter, if the average is always going to then be normalized anyway. I'm going to assume that's not the case. At least it's not something that can be relied upon to generally be true.
It kind of made sense to use [] for visualization, given that it's a relatively narrow range.
GIFs are always uint8 or logical.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Jon
Jon am 16 Nov. 2023
im1 = imread('Im1.gif');
im2 = imread('Im2.gif');
imAvg = (im1 + im2)/2;
imagesc(imAvg)
  5 Kommentare
Jon
Jon am 17 Nov. 2023
@DGM- Thanks for the thoughtful followup. No problem, on crediting the answer, I'm just trying to help when I can, but also learn, and I learned a lot here. Also made me realize I should be a little more careful when jumping into things I'm not well versed in. I do occassional image processing but usually monchrome .png's with simple pixel intensity stored in the array. I definitely should have remembered that these are returned as integers not doubles, and so they should be converted to doubles before, for example computing an average. I hadn't been aware of the further complexities of .gif files and indices to color maps. Thanks for helping me learn more.
DGM
DGM am 17 Nov. 2023
Bearbeitet: DGM am 17 Nov. 2023
As far as I'm concerned, I appreciate sincere motivations a lot more these days. There's plenty of room for answers that aren't ideal, so long as there's also room to improve. I'm not exactly careful myself :D
The canonical workflows suggested by the form of things in MATLAB/IPT leaves plenty of room for these sorts of problems with numeric class magically changing or causing incompatibility with mixed-class operations. MIMT might be a giant hobbyist embarrassment, but at least it's working toward providing class and depth-agnostic workflows in some ways. As I mentioned to IA, the way I would've done the averaging using imblend() wouldn't need to know the class of either input.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Image Processing Toolbox finden Sie in Help Center und File Exchange

Produkte


Version

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by