Search code examples
imageopencvpngtransparencyalpha

OpenCV : Transparent area of imported .png file is now white


I'm trying to develop a small and simplistic webcam-controlled game, where the user moves a figure on the x-axis by tracking a lighting source with the webcam (flashlight eg.)

So far my code generates a target object every couple of seconds at a random location in the picture. That object is stored as a Mat via

Mat target = imread("target.png");

In order to paint the object onto the background image, I'm using

bgClear.copyTo(temp);    
for(int i = targetX; i < target.cols + targetX; i++){
            for(int j = targetY; j < target.rows + targetY; j++){                               
                    temp.at<Vec3b>(j,i) = target.at<Vec3b>(j-targetY,i-targetX);                
            }
          } 
temp.copyTo(bg);

where bgClear represents the clean background, temp the background copy that is being edited and bg the final background thats being shown. including the object.
targetX and targetY are the starting coordinates of the object (whereas targetX is randomly generated beforehand so that the object spawns at a random location in the upper half of the image), relative to the background. (so I'm not iterating through the whole background, only the range of the object).

It works so far, but I have a problem: The transparent area of the imported image is now white, and I dont seem to be able to fix it by checking the pixel values with something like

       if(target.at<Vec3b>(Point(j-targetY,i-targetX))[0] != 255 &&
       target.at<Vec3b>(Point(j-targetY,i-targetX))[1] != 255 &&
       target.at<Vec3b>(Point(j-targetY,i-targetX))[2] != 255)

before I am actually replacing the pixel.

I've also tried loading the .png file by adding the -1 flag (alpha channel), but then the image just seems ghosty and can barely be seen.

In case I might you have problems imaging what I'm talking about, here's a partial screenshot of it: Screenshot

Any advice on how I might fix this ?

Regards, Daniel


Solution

  • You need to handle transparency manually. General idea is, while copying to temp only copy pixels that are opaque i.e. alpha value is high.

    1. use CV_LOAD_IMAGE_UNCHANGED (= -1) in imread.
    2. split target to four single channel image using split.
    3. merge first three channels to form a BGR image using merge.
    4. in the paint loop, use newly formed BGR image as source and the unmerged fourth channel (alpha) as mask.