简体   繁体   English

OpenCV-Android:导入.png以保留空白区域的透明度

[英]OpenCV-Android: Import .png preserving transparency of empty areas

I am currently trying to transform an input .png file to a OpenCV:Mat, preserving its transparency on empty areas. 我目前正在尝试将输入的.png文件转换为OpenCV:Mat,以保留其在空白区域的透明度。 Working on eclipse, using openCV4Android. 使用openCV4Android处理Eclipse。

I've tried this (using a Drawable): 我已经尝试过(使用Drawable):

Inputs: 输入:

  • icon.png is a resource file that is correctly loaded as RGBA (4 channels). icon.png是一个资源文件,已正确加载为RGBA(4个通道)。
  • Mat mcSprite (global field). Mat mcSprite(全局字段)。

     onCameraFrame method{ try { mcSprite = Utils.loadResource(this, R.drawable.icon); System.out.println(mcSprite.empty()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Imgproc.resize(mcSprite, mZoomWindow, mZoomWindow.size()); } 

The resulting image: 结果图像:

黑区

PS: If i import using: PS:如果我使用导入:

mcSprite = Utils.loadResource(this, R.drawable.icon , -1 ); mcSprite = Utils.loadResource(this,R.drawable.icon, -1 );

>0 Return a 3-channel color image.
=0 Return a grayscale image.
<0 Return the loaded image as is (with alpha channel).

no image is displayed. 没有图像显示。

Solved: 解决了:

    public void overlayImage(Mat background, Mat foreground,Mat output)//, Point location)
    {
      background.copyTo(output);
      Mat dst = new Mat();
      Imgproc.resize(foreground, dst, background.size());
      double alpha;
      // start at row 0/col 0
      for(int y = 0; y < background.rows() ; ++y)
      {
          for(int x = 0; x < background.cols() ; ++x)
          {
              double info[] = dst.get(y, x);
              alpha = info[3];
              // and now combine the background and foreground pixel, using the opacity,but only if opacity > 0. 
              if(alpha>0) //rude but this is what I need
              {
                  double infof[] = dst.get(y, x);
                  output.put(y, x, infof);
              }
          }
      } 

Final Result: 最后结果:

在此处输入图片说明

A lot faster solution, using masks: 使用蒙版的解决方案快得多:

    public Mat overlayImage(Mat background, Mat foreground)//, Point location)
    {
          Mat mask = new Mat();
          Imgproc.resize(mCurrentMask, mask, background.size());

          Mat source = new Mat();             
          Imgproc.resize(foreground, source, background.size()); 

          source.copyTo(background,mask);
          source.release();
          mask.release();
          return background;
    }

    public void createMask (Mat sprite){
        mCurrentMask = new Mat(sprite.height(),sprite.width(),24);
        double f[] = {1,1,1,0};
        double e[] = {0,0,0,0};
        for(int y = 0; y < (int)(sprite.rows()) ; ++y)
        {
              for(int x = 0; x < (int)(sprite.cols()) ; ++x)
              {     
                  double info[] = sprite.get(y, x);                 
                  if(info[3]>0) //rude but this is what I need
                  {
                      mCurrentMask.put(y, x, f);
                  } 
                  else mCurrentMask.put(y, x, e);
              }
        } 
    }   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM