Why do I write as Ib(1:478,31:565)(~BW) = 255

Ib(1:478,31:565)(~BW) = 255
Ib is a gray image. I want to set a fixed black region as blue, but this code is wrong.
Do we have simple method to finish it?

1 Comment

I don't want to assign Ib(1:478,31:565) to new variable to meet request.

Sign in to comment.

 Accepted Answer

DGM
DGM on 26 Feb 2025
Edited: DGM on 26 Feb 2025
There are various ways, including expanding the mask, or using more purpose-built tools, but if you're trying to apply an undersize mask to a rectangular sub-image, maybe it'd be best to just show it like this, since it demonstrates a number of concepts that can be rearranged and applied as is truly needed.
% this is a single-channel (gray) image in uint8
inpict = imread('cameraman.tif'); % 256x256x1
imshow(inpict)
% say we have some smaller logical mask
% ignore the ==0 here. that's just a consequence of the image i'm repurposing
mask = imread('150mk.png') == 0; % 150x150x1
imshow(mask)
% if we want the output to contain color,
% let's start with expanding the image as needed
if size(inpict,3) == 1
outpict = repmat(inpict,[1 1 3]);
else
outpict = inpict;
end
% we want to apply the mask to some region within the image
% we might choose to just extract that region
offset = [10 10]; % [y x]
sz = size(mask,1:2);
roi = outpict(offset(1):offset(1)+sz(1)-1, ...
offset(1):offset(2)+sz(2)-1,:);
% we can apply the mask to that sub-image
fgcolor = [0 0 1]; % unit-scale float
for c = 1:3
thischannel = roi(:,:,c);
thischannel(mask) = im2uint8(fgcolor(c));
roi(:,:,c) = thischannel;
end
% we can put the roi back into the image if we want
outpict(offset(1):offset(1)+sz(1)-1, ...
offset(1):offset(2)+sz(2)-1,:) = roi;
% show the result
imshow(outpict)
Not sure if that covers all the bases, but maybe it's a start. I know you don't want to assign the subimage to a new variable, but you're going to have to do something, since the image an mask have mismatched geometry, and the input and output have mismatched depth.
EDIT: Like I said, there are other ways. This example uses different approaches to addressing both of the above issues.
% this is a single-channel (gray) image in uint8
inpict = imread('cameraman.tif'); % 256x256x1
% say we have some smaller logical mask
mask = imread('150mk.png')==0; % 150x150x1
% instead of working on the sub-image to fix the geometry mismatch
% just expand the mask to fit the image
offset = [10 10]; % [y x]
sz = size(mask,1:2);
fullmask = false(size(inpict,1:2));
fullmask(offset(1):offset(1)+sz(1)-1, ...
offset(1):offset(2)+sz(2)-1) = mask;
% use simple multiplicative composition to construct the output
% in modern versions, this lets us avoid the problem of mismatched depth
fgcolor = [0 0 1]; % unit-scale float
outpict = im2double(inpict).*(1-fullmask) ... % do the composition
+ permute(fgcolor,[1 3 2]).*fullmask;
outpict = im2uint8(outpict); % assuming the output should be uint8
% show the result
imshow(outpict)
Alternatively, so long as the image/mask geometry matches, the final composition could be done using tools made for the purpose.
% IPT imoverlay() can do solid-color fills, given a logical mask
fgcolor = [0 0 1]; % unit-scale float
outpict = imoverlay(inpict,fullmask,fgcolor);

6 Comments

@DGM, thank you!
I just want to pickup golden pattern. change the red to blue in below picture.
but Ib(1:478,31:565)(~BW) = 255 , it can't work in matlab.
as your final reminder, I can use function: imoverlay. It's very easy and simple. but the effect is changed all color but my pattern I need.
I0=imread("IMG_0307.JPG");
BW = imbinarize(im2gray(I0),"adaptive");
BW = uint8(BW);
R=I0(:,:,1);G=I0(:,:,2);B=I0(:,:,3);
Ir = R.*BW;Ig = G.*BW;Ib = B.*BW;
% Ib(1:478,31:565)(~BW) = 255;
Ie = cat(3,Ir,Ig,Ib);
imshowpair(I0,Ie,"montage");
I1=imoverlay(I0,~BW,[0 0 1]);
imshow(I1);
Yeah. You don't need to do a color fill, but a color adjustment. The composition step will still be part of the process, but imoverlay() isn't the tool for the job.
MATLAB doesn't have purpose-built tools for doing hue adjustment, but there are indirect ways to do it, and there are purpose-built tools on the File Exchange.
Getting clean edges on the composition may be a challenge
% the image
I0 = imread("IMG_0307.JPG");
% a mask of the same geometry
% this can be binarized or soft edged
% and it can be based on graylevel intensity
% or it can be based on color properties (e.g. hue and saturation)
BW = imbinarize(im2gray(I0),"adaptive");
% adjust the HSV hue on a copy
hadjust = -0.30; % adjust me
hsvcopy = rgb2hsv(I0);
hsvcopy(:,:,1) = mod(hsvcopy(:,:,1)+hadjust,1);
adjusted = hsv2rgb(hsvcopy);
% compose the two
mask = im2double(BW); % make sure it's unit-scale
outpict = im2double(I0).*mask + adjusted.*(1-mask);
outpict = im2uint8(outpict);
% show the result
imshow(outpict)
The same adjustment and composition can be done more succinctly with purpose-built tools.
% ... same as before ...
% adjust the color on a copy
% this can adjust any component of color
% within any selected color model, not just HSV
adjusted = imtweak(I0,'hsv',[-0.30 1 1]); % MIMT
% compose the two
outpict = replacepixels(I0,adjusted,BW); % MIMT
% show the result
imshow(outpict)
These examples cover doing masked color adjustment using various tools and techniques:
pink strawberries (answer as comment; HSV segmentation & adjustment; no MIMT)
naive channel swap, hard masked filling/tweaking, lin masked colorization (color chips)
triangle of colored dots; links to other answers
This example is non-masked color adjustment by various methods, showing the influence each approach has on the perceived change of independent color properties. This same lesson applies to masked adjustments.
popsquares example (hue rotate, hue replace, solid fill; mostly MIMT)
Thank you DGM!
Too much information, I need to dig it longtime.
After learn the material you provide, I think I will deeply understand it.
HI @DGM,
IN above code, the key code: hsvcopy(:,:,1) = mod(hsvcopy(:,:,1)+hadjust,1).
How to understand it?
Hues are values on a circular continuum -- angles in a polar space. A hue of 0 degrees is the same as 360 degrees.
The output of rgb2hsv() is unit-scale HSV -- specifically meaning that hue data (angles from 0-360 degrees) are normalized to a [0 1] scale.
If we offset hues by addition, we may end up with angles outside of our expected interval (either [0 360] or [0 1]), so we use mod() to wrap these angles back to the expected interval. Since in this case we're using unit-scale, we do mod(H,1) instead of mod(H,360).
Consider the three examples to see what the effect is.
% the amount to offset H
% e.g. 0.25 is a 90 degree rotation
os = -0.3;
% the image
inpict = imread('peppers.png');
% simply apply the offset by addition
% we potentially create values outside the unit interval
% this causes problems on conversion back to RGB
hsvcopy = rgb2hsv(inpict);
hsvcopy(:,:,1) = hsvcopy(:,:,1) + os;
op1 = hsv2rgb(hsvcopy);
% do the same thing, but try to constrain H
% by clamping values to the unit interval
% this creates abrupt gaps in the color distribution
% as colors get compressed near zero (red in HSV)
hsvcopy = rgb2hsv(inpict);
hsvcopy(:,:,1) = min(max(hsvcopy(:,:,1) + os,0),1);
op2 = hsv2rgb(hsvcopy);
% apply the offset by modular addition
% values simply circulate like angles should
hsvcopy = rgb2hsv(inpict);
hsvcopy(:,:,1) = mod(hsvcopy(:,:,1) + os,1);
op3 = hsv2rgb(hsvcopy);
% compare the results
outpict = [op1; op2; op3];
imshow(outpict)
Understood completely. a circle
so I can try to change every color by myself. thank you DGM。

Sign in to comment.

More Answers (1)

temp = Ib(1:478,31:565,:);
temp(~repmat(BW,1,1,ndims(temp))) = 255;
Ib(1:478,31:565,:) = temp;

3 Comments

temp matrix size is mismatch with BW.
Ib = randi([0 255], 500, 600, 3, 'uint8');
temp = Ib(1:478,31:565,:);
BW = rand(size(temp,1), size(temp,2)) > 0.8;
temp(~repmat(BW,1,1,size(temp,3))) = 255;
Ib(1:478,31:565,:) = temp;
Thank you Walter!
My BW size is the size of full picture. so I should crop it to setting,
temp = Ib(1:478,31:565);
BW = Ib(1:478,31:565);
temp(~BW) = 255;
Ib(1:478,31:565,:) = temp;
I think that my definition of location is not good idear.

Sign in to comment.

Asked:

xie
on 26 Feb 2025

Commented:

xie
on 28 Feb 2025

Community Treasure Hunt

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

Start Hunting!