• 图像处理------基于像素的图像混合 分类: 视频图像处理 2015-07-24 14:57 43人阅读 评论(0) 收藏


    介绍几种常见的将两张图像混合在一起形成一张新的图像的算法,

    首先看一下下面算法演示中要使用的两张图像:



    为了得到更好的混合效果,我选择了两张一样大小的图片。

    方法一:

    通过简单对于像素点的像素相乘得到输出像素值,代码演示如下:

    1. private int modeOne(int v1, int v2) {  
    2. <span style="white-space:pre">  </span>return (v1 * v2) / 255;  
    3. }  

    方法一的效果如下:


    方法二:

    通过计算两个像素之和再减去方法一的输出值,代码如下:

    1. private int modeTwo(int v1, int v2) {  
    2.     return v1 + v2 - v1 * v2 / 255;  
    3. }  

    方法二的效果如下:


    方法三:

    通过像素值128这个特殊的中值来求取输出值,代码如下:

    1. private int modeThree(int v1, int v2) {  
    2.     return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);  
    3. }  

    方法三的效果如下:


    方法四:

    与方法三不同,中值127.5被用在计算等式中,代码如下:

    1. private int modeFour(double v1, double v2) {  
    2.   if ( v1 > 127.5 ){  
    3.       return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
    4.    }else{  
    5.       return (int)(v2 - v2 * ((127.5 -  v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
    6.    }  
    7. }  

    方法四的效果如下:


    方法五:

    中值计算考虑,是方法一的升级版本,使得混合更加精细,代码如下:

    1. private int modeFive(double v1, double v2) {  
    2.   if ( v1 > 127.5 ){  
    3.       return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5));  
    4.    }else{  
    5.       return (int)(v2 * v1 / 127.5);  
    6.    }  
    7. }  

    方法五的效果如下:


    滤镜源代码如下:

    1. package com.gloomyfish.filter.study;  
    2.   
    3. import java.awt.image.BufferedImage;  
    4. /*** 
    5.  * i get these blend method from html5 demo then i decide to  
    6.  * translate these java script methods into java 
    7.  * 偶尔我也会写中文注释, 常见的图像混合方法 
    8.  * @author fish 
    9.  * @date 2012-11-28 
    10.  */  
    11. public class ImageBlendFilter extends AbstractBufferedImageOp {  
    12.     /** Define the blend mode */  
    13.     public final static int MULTIPLY_PIXEL = 1;  
    14.     public final static int SCREEN_PIXEL = 2;  
    15.     public final static int OVERLAY_PIXEL = 3;  
    16.     public final static int SOFTLIGHT_PIXEL = 4;  
    17.     public final static int HARDLIGHT_PIXEL = 5;  
    18.       
    19.     private int mode;  
    20.     private BufferedImage secondImage;  
    21.     public ImageBlendFilter() {  
    22.         mode = 1;  
    23.     }  
    24.   
    25.     public void setBlendMode(int mode) {  
    26.         this.mode = mode;  
    27.     }  
    28.       
    29.     public void setSecondImage(BufferedImage image) {  
    30.         this.secondImage = image;  
    31.     }  
    32.       
    33.   
    34.     @Override  
    35.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
    36.         checkImages(src);  
    37.         int width = src.getWidth();  
    38.         int height = src.getHeight();  
    39.   
    40.         if ( dest == null )  
    41.             dest = createCompatibleDestImage( src, null );  
    42.   
    43.         int[] input1 = new int[width*height];  
    44.         int[] input2 = new int[secondImage.getWidth() * secondImage.getHeight()];  
    45.         int[] outPixels = new int[width*height];  
    46.         getRGB( src, 00, width, height, input1);  
    47.         getRGB( secondImage, 00, secondImage.getWidth(), secondImage.getHeight(), input2);  
    48.         int index = 0;  
    49.         int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;  
    50.         for(int row=0; row<height; row++) {  
    51.             for(int col=0; col<width; col++) {  
    52.                 index = row * width + col;  
    53.                 ta1 = (input1[index] >> 24) & 0xff;  
    54.                 tr1 = (input1[index] >> 16) & 0xff;  
    55.                 tg1 = (input1[index] >> 8) & 0xff;  
    56.                 tb1 = input1[index] & 0xff;  
    57.                 int[] rgb = getBlendData(tr1, tg1, tb1, input2, row, col);  
    58.                 outPixels[index] = (ta1 << 24) | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];  
    59.                   
    60.             }  
    61.         }  
    62.         setRGB( dest, 00, width, height, outPixels );  
    63.         return dest;  
    64.     }  
    65.   
    66.     private int[] getBlendData(int tr1, int tg1, int tb1, int[] input,int row, int col) {  
    67.         int width = secondImage.getWidth();  
    68.         int height = secondImage.getHeight();  
    69.         if(col >= width || row >= height) {  
    70.             return new int[]{tr1, tg1, tb1};  
    71.         }  
    72.         int index = row * width + col;  
    73.         // int ta = (input[index] >> 24) & 0xff;  
    74.         int tr = (input[index] >> 16) & 0xff;  
    75.         int tg = (input[index] >> 8) & 0xff;  
    76.         int tb = input[index] & 0xff;  
    77.         int[] rgb = new int[3];  
    78.         if(mode == 1) {  
    79.             rgb[0] = modeOne(tr1, tr);  
    80.             rgb[1] = modeOne(tg1, tg);  
    81.             rgb[2] = modeOne(tb1, tb);  
    82.         }  
    83.         else if(mode == 2) {  
    84.             rgb[0] = modeTwo(tr1, tr);  
    85.             rgb[1] = modeTwo(tg1, tg);  
    86.             rgb[2] = modeTwo(tb1, tb);            
    87.         }  
    88.         else if(mode == 3) {  
    89.             rgb[0] = modeThree(tr1, tr);  
    90.             rgb[1] = modeThree(tg1, tg);  
    91.             rgb[2] = modeThree(tb1, tb);              
    92.         }  
    93.         else if(mode == 4) {  
    94.             rgb[0] = modeFour(tr1, tr);  
    95.             rgb[1] = modeFour(tg1, tg);  
    96.             rgb[2] = modeFour(tb1, tb);           
    97.         }  
    98.         else if(mode == 5) {  
    99.             rgb[0] = modeFive(tr1, tr);  
    100.             rgb[1] = modeFive(tg1, tg);  
    101.             rgb[2] = modeFive(tb1, tb);           
    102.         }  
    103.         return rgb;  
    104.     }  
    105.       
    106.     private int modeOne(int v1, int v2) {  
    107.         return (v1 * v2) / 255;  
    108.     }  
    109.       
    110.     private int modeTwo(int v1, int v2) {  
    111.         return v1 + v2 - v1 * v2 / 255;  
    112.     }  
    113.       
    114.     private int modeThree(int v1, int v2) {  
    115.         return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);  
    116.     }  
    117.       
    118.     private int modeFour(double v1, double v2) {  
    119.       if ( v1 > 127.5 ){  
    120.           return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
    121.        }else{  
    122.           return (int)(v2 - v2 * ((127.5 -  v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255.0));  
    123.        }  
    124.     }  
    125.       
    126.     private int modeFive(double v1, double v2) {  
    127.       if ( v1 > 127.5 ){  
    128.           return (int)(v2 + (255.0 - v2) * ((v1 - 127.5) / 127.5));  
    129.        }else{  
    130.           return (int)(v2 * v1 / 127.5);  
    131.        }  
    132.     }  
    133.   
    134.     private void checkImages(BufferedImage src) {  
    135.         int width = src.getWidth();  
    136.         int height = src.getHeight();  
    137.         if(secondImage == null || secondImage.getWidth() > width || secondImage.getHeight() > height) {  
    138.             throw new IllegalArgumentException("the width, height of the input image must be great than blend image");  
    139.         }  
    140.     }  
    141.   
    142. }  

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    【MySQL笔记】数据定义语言DDL
    【MySQL笔记】SQL语言四大类语言
    《ggplot2:数据分析与图形艺术》,读书笔记
    【数据处理】为什么数据要取对数
    【R实践】时间序列分析之ARIMA模型预测___R篇
    【R笔记】使用R语言进行异常检测
    【R笔记】日期处理
    朴素贝叶斯分类器的应用
    数据分析的方法与技术
    爬虫 测试webmagic (一)
  • 原文地址:https://www.cnblogs.com/mao0504/p/4705507.html
Copyright © 2020-2023  润新知