zoukankan      html  css  js  c++  java
  • 两幅图像的融合与叠加

    假设两幅图像的大小完全一致,对应的像素数组分别为A与B,对应的任意单个像素值分别是a与b,混合后的像素值为c
    几种典型图像叠加操作:
    1、乘法叠加
    c=(ab)/255 public int modeOne(int v1,int v2){
    return (v1
    v2)/255;
    }
    2、加法叠加
    c=(a+b)/2 public int modeTwo(int v1,int v2){
    return (v1+v2)/2;
    }
    3、减法叠加
    c=|a-b| public int modeThree(int v1,int v2){
    return Math.abs(v1-v2);
    }
    4、取反叠加
    c=255-((255-a)(255-b)/255)——首先对各自的像素取反,然后使用乘法叠加后对得到的结果再次取反。
    public int modeFour(int v1,int v2){
    double p = (int)((255-v1)
    (255-v2));
    return (int)(255-p/255);
    }
    5、加法取反叠加
    c=255-(a+b) {(a+b)<255} | c=0 {(a+b)>=255}
    public int modeFive(int v1,int v2){
    int p = (int) (v1+v2);
    if(p>255){
    return 0;
    }else{
    return 255-p;
    }

                               }
    

    6、除法取反叠加
    c=(a/(255-b))255 public int modeSix(int v1,int v2){
    if(v2==255)
    return 0;
    double p = (v1/(255-v2))
    255;
    return clamp((int)p);
    }
    主要代码如下:
    package chapter5;
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;

    /**

    • Created by LENOVO on 18-1-30.
      */
      public class BlendFilter extends AbstractBufferedImageOp {
      public static final int MULTIPLY_PIXEL = 1;
      public static final int PLUS_PIXEL = 2;
      public static final int MINUS_PIXEL = 3;
      public static final int INVERSE_PIXEL = 4;
      public static final int INVERSE_PLUS_PIXEL = 5;
      public static final int DIVERSION_PIXEL = 6;

      private int mode;
      File file = new File("C:/Users/LENOVO/Desktop/rainbow.jpg");//读取的融合图片
      private BufferedImage secondImage ;
      public BlendFilter(){
      mode = MULTIPLY_PIXEL;//乘法叠加
      try {
      secondImage = ImageIO.read(file);

       } catch (IOException e) {
           e.printStackTrace();
       }
      

      }

      public void setMode(int mode) {
      this.mode = mode;
      }
      public void setSecondImage(BufferedImage secondImage) {
      this.secondImage = secondImage;
      }

      public BufferedImage filter(BufferedImage src,BufferedImage dest){
      checkImages(src);
      int width = src.getWidth();
      int height = src.getHeight();
      if(dest == null){
      dest = creatCompatibleDestImage(src,null);
      }
      int[] input1 = new int[widthheight];//原图
      int[] input2 = new int[secondImage.getWidth()
      secondImage.getHeight()];//第二张图
      int[] outPixels = new int[widthheight];
      getRGB(src,0,0,width,height,input1);
      getRGB(secondImage,0,0,secondImage.getWidth(),secondImage.getHeight(),input2);
      int index = 0;
      int ta1 = 0,tr1 = 0,tg1 = 0,tb1 = 0;
      for(int row=0;row<height;row++){
      for(int col=0;col<width;col++){
      index = row
      width +col;
      ta1 = (input1[index] >> 24) & 0xff;
      tr1 = (input1[index] >> 16) & 0xff;
      tg1 = (input1[index] >> 8) & 0xff;
      tb1 = (input1[index]) & 0xff;
      int rgb[] = getBlendData(tr1,tg1,tb1,input2,row,col);
      outPixels[index] = (ta1 << 24) | (clamp(rgb[0]) << 16) |(clamp(rgb[1]) << 8) |clamp(rgb[2]);
      }
      }
      setRGB(dest,0,0,width,height,outPixels);
      return dest;
      }

      //获取融合后的像素数据
      private int[] getBlendData(int tr1,int tg1,int tb1,int[] input,int row,int col){
      int width = secondImage.getWidth();
      int height = secondImage.getHeight();
      int index = row*width+col;
      if(col>=width || row >=height){//
      return new int[]{tr1,tg1,tb1};
      }
      int tr = (input[index] >> 16) & 0xff;
      int tg = (input[index] >>8) & 0xff;
      int tb = (input[index]) & 0xff;
      int[] rgb = new int[3];

       if(mode == MULTIPLY_PIXEL){
           rgb[0] = modeOne(tr1,tr);
           rgb[1] = modeOne(tg1,tg);
           rgb[2] = modeOne(tb1,tb);
       }else if(mode == PLUS_PIXEL){
           rgb[0] = modeTwo(tr1,tr);
           rgb[1] = modeTwo(tg1,tg);
           rgb[2] = modeTwo(tb1,tb);
       }else if(mode == MINUS_PIXEL){
           rgb[0] = modeThree(tr1,tr);
           rgb[1] = modeThree(tg1,tg);
           rgb[2] = modeThree(tb1,tb);
       }else if(mode == INVERSE_PIXEL){
           rgb[0] = modeFour(tr1,tr);
           rgb[1] = modeFour(tg1, tg);
           rgb[2] = modeFour(tb1, tb);
       }else if(mode == INVERSE_PLUS_PIXEL){
           rgb[0] = modeFive(tr1, tr);
           rgb[1] = modeFive(tg1, tg);
           rgb[2] = modeFive(tb1, tb);
       }else if(mode == DIVERSION_PIXEL){
           rgb[0] = modeSix(tr1, tr);
           rgb[1] = modeSix(tg1, tg);
           rgb[2] = modeSix(tb1, tb);
       }
       return rgb;
      

      }
      //乘法叠加
      public int modeOne(int v1,int v2){
      return (v1v2)/255;
      }
      //加法叠加
      public int modeTwo(int v1,int v2){
      return (v1+v2)/2;
      }
      //减法叠加
      public int modeThree(int v1,int v2){
      return Math.abs(v1-v2);
      }
      //取反叠加
      public int modeFour(int v1,int v2){
      double p = (int)((255-v1)
      (255-v2));
      return (int)(255-p/255);
      }
      //加法取反叠加
      public int modeFive(int v1,int v2){
      int p = (int) (v1+v2);
      if(p>255){
      return 0;
      }else{
      return 255-p;
      }
      }
      //除法取反叠加
      public int modeSix(int v1,int v2){
      if(v2 == 255)
      return 0;
      double p = (v1/(255-v2))*255;
      return clamp((int)p);
      }
      //判断两张图像大小是否相同
      public void checkImages(BufferedImage src){
      int width = src.getWidth();
      int height = src.getHeight();
      if(secondImage == null || secondImage.getWidth()>width || secondImage.getHeight()>height){
      throw new IllegalArgumentException("输入图片必须要大于融合的图片");
      }
      }
      }
      主要代码如下:

  • 相关阅读:
    linux--文件夹下批量改动IP
    Effective C++ 条款24
    ARMv8 Linux内核异常处理过程分析
    VS2010升级VS2013后,出现没有定义类型“PowerPacks.ShapeContainer”错误解决方法
    利用Nginx构建负载均衡server
    getline与get函数的区别
    Linking Containers Together
    获取不同机型外置SD卡路径
    查看linux系统状态
    Linux 开机自检的设置(tune2fs和fsck)
  • 原文地址:https://www.cnblogs.com/bigdream6/p/8385886.html
Copyright © 2011-2022 走看看