Creation of a mask on RGB image

14 views (last 30 days)
Fed on 3 Sep 2020
Commented: Fed on 3 Sep 2020
I have applied a mask with irregular contours to a RGB image and then changed the saturation only in the area of the mask.
Imm = imread('lena .bmp');
title('Original Image');
message = sprintf('After you see the cross hairs, \nleft-click and hold to begin drawing.\nSimply lift the mouse button to finish');
hFH = drawfreehand();
% Create a binary image ("mask") from the ROI object.
binaryImage = hFH.createMask();
% Display the freehand mask
title('Binary mask of the region');
%Get HSV image from the RGB image
hsvImage = rgb2hsv(Imm);
hueImage = hsvImage(:, :, 1);
saturationImage = hsvImage(:, :, 2);
valueImage = hsvImage(:, :, 3);
% Increase saturation only within the mask area.
satFactor = 1.6;
saturationImage(binaryImage) = saturationImage(binaryImage) * satFactor;
% Recombine
hsvImage = cat(3, hueImage, saturationImage, valueImage);
% Convert back to RGB
rgbImage2 = hsv2rgb(hsvImage);
title('Altered RGB Image');
Here the result I got:
Do you know how to obtain a less sharper transition between the mask and the rest of the image in order to get a less artificial effect?
Thank you in advance for your help, I'm not very skilled on Image Processing yet.

Accepted Answer

J. Alex Lee
J. Alex Lee on 3 Sep 2020
Instead of multiplying pixels in the mask by a constant value, you can mulitply all pixels by an "image" of the saturation multiplier.
So rather than the scalar "1.6", which could as well have been a element-by-element multiplication, your original strategy could have been executed as
[M,N] = size(Imm)
satFactorMat = 1.6*ones(M,N);
satFactorMat(binaryImage) = 1.6;
saturationImage = saturationImage .* satFactorMat;
So now hopefully it is clear you don't really need the mask concept for the operation of altering the image itself, you just might use it to define the satFactorMat "topography", which looks like a mesa.Now you can just smooth it out using something like a smoothing function; you can use imgaussfilt
satFactorMat = imgaussfilt(satFactorMat,6);
You may need to convert everything to doubles first before doing the imgaussfilt and elementwise multiplication, and then convert back to uint8.
Also, note that multiplying is dangerous because you may end up with values outside valid range (>255). So it would be safe to exponentiate (but then you have to normalize your pixel values onto (0,1) first.
hsvImage = double(hsvImage)/255;
% ... everythign in between
% except instead of multiply by satFactorMat, you can do something like
satPowerMat = ones(M,N);
satPowerMat(binaryImage) = 0.3;
satPowerMat = imgaussfilt(satPowerMat,6);
saturationImage = saturationImage .* satPowerMat;
% Recombine
hsvImage = cat(3, hueImage, saturationImage, valueImage);
hsvImage = uint8(hsvImage*255);
Fed on 3 Sep 2020
Thanks again, I will also consider this aspect.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!