--- In [hidden email], "luca.dantona" <luca.dantona@...> wrote:
> I need to add two images with alpha blending using a mask, but I found
> that cvAddWeighted doesn't support masks :(
> Has anyone already faced this problem?
Yes, I've faced this problem and I've got a solution that worked for me,
though your circumstances may be different. In my case I wanted to
overlay some decals (X's, check marks, etc.) over a second main image.
The images I wanted overlayed were simple graphics with a black
background. I wanted to alpha-blend the non-black part of the decals
with the main image. cvAddWeighted didn't work because it would add in
the black part of the decals, which I didn't want. If this is something
like your situation, continue reading.
To solve this I did the following. Let decal be the image I wanted to
overlay, decal_size its size, and img be the main image.
// Make a mask from all non-zero pixels in the decal.
mask = cvCreateImage(decal_size, IPL_DEPTH_8U, 1);
cvCvtColor(decal_size, mask, CV_RGB2GRAY);
cvThreshold(mask, mask, 0.0, 255.0, CV_THRESH_BINARY_INV);
// Here, the target image ROI needs to be set to the region you wish
to be blended. I
// I assume you've calculated this and put it in target_rect.
cvCopy(img, decal, mask);
// Now alpha blend. Note that for img, alpha * img + 1 - alpha *
decal gives back 1.0 * img.
cvAddWeighted(img, 1.0 - alpha, decal, alpha, 0.0, img);
The main weakness is the thresholding that is used to generate the mask.
If your decal has anti-aliased pixels, these can cause some odd effects.
I haven't found a completely general way of getting satisfactory
blending. If someone has a better way, I'd be eager to hear it.
[Non-text portions of this message have been removed]
> Yes, I've faced this problem and I've got a solution that worked for
> me... [CUT]
Thanks very much for your reply.
If I've understood your solution, it works only with rectangular
masks; however I don't get why cvAddWighted doesn't support masks. How
does it differ from cvAdd? I mean, the main structure of the two
functions is the same, the only difference is:
cvAdd -> dest = img1 + img2
cvAddWeighted -> dest = alpha*img1 + eta*img2
In this sense, what about the following code?
void AlphaBlending(IplImage *pImg1, float alpha, IplImage *pImg2,
float beta, IplImage *pDest, IplImage *pMask)
// pMask must have 1 channel