两幅图像的融合与叠加

Posted 爽朗的sunmeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两幅图像的融合与叠加相关的知识,希望对你有一定的参考价值。

假设两幅图像的大小完全一致,对应的像素数组分别为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[width*height];//原图
    int[] input2 = new int[secondImage.getWidth()*secondImage.getHeight()];//第二张图
    int[] outPixels = new int[width*height];
    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

    //获取融合后的像素数据
    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("输入图片必须要大于融合的图片");
    }
    }
    }
    主要代码如下:

以上是关于两幅图像的融合与叠加的主要内容,如果未能解决你的问题,请参考以下文章

求加权平均的图像融合matlab 程序

matlab imadd关于2幅图像叠加问题

图像融合

opencv2.4.3中基于sift算法完成特征检测后,有没有图像融合的函数。直接把检测完的两幅图像拼接起来。

OpenCV实践- 叠加两幅图片

计算两幅图像的重叠区域