图像处理------基于像素的图像混合

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

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

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

方法一:

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

[java] view plaincopy

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

方法一的效果如下:

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

[java] view plaincopy

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

方法二的效果如下:


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

[java] view plaincopy

  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被用在计算等式中,代码如下:

[java] view plaincopy

  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. }  

方法四的效果如下:


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

[java] view plaincopy

  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. }  

方法五的效果如下:

滤镜源代码如下:

[java] view plaincopy

  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, 0, 0, width, height, input1);  
  47.         getRGB( secondImage, 0, 0, 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, 0, 0, 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. }  
时间: 2025-01-25 08:58:55

图像处理------基于像素的图像混合的相关文章

图像处理------基于像素的皮肤检测技术

基于像素的皮肤检测技术 介绍一种基于颜色空间的皮肤检测技术,可以检测亚洲人种与白人的皮肤,皮肤检测 人脸识别的基础,也是很多人像识别技术的基础操作,在实际应用中还是非常有用的.   基于像素的皮肤检测主要是寻找正确的颜色空间几何,图像处理中,常见的颜色空间 有如下几种 1.      RGB色彩空间 – R代表单色红,G代表单色绿,B代表单色蓝 2.      HSV色彩空间 – H 代表色彩, S代表饱和度,V代表强度值 3.      YCbCr色彩空间 – 是数字电视的色彩空间   RGB

《Java数字图像处理:编程技巧与应用实践》——2.3 基于BufferedImageOp的图像滤镜演示

2.3 基于BufferedImageOp的图像滤镜演示 通过前面两节的学习,我们已经大致了解BufferedImageOp接口及其实现类的功能.实践出真知,本节将演示BufferedImageOp接口中每个实现类的实际使用场景,达到知行合一.学以致用的目的,帮助大家解决项目中遇到的实际问题.为了让大家对应用效果有更加深刻的印象,下面会使用BufferedImageOp的实现类来实现如下几个滤镜特效功能. 黑白滤镜:将彩色图像自动转换为黑白两色图像. 灰度滤镜:将彩色图像自动转换为灰度图像. 模

Matlab与.NET基于类型安全的接口混合编程入门

原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标.  [原创分享]Matlab.NET混编调用Figure窗体 http://www.cnblogs.com/asxinyu/archive/2013/04/14/3020813.html   [原创]开源.NET下的XML数据库介绍及入门  http://www.cnblogs.com/asxinyu/archive/2013/03/25/2980086.

[学习日记]VB图像处理之像素的获取和输出

VB图像处理之像素的获取和输出 作者:佚名 来源:InterNet 加入时间:2005-1-28 要处理一个图像,首先要获得该图像的像素值,而VB本身提供的PICTURE控件虽然可以打开很多类型的图片,但是它提供的那个POINT方法读取像素实在是太慢.而使用GetPixel这个API的速度也快不到哪里去,因为PIONT方法本身就是对于GetPixel的一个包装. 在VB中要快速获取一幅在PICTURE中打开的图像比较快速的方法是使用DIB方法,当然还有DDB方法,不过使用DDB方法还需要考虑不同

图像处理-如何在单幅图像中消去阴影

问题描述 如何在单幅图像中消去阴影 在对图像处理时,由于图像中的阴影出现,导致算法无法进行,怎样可以将单幅图像里的阴影消去 解决方案 /*********************************************/ //阴影检测 /*********************************************/ CvPoint downleft,upright; int cnt; int dir[8][2]={-1,-1,-1,0,-1,1,0,1,0,-1,1,1,1

二进制数据-Mfc与图像处理关于读取二进制图像数据

问题描述 Mfc与图像处理关于读取二进制图像数据 有一些二进制图像数据.要求写读取裸图像信息的程序.该怎么写啊?用到opencv 解决方案 有几点不明,二进制数据?是内存中的数据吗?还是存在硬盘上的二进制文件? 如果是内存中的数据,使用Opencv的Mat类,一个个的赋值也可以,如果内存中的数据是连续的直接使用Mat的构造函数也可以.如果是文件中的二进制数据,先将文件读入内存中,再根据文件的结构,分解数据,将属于图像数据的部分赋值给Mat类 不同情况不同处理···

[文档]基于云计算及图像内容分析的医学图像融合方法

基于云计算及图像内容分析的医学图像融合方法 李文娟  那彦 提出了一种使用云计算实现基于图像内容分析的医学图像融合方法.为了设计云计算推理规则,对两幅输入图像---CT和MR I图像进行灰度直方图分析.并基于CT与MR I图像的灰度直方图与融合目的设计推理规则.将CT与MR I图像作为推理系统的两个输入,进而得到融合图像. 关键词--云计算 云模型 云推理 模糊推理 医学图像融合 [下载地址]http://bbs.chinacloud.cn/showtopic-11845.aspx

lda 图像处理-基于lda主题模型的图像分类器

问题描述 基于lda主题模型的图像分类器 老师给的任务是做一个针对图像的lda分类器,可是没有头绪,希望有大神指点一下啊 解决方案 LDA主题模型简介LDA主题模型简介LDA主题模型简介

【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解

        本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片点运算处理,包括图像灰度线性变换.灰度非线性变换.图像阈值化处理.图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 .同时文章比较详细基础,希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生.        [数字图像处理]一.MFC详解显示BMP格式图片        [数字图像处理]二.MFC单文档分割窗