Java OpenCV 将小图像叠加到具有透明度的大图像上

Java OpenCV Layer small image onto larger image with transparency

我正在尝试编写一个函数,将一个图像叠加在另一个图像上方的矩形上,但它不会对图像进行分层,它只是擦除我叠加的部分,透明度会贯穿整个图像图片。这是我的代码。

public static void overlayImage(String imagePath, String overlayPath, int x, int y, int width, int height) {
    Mat overlay = Imgcodecs.imread(overlayPath, Imgcodecs.IMREAD_UNCHANGED);
    Mat image = Imgcodecs.imread(imagePath, Imgcodecs.IMREAD_UNCHANGED);

    Rectangle rect = new Rectangle(x, y, width, height);
    Imgproc.resize(overlay, overlay, rect.size());
    Mat submat = image.submat(new Rect(rect.x, rect.y, overlay.cols(), overlay.rows()));
    overlay.copyTo(submat);
    Imgcodecs.imwrite(imagePath, image);
}

编辑:以下是一些示例图片: 之前:

之后:

发现这个功能完全符合我的需要。

 public static void overlayImage(Mat background,Mat foreground,Mat output, Point location){

  background.copyTo(output);

  for(int y = (int) Math.max(location.y , 0); y < background.rows(); ++y){

   int fY = (int) (y - location.y);

   if(fY >= foreground.rows())
          break;

      for(int x = (int) Math.max(location.x, 0); x < background.cols(); ++x){
          int fX = (int) (x - location.x);
          if(fX >= foreground.cols()){
           break;
          }

           double opacity;
           double[] finalPixelValue = new double[4];

           opacity = foreground.get(fY , fX)[3];

           finalPixelValue[0] = background.get(y, x)[0];
           finalPixelValue[1] = background.get(y, x)[1];
           finalPixelValue[2] = background.get(y, x)[2];
           finalPixelValue[3] = background.get(y, x)[3];

           for(int c = 0;  c < output.channels(); ++c){
               if(opacity > 0){
                   double foregroundPx =  foreground.get(fY, fX)[c];
                   double backgroundPx =  background.get(y, x)[c];

                   float fOpacity = (float) (opacity / 255);
                   finalPixelValue[c] = ((backgroundPx * ( 1.0 - fOpacity)) + (foregroundPx * fOpacity));
                   if(c==3){
                       finalPixelValue[c] = foreground.get(fY,fX)[3];
                   }
               }
           }
           output.put(y, x,finalPixelValue);
      }
  } 
}