zoukankan      html  css  js  c++  java
  • 图像处理------基于像素的图像混合 分类: 视频图像处理 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. }  

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

  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/mao0504/p/4705507.html
Copyright © 2011-2022 走看看