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

折月煮酒 提交于 2019-12-11 03:38:45

问题


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


回答1:


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.



回答2:


...as I was mentioning in my comment to asif's helpful answer:

Mat target = imread("target", CV_LOAD_IMAGE_UNCHANGED); // load image
Mat targetBGR(target.rows, target.cols, CV_8UC3);       // create BGR mat
Mat targetAlpha(target.rows, target.cols, CV_8UC1);     // create alpha mat
Mat out[] = {targetBGR, targetAlpha};                   // create array of matrices
int from_to[] = { 0,0, 1,1, 2,2, 3,3 };                 // create array of index pairs 
mixChannels( &target, 1, out, 2, from_to, 4 );          // finally split target into 3 
                                                        channel BGR plus 1 channel Alpha

...as described in this example. (minus the R-B-channel-swapping).

...later in the pixel-processing loop:

  if(targetAlpha.at<uchar>(j-targetY,i-targetX) > 0)
                    temp.at<Vec3b>(j,i) = targetBGR.at<Vec3b>(j-targetY,i-targetX); 

Working like a charm!



来源:https://stackoverflow.com/questions/25979946/opencv-transparent-area-of-imported-png-file-is-now-white

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!