Combine masked images into one, with each mask having a unique color.

12 vues (au cours des 30 derniers jours)
Alex Lefebvre
Alex Lefebvre le 12 Mai 2022
Commenté : Alex Lefebvre le 12 Mai 2022
Good day,
I'm tracking the migration of a spill into a soil column by taking pictures. The spill is dyed red and so I use Hue threholds to produce masked images and binary images (to track the spill in each image), then bwboundaries to produce contours. It gives me something like the image attached (left part) once I compile a few image contours. However, in addition to having contours, I'm hoping to assign a color to each area so it looks like the attached picture (on the right). I would rather track the progression of the spill by the fill color instead of the contour color (contours can all be black). However, I don't know how to proceed. What function do you recommend? If there's a more efficient way of doing this than what I've described so far, please let me know, my experience with mathlab is limited. Thank you.
  2 commentaires
DGM
DGM le 12 Mai 2022
Modifié(e) : DGM le 12 Mai 2022
I think that calculating the boundary images is going to be counterproductive toward that goal. It's probably going to be best to start somewhere back a few steps. That said, I don't know what your source or intermediate images look like, so I'm not sure what to recommend.
That said, this isn't really a contour map of a scalar field. It's a sequence of approximate flow fronts over time, so unlike a contour map, the lines can intersect. Trying to represent that with opaque fills may be visually confusing, and it becomes problematic trying to decide which "level" is on top. Consider the following simplified example:
% a set of binary images
m1 = imread('m1.png')>128;
m2 = imread('m2.png')>128;
m3 = imread('m3.png')>128;
m4 = imread('m4.png')>128;
M = cat(4,m1,m2,m3,m4);
sz = [size(M,1) size(M,2)];
% for sake of viewing, just take the mean
meanimg = mean(M,4);
% which filled "contour" level gets drawn on top?
imshow(meanimg)
In this example, if the smallest filled region (the earliest part of the flow) is shown on top, it obscures the features beneath it in subsequent images.
% get a colormap and create a color composite image
cmap = parula(4);
C = zeros([sz 3]);
for k = 4:-1:1
cpict = repmat(permute(cmap(k,:),[1 3 2]),sz);
thismk = repmat(M(:,:,:,k),[1 1 3]);
C(thismk) = cpict(thismk);
end
% early flow on top
imshow(C)
If the largest filled region (the latter part of the flow) is on top instead, a similar occlusion occurs.
% get a colormap and create a color composite image
cmap = parula(4);
C = zeros([sz 3]);
for k = 1:4
cpict = repmat(permute(cmap(k,:),[1 3 2]),sz);
thismk = repmat(M(:,:,:,k),[1 1 3]);
C(thismk) = cpict(thismk);
end
% late flow on top
imshow(C)
There probably is some conventional way to plot things like this, but I'm not familiar with it.
Alex Lefebvre
Alex Lefebvre le 12 Mai 2022
Those solutions are good for me! That's good thinking, you really understood what I meant. Thank you.

Connectez-vous pour commenter.

Réponse acceptée

DGM
DGM le 12 Mai 2022
If those would work for you, then you might also consider something like these:
% do a simple mean of colored frames
% a set of binary images
m1 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995325/m1.png')>128;
m2 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995320/m2.png')>128;
m3 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995315/m3.png')>128;
m4 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995310/m4.png')>128;
M = cat(4,m1,m2,m3,m4);
sz = [size(M,1) size(M,2)];
% get a colormap and colorize the frames
cmap = parula(4);
C = zeros([sz 3]);
for k = 1:4
C(:,:,:,k) = M(:,:,:,k).*permute(cmap(k,:),[1 3 2]);
end
% for sake of viewing, just take the mean
meanimg = mean(C,4);
% which filled "contour" level gets drawn on top?
imshow(meanimg)
% ignore underlying black regions when taking mean
% a set of binary images
m1 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995325/m1.png')>128;
m2 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995320/m2.png')>128;
m3 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995315/m3.png')>128;
m4 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/995310/m4.png')>128;
M = cat(4,m1,m2,m3,m4);
sz = [size(M,1) size(M,2)];
% get a colormap and colorize the frames
cmap = parula(4);
C = zeros([sz 3]);
for k = 1:4
C(:,:,:,k) = M(:,:,:,k).*permute(cmap(k,:),[1 3 2]);
end
% for sake of viewing, just take the mean
meanimg = mean(C,4);
% but compensate for underlying black regions
Mm = mean(M,4);
Mz = repmat(Mm==0,[1 1 3]);
meanimg = meanimg./Mm;
meanimg(Mz) = 0;
% which filled "contour" level gets drawn on top?
imshow(meanimg)
I'm sure the latter example could be simplified, but I'm not really used to thinking about these compositions with base MATLAB tools.
  1 commentaire
Alex Lefebvre
Alex Lefebvre le 12 Mai 2022
Those are all really good suggestions, thank you. The previous options you mentioned worked like a charm, but I'll give those recent ones a try as well. But they are all good options! It comes down to the type of spill and what options best illustrate how it migrates. Worth trying it all.

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by