OpenCV:导入的.png文件的透明区域现在为白色

时间:2014-09-22 17:36:53

标签: image opencv png transparency alpha

我正在尝试开发一个小而简单的网络摄像头控制的游戏,用户通过使用网络摄像头(例如手电筒)跟踪光源来在x轴上移动图形。

到目前为止,我的代码在图片中的随机位置每两秒生成一个目标对象。 该对象通过

存储为Mat
Mat target = imread("target.png");

为了将对象绘制到背景图像上,我正在使用

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);

其中 bgClear 表示干净的背景, temp 表示正在编辑的背景副本, bg 表示正在显示的最终背景。包括对象。
targetX targetY 是对象的起始坐标(而targetX是预先随机生成的,因此对象会在图像上半部分的随机位置产生),相对到后台。 (所以我不是遍历整个背景,只是对象的范围)。

它到目前为止工作,但我有一个问题: 导入图像的透明区域现在是 白色 ,我似乎无法通过检查

之类的像素值来修复它
       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)

在我实际更换像素之前。

我也尝试通过添加 -1标志(alpha通道)来加载.png文件,但是图像看起来很怪异,几乎看不到。

如果我对你正在谈论的内容有疑问,可以点击它的部分截图:Screenshot

关于如何解决此问题的任何建议?

此致 丹尼尔

2 个答案:

答案 0 :(得分:2)

您需要手动处理透明度。一般的想法是,虽然复制到temp只复制不透明的像素,即alpha值很高。

  1. imread中使用CV_LOAD_IMAGE_UNCHANGED(= -1)。
  2. 使用splittarget拆分为四个单通道图像。
  3. 使用merge合并前三个通道以形成BGR图像。
  4. 在绘画循环中,使用新形成的BGR图像作为源,使用未合并的第四通道(alpha)作为遮罩。

答案 1 :(得分:0)

......正如我在评论中提到asif的有用答案:

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

...如本example所述。 (减去R-B频道交换)。

...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); 

像魅力一样工作!