How to convert specific GrayScale into coloured pixel

조회 수: 7 (최근 30일)
Daniel Fernandes
Daniel Fernandes 2021년 3월 2일
편집: DGM 2021년 6월 3일
Hello; I need your very helps about my project in University. I need to colorize metalographic images.
The original Image
I need to quantify the iron phases. I have converted the RGB image to GrayScale because I think is easier to define the regions.
This is the GrayScale one, and I need to convert the light phase into yellow, the almost black into green and the black (circles) into blue.
The aim of this is to quantify the percentual of each phase.
I have tried by RGB image using this code
%%
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Get the Perlite mask
yellowMask =redChannel >= 130 & greenChannel >= 130 & blueChannel >= 130;
% Get the Ferrite mask
GreenMask = redChannel > 60 & greenChannel > 60 & blueChannel > 60 & redChannel < 130 & greenChannel < 130 & blueChannel < 130;
% Get the Graphite mask
BlueMask = redChannel <= 60 & greenChannel <= 60 & blueChannel <= 60;
% Make Perlit mask Yellow
redChannel(yellowMask) = 255;
greenChannel(yellowMask) =255;
blueChannel(yellowMask) = 0;
% Make the white mask Green
redChannel(GreenMask) = 0;
greenChannel(GreenMask) = 255;
blueChannel(GreenMask) = 0;
% Make the Graphite mask Blue
redChannel(BlueMask) = 0;
greenChannel(BlueMask) = 0;
blueChannel(BlueMask) = 255;
% Recombine separate color channels into a single, true color RGB image.
rgbImage2 = cat(3, redChannel, greenChannel, blueChannel);
figure
imshow(rgbImage2)
The final result was not as good I've expected
Thanks very much in advance!
Daniel
  댓글 수: 7
Daniel Fernandes
Daniel Fernandes 2021년 6월 1일
Thank you DGM for your comment.
I already do the calcs in grayscale, I'm trying to use the colored image just for an aesthetic reason and to be more intuitive for people who will read my paperwork, and sincerely I'm almost giving up to use a colored image.
I was looking for some alternatives. A watershed image segmentation could be used for what I need? or just will complicate the process?
Daniel Fernandes
Daniel Fernandes 2021년 6월 1일
The problem is the pixels values that do not fit in the considerations. In the image for example [128 125 106], any threshold values do not satisfy this condition. I've set the thresholds with other conditions but I'm afraid that can impact the right phase counting. There is a way to set a boundary limit and calculate the area by that?

댓글을 달려면 로그인하십시오.

채택된 답변

DGM
DGM 2021년 6월 3일
편집: DGM 2021년 6월 3일
I forgot you were doing masking in RGB. You're right. The union of the masks won't span the image. You could find the set difference, but the color points are all very close to the diagonal. It might suffice to just use a brightness metric. It's the same difference really, but it's just less code.
Let's just recreate the masks as calculated
inpict = imread('phases.jpg');
mkperlite = inpict(:,:,1)>=130 & inpict(:,:,2)>=130 & inpict(:,:,3)>=130;
mkgraphite = inpict(:,:,1)<=60 & inpict(:,:,2)<=60 & inpict(:,:,3)<=60;
mkferrite = inpict(:,:,1)<130 & inpict(:,:,2)<130 & inpict(:,:,3)<130 ...
& inpict(:,:,1)>60 & inpict(:,:,2)>60 & inpict(:,:,3)>60;
% this information doesn't necessarily need color unless you want it
outpict = zeros(size(mkperlite));
outpict(mkgraphite) = 0.33;
outpict(mkferrite) = 0.67;
outpict(mkperlite) = 1;
Certainly, there are holes in the sum of masks.
You could use a single brightness metric to avoid having to deal with as many comparisons. Using the difference of masks ensures that the sum of masks spans the image.
ipict = mean(inpict,3); % this calculates I as in HSI
% you could also use V, L, Y, etc
bp = [60 130]; % choose some breakpoints (feel free to tweak)
mkperlite = ipict>=bp(2);
mkgraphite = ipict<=bp(1);
mkferrite = ~(mkperlite | mkgraphite); % this makes the masks span the image
% generating the image is the same
outpict2 = zeros(size(mkperlite));
outpict2(mkgraphite) = 0.33;
outpict2(mkferrite) = 0.67;
outpict2(mkperlite) = 1;
imshow2(outpict2,'invert')
% mask fractions can be calculated
N = numel(mkgraphite);
fracgraphite = sum(mkgraphite(:))/N
fracferrite = sum(mkferrite(:))/N
fracperlite = sum(mkperlite(:))/N
sum([fracgraphite fracferrite fracperlite]) % equals 1 like expected
There could still probably be some improvement made (e.g. the southeast corner) in dealing with the reflectivity/lighting issues. I'm not sure how to approach that.
It's worth pointing out what the geometry of the masks looks like in three dimensions. Consider the masks you're calculating in RGB:
Note that the union of the box selections don't span the domain. If the color points in the image lie in a band about the diagonal of the domain, many points will escape all box selections. You could choose to select two (e.g. the upper and lower ones) and then pick the third by difference as described. That would span the domain, but in this case, it would mean that one of the three selections is much more inclusive than the others.
On the other hand, we can look at what the surfaces of V, I, and L look like. These aren't really selections so much as the boundary between selected regions in the cube:
As you can see, I and L tend to subdivide the volume evenly -- that is a boundary at 50% I or L divides the RGB cube in half. Contrast this against a boundary at 50% V which does not.
I just picked I because it's simple and symmetrically splits the RGB cube where the original box selections touch.

추가 답변 (0개)

Community Treasure Hunt

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

Start Hunting!

Translated by