Reputation: 8886
I have transparent images [shown below] and I am trying to overlay it with aishack.in cvOverlayImage() function to overlay it on camera source
cvOverlayImage()
void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
{
int x,y,i;
for(x=0;x < overlay->width -10;x++)
{
if(x+location.x>=src->width) continue;
for(y=0;y < overlay->height -10;y++)
{
if(y+location.y>=src->height) continue;
CvScalar source = cvGet2D(src, y+location.y, x+location.x);
CvScalar over = cvGet2D(overlay, y, x);
CvScalar merged;
for(i=0;i<4;i++)
merged.val[i] = (S.val[i]*source.val[i]+D.val[i]*over.val[i]);
cvSet2D(src, y+location.y, x+location.x, merged);
}
}
}
calling cvOverlayImage()
cvOverlayImage(image_n, neg_img, cvPoint(0, 0), cvScalar(1.0,1.0,1.0,1.0), cvScalar(0.1,0.1,0.1,0.1));
Inputs to cvOverlayImage()
Output from cvOverlayImage()
As you can see I am not getting what I need.Please help me.
Upvotes: 0
Views: 5145
Reputation: 3971
I think what you want to achieve is not addition but multiplication:
int multiplicator = over.val[i] / 255 // 0 for black, 1 for white
merged.val[i] = source.val[i] * multiplicator;
This way the pixel value will be the original value for a white overlay pixel and black for a black overlay pixel.
Upvotes: 0
Reputation: 2487
One solution I used is to simply detect where the white is present and in those cases simply use the pixel from the source picture. Otherwise use the overlay picture's pixel. Worked well for me for a similar situation. Also, if the picture you load has the alpha channel and can be used as a mask, that's even better.
void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location,
CvScalar S, CvScalar D)
{
int x,y,i;
for(x=0;x < overlay->width;x++)
{
if(x+location.x>=src->width) continue;
for(y=0;y < overlay->height;y++)
{
if(y+location.y>=src->height) continue;
CvScalar source = cvGet2D(src, y+location.y, x+location.x);
CvScalar over = cvGet2D(overlay, y, x);
CvScalar merged;
if(over.val[0] == 255 && over.val[1] == 255 && over.val[2] == 255 && over.val[3] == 255)
{
// White pixel so don't overlay
for(i=0;i<4;i++)
merged.val[i] = (source.val[i]);
}
else
{
for(i=0;i<4;i++)
merged.val[i] = (over.val[i]);
}
cvSet2D(src, y+location.y, x+location.x, merged);
}
}
}
Upvotes: 2
Reputation: 3802
This isn't tested, but shouldn't S[i]+D[i] = 1 to preserve the total intensity ?
Upvotes: 1