how to blend an image that is a non-rectangular mask with a background image?
Show older comments
Okay, I'm stumped.
I have a background image and I want to put a circular mask image on top of it, blended together 50-50 for everything within the circle. I want to stick with images and not use figures so that I can view the results with imagesc(image).
If pic1 is the full image that is cropped into the circle, and pC is a black circle on a white background with dimensions bCx, bCy, I use this to add in the image I want.
pzzc = imadd(pic1(bCx,bCy,:),pC);
I now have a circle with the original image in it and a white background. So far so good.
I now want to combine that image with the background image, such as this.
pzzz = imfuse(pzzz, pzzc,'blend');
The problem is that this doesn't work, as I can't get rid of the square bounding box around the circle image, since it's a mean of the 2 images, white and background.
immultiply doesn't work either. With this alternate approach:
pzz = immultiply(uint16(pzzz(bCx,bCy,:)), uint16(pzzc)); % IMAGE AND BACKGROUND
pzzz(bCx,bCy,:) = uint8(pzz);
pzz has the circle correct but is unblended, and the masked part of pzzz just comes out white.
If I have to I can live with the unblended image, but I don't understand why the masked part of the full image is white.
A full code example below:
clear all
pic1 = imread('visionteam.tif');
[x,y,z] = size(pic1);
pzzz = 20-uint8(zeros(x, y, z));
% ADD A DARK GRAY TO BACKGROUND IMAGE TO SEE IF CIRCLE LOSES BACKGROUND WHITE AREA
pC = imread('Circle1000x1000.tif'); % 1000 X 1000 BLACK CIRCLE WITH WHITE BACKGROUND
bbox = [86 52 70 70]; % X Y H W
pC = imresize(pC,[bbox(1,3), bbox(1,4)]); % RESIZE CIRCLE TO BB DIMENSIONS
bCx = bbox(1,1):bbox(1,1)+bbox(1,3)-1; % FIND X AND Y AREA OF BB
bCy = bbox(1,2):bbox(1,2)+bbox(1,3)-1;
mask = imadd(pic1(bCx,bCy,:),pC); % ADD Visionteam IMAGE INSIDE CIRCLE
mask = uint8(mask);
pzzz(bCx,bCy,:) = immultiply(uint16(pzzz(bCx,bCy,:)), uint16(mask))/255;
pzzz = uint8(pzzz);
imagesc(pzzz)
3 Comments
darova
on 4 Apr 2020
Too many text too many explanations. Please attach some picture and examples. Where is the data?
mark palmer
on 4 Apr 2020
darova
on 4 Apr 2020
What is this?

Accepted Answer
More Answers (1)
DGM
on 5 May 2023
A big part of the confusion here is from attempting to use imadd() and immultiply() as image blending tools when
- they are not practical as image blending tools
- the images are not scaled such that they could be blended
- image blending would not effect compositing in this manner anyway (at least if I'm understanding the intent)
We can work around 1 and 2 thusly:
pic1 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/281870/visionteam.jpg');
[x,y,z] = size(pic1);
% ADD A DARK GRAY TO BACKGROUND IMAGE TO SEE IF CIRCLE LOSES BACKGROUND WHITE AREA
pzzz = zeros(x, y, z)+0.5;
pC = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/281869/Circle1000x1000.jpg'); % 1000 X 1000 BLACK CIRCLE WITH WHITE BACKGROUND
bbox = [86 52 70 70]; % X Y H W
pC = imresize(pC,[bbox(1,3), bbox(1,4)]); % RESIZE CIRCLE TO BB DIMENSIONS
bCx = bbox(1,1):bbox(1,1)+bbox(1,3)-1; % FIND X AND Y AREA OF BB
bCy = bbox(1,2):bbox(1,2)+bbox(1,3)-1;
mask = imadd(pic1(bCx,bCy,:),pC); % ADD Visionteam IMAGE INSIDE CIRCLE
mask = uint8(mask);
% immultiply() is not a blending tool
% if you want to use immultiply as a blending tool
% both input images must be unit-scale floating-point
pzzz(bCx,bCy,:) = immultiply(pzzz(bCx,bCy,:),im2double(mask));
pzzz = im2uint8(pzzz);
imshow(pzzz,'border','tight')

Note the comments about the use of immultiply(). Despite its limitations, this does effect a 'multiply' blend, not alpha compositing. Instead of the circular region being the linear combination of foreground and background, it's the foreground region multiplied by 0.5.
Assuming that the goal is to instead have the circular region at some opacity over a colored field, this is how I'd do it. As usual, I'm just going to use MIMT tools because they exist so that I don't have to reinvent the wheel every time. They are succinct and flexible, handling mixed-class and mixed-depth operations without hassle.
% parameters
opacity = 0.5;
bgcolor = [0.43 0.38 0.25]; % any color tuple (1,2,3,or 4 elements)
% read the files
FG = imread('visionteam.jpg');
% generate a soft-edged mask directly
sz = imsize(FG,2); % get image geometry only
mask = drawcircle(sz,[90 75],50);
% compose output image
% output image class is inherited from the BG tuple (double)
outpict = replacepixels(FG,bgcolor,mask*opacity);
imshow2(outpict)
% draw smooth circle
function circ = drawcircle(sz,c,r)
xx = 1:sz(2);
yy = (1:sz(1)).';
circ = sqrt((xx-c(2)).^2 + (yy-c(1)).^2);
circ = min(max(-(circ-r)/2,0),1);
end

Or if my interpretation of intent is incorrect, I can always replicate @Image Analyst's last example for sake of completeness.
% read the files
FG = imread('pears.png');
BG = imread('visionteam.jpg');
mask = imread('Circle1000x1000.jpg');
% resize the off-size example images
sz = imsize(BG,2);
FG = imresize(FG,sz);
mask = imresize(mask,sz);
% compose output image
% output image class is inherited from BG image (uint8)
outpict = replacepixels(FG,BG,iminv(mask)*0.5);
imshow2(outpict)

Categories
Find more on Image Arithmetic in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!