2014-09-22 30 views
0

我正在尝试开发一个小型且简单化的摄像头控制的游戏,其中用户通过跟踪摄像头的光源在x轴上移动图形(手电筒例如)OpenCV:导入的.png文件的透明区域现在是白色

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

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表示干净的背景,温度正在编辑的背景副本以及显示的最终背景。包括对象。
targetX and 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) 

之前我实际上更换像素。

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

在情况下,我可能会遇到问题成像我在说一下,这里是它的部分截图:Screenshot

,我怎么可能解决这一问题有何建议?

问候, 丹尼尔

回答

2

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

  1. 使用CV_LOAD_IMAGE_UNCHANGED(= -1)imread
  2. target分割为4个使用split的单通道图像。
  3. 使用merge合并前三个通道以形成BGR图像。
  4. 在绘制循环中,使用新形成的BGR图像作为源和未合并的第四通道(alpha)作为蒙版。
+0

非常感谢您的回复;我对OpenCV在阵列上的操作进行了更多的研究,并利用'mixChannels'函数发现了另一种解决方案: – danksch 2014-09-24 23:00:57

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

工作就像一个魅力!

相关问题