图像处理 背景比较

2018-06-07 14:56:17 qq_37764129 阅读数 16344

本Project要对一下图像进行处理,去掉指纹周围的雾。这里采用matlab软件来对图像进行批量处理。

源代码:https://download.csdn.net/download/qq_37764129/10384282

待处理图像如图1所示:

    在本项目中,采用了Sobel边缘检测算子进行指纹的提取,通过膨胀腐蚀去除了部分面积较小的雾点,以第20号图即这里的待处理图像(4)为例得到图a即下面的图3-1。

    用find函数提取经前几步处理后二值图像中的所有黑色区域即背景的线性索引向量,在原图中把相应位置的灰度值置为255饱和状态,得到图b即下图3-2。

    这样指纹提取工作基本完成,但此时的提取结果还会有部分污点没去除干净,这样通过一个imopen函数对a图即图3-1再进行一遍开运算,去除剩下的雾污染和零碎的指纹点,结果如图3-3

    将a图即图3-1与图3-3开操作的结果做差,可以得到a图即图3-1中多余的雾污染及无关点的二值图,如下图3-4所示:

    再用find函数提取这部分的索引向量在b图即图3-2中将其置为255就可以得到最后的比较理想的指纹了,如下图3-5。

源代码见链接:

https://download.csdn.net/download/qq_37764129/10384282

2017-03-02 17:34:16 sinat_37729342 阅读数 2973

图像处理——目标检测与前背景分离
前提

    运动目标的检测是计算机图像处理与图像理解领域里一个重要课题,在机器人导航、智能监控、医学图像分析、视频图像编码及传输等领域有着广泛的应用。
                                      这里写图片描述

目标检测方法分类

  第一,已知目标的先验知识。在这种情况下检测目标有两类方法,第一类方法是用目标的先验知识训练一堆弱分类器,然后这些弱分类器一起投票来检测目标,如boosting, random forest 都是这个思路,大家熟知的adaboost人脸检测也是如此。第二类方法是根据先验知识找到目标和非目标的最佳划分线,如SVM.这两类方法各成一家,各有所长,都有着不错的表现。

  第二,未知目标的先验知识。此时不知道要检测的目标是什么,于是什么是目标就有了不同的定义。一种方法是检测场景中的显著目标,如通过一些特征表达出场景中每个像素的显著性概率,然后找到显著目标。另一种方法就是检测场景当中的运动目标了。

经典目标检测方法

1、背景差分法
  在检测运动目标时,如果背景是静止的,利用当前图像与预存的背景图像作差分,再利用阈值来检测运动区域的一种动态目标识别技术。
  背景差分算法适用于背景已知的情况,但难点是如何自动获得长久的静态背景模型。
  matlab中单纯的背景差分直接是函数imabsdiff(X,Y)就可以。
2、帧差分法
  利用视频序列中连续的两帧或几帧图像的差来进行目标检测和提取。在运动的检测过程中,该方法利用时间信息,通过比较图像中若干连续帧获得对应像素点的灰度差值,如果均大于一定的阈值T2,则可以判断该位置存在运动的目标。
  较适合于动态变化场景。
3、光流场法
  利用相邻两帧中对应像素的灰度保持原理来评估二维图像的变化。能够较好的从背景中检测到相关前景目标,甚至是运动屋里中的部分运动目标,适用于摄像机运动过程中相对运动目标的检测。
  开口问题、光流场约束方程的解的不唯一性问题。不能正确的表示实际的运动场。
        例子如下:
       1.首先在一帧图像内随机均匀选取k个点,并滤除那些邻域纹理太光滑的点,因为这些点不利于计算光流。
这里写图片描述
       2.计算这些点与上一帧图像的光流矢量,如上右图,此时已经可以看出背景运动的大概方向了。
       这里写图片描述
       3.接下来的这一步方法因人而异了。
       2007年cvpr的一篇文章Detection and segmentation of moving objects in highly dynamic scenes的方法是把这些光流点的(x,y,dx,dy,Y,U,V)7个特征通过meanshift聚类来聚合到一起,最后形成运动目标轮廓。

新目标检测方法

       其实写到这里想了想到底能不能叫目标检测,博主认为图像的前背景分离也是目标检测的一种(博主才疏学浅,求赐教)

1、像素点操作
  对每个像素点进行操作,判别为前景或者背景两类。如下面的图片所示:
  这里写图片描述
2、低秩矩阵应用
  背景建模是从拍摄的视频中分离出背景和前景。下面的例子就是将背景与前景分离开。使用的方法是RPCA的方法。
  其网址以及效果如下:
  http://perception.csl.illinois.edu/matrix-rank/introduction.html
  这里写图片描述
3、深度学习
  FCN + denseCRF 精确分割+语义标签。图像中的前景目标检测分割做的很好,下面还能做出语义检测,判断出图中的东西属于什么。This demo is based on our ICCV 2015 paper :Conditional Random Fields as Recurrent Neural Networks,
  测试网址以及测试图像如下:
  http://www.robots.ox.ac.uk/~szheng/crfasrnndemo
  这里写图片描述






2016-02-26 17:48:13 baimafujinji 阅读数 69723

什么是数字图像处理?历史、以及它所研究的内容。

 

说起图像处理,你会想到什么?你是否真的了解这个领域所研究的内容。纵向来说,数字图像处理研究的历史相当悠久;横向来说,数字图像处理研究的话题相当广泛。

数字图像处理的历史可以追溯到近百年以前,大约在1920年的时候,图像首次通过海底电缆从英国伦敦传送到美国纽约。图像处理的首次应用是为了改善伦敦和纽约之间海底电缆发送的图片质量,那时就应用了图像编码,被编码后的图像通过海底电缆传送至目的地,再通过特殊设备进行输出。这是一次历史性的进步,传送一幅图片的时间从原来的一个多星期减少到了3小时。

1950年,美国的麻省理工学院制造出了第一台配有图形显示器的电子计算机——旋风I号(Whirlwind I)。旋风I号的显示器使用一个类似于示波器的阴极射线管(Cathode Ray Tube,CRT)来显示一些简单的图形。1958年美国Calcomp公司研制出了滚筒式绘图仪,GerBer公司把数控机床发展成为平板式绘图仪。在这一时期,电子计算机都主要应用于科学计算,而为这些计算机配置的图形设备也仅仅是作为一种简单的输出设备。

随着计算机技术的进步,数字图像处理技术也得到了很大的发展。1962年,当时还在麻省理工学院攻读博士学位的伊凡·苏泽兰(Ivan Sutherland)成功开发了具有划时代意义的“画板”(Sketchpad)程式。而这正是有史以来第一个交互式绘图系统,同时这也是交互式电脑绘图的开端。从此计算机和图形图像被更加紧密地联系到了一起。鉴于伊凡·苏泽兰为计算机图形学创立所做出的杰出贡献,他于1988年被授予计算机领域最高奖——图灵奖。

1964年,美国加利福尼亚的喷气推进实验室用计算机对“旅行者七号”太空船发回的大批月球照片进行处理,以校正航天器上摄影机中各种类型的图像畸变,收到了明显的效果。在后来的宇航空间技术中,数字图像处理技术都发挥了巨大的作用。

到了20世纪60年代末期,数字图像处理已经形成了比较完善的学科体系,这套理论在20世纪70年代发展得十分迅速,并开始应用于医学影像和天文学等领域。1972年,美国物理学家阿伦·马克利奥德·柯麦科(Allan MacLeodCormack)和英国电机工程师戈弗雷·纽博尔德·豪恩斯弗尔德(Godfrey Newbold Housfield)发明了轴向断层术,并将其用于头颅诊断。世界第一台X射线计算机轴向断层摄影装置由EMI公司研制成功,这也就是人们通常所说的CT(Computer Tomograph)。CT可通过一些算法用感知到的数据去重建通过物体的“切片”图像。这些图像组成了物体内部的再现图像,也就是根据人的头部截面的投影,经计算机处理来进行图像重建。鉴于CT对于医学诊断技术的发展所起到的巨大推动作用,柯麦科和豪恩斯弗尔德于1979年获得了诺贝尔生理或医学奖。

随后在2003年,诺贝尔生理或医学奖的殊荣再次授予了两位在医疗影像设备研究方面做出杰出贡献的科学家——美国化学家保罗·劳特伯尔(Paul Lauterbur)和英国物理学家彼得·曼斯菲尔(Peter Mansfield)。两位获奖者在利用磁共振成像(Magnetic Resonance Imaging,MRI)显示不同结构方面分别取得了开创性成就。瑞典卡罗林斯卡医学院称,这两位科学家在MRI领域的开创性工作,代表了医学诊疗和研究的重大突破。而事实上,核磁共振的成功同样也离不开数字图像处理方面的发展。即使在今天,诸如MRI图像降噪等问题依然是数字图像处理领域的热门研究方向。

说到数字图像的发展历程,还有一项至关重要的成果不得不提,那就是电荷耦合元件(Charge-coupled Device,CCD)。CCD最初是由美国贝尔实验室的科学家维拉德·波义耳(Willard Sterling Boyle)和乔治·史密斯(George Elwood Smith)于1969年发明的。CCD的作用就像胶片一样,它能够把光学影像转化为数字信号。今天人们所广泛使用的数码照相机、数码摄影机和扫描仪都是以CCD为基础发展而来的。换句话说,我们现在所研究的数字图像主要也都是通过CCD设备获取的。由于波义耳和史密斯在CCD研发上所做出的巨大贡献,他们两人共同荣获了2009年度的诺贝尔物理学奖。

数字图像处理在今天是非常热门的技术之一,生活中无处不存在着它的影子,可以说它是一种每时每刻都在改变着人类生活的技术。但长久以来,很多人对数字图像处理存在着较大的曲解,人们总是不自觉地将图像处理和Photoshop联系在一起。大名鼎鼎的Photoshop无疑是当前使用最为广泛的图像处理工具。类似的软件还有Corel公司生产的CorelDRAW等软件。

尽管Photoshop是一款非常优秀的图像处理软件,但它的存在并不代表数字图像处理的全部理论与方法。它所具有的功能仅仅是数字图像处理中的一部分。总的来说,数字图像处理研究的内容主要包括如下几个方面:

  • 1)图像获取和输出
  • 2)图像编码和压缩
  • 3)图像增强与复原
  • 4)图像的频域变换
  • 5)图像的信息安全
  • 6)图像的区域分割
  • 7)图像目标的识别
  • 8)图像的几何变换

但图像处理的研究内容,又不仅限于上述内容!所以说图像处理的研究话题是相当宽泛的。那现在图像处理都应用在哪些领域呢?或许我们可能熟知的例子有(当然,你应该还能举出更多例子):

  • 1)一些专业图像处理软件:Photoshop、CorelDRAW……
  • 2)一些手机APP应用:美图秀秀、玩图……
  • 3)一些医学图像处理应用:MRI、彩超图像处理……
  • 4)一些制造业上的应用:元器件检测、瑕疵检测……
  • 5)一些摄像头、相机上的应用:夜间照片的质量改善……
  • 6)一些电影工业上是应用:换背景、电影特技……

 

什么样的人会去学(或者需要学)图像处理?

 

1)如果你是我上述那些应用领域的从业者,你当然需要掌握图像方面的理论和技术;2)相关专业的研究人员、大专院校的博士生、研究生。

所谓相关专业又是指什么呢?这个答案也可能相当宽泛,例如(但不仅限于此):Computer Science, Software Engineering, Electronic Engineering, Biomedical Engineering, Automation, Control, Applied Mathematics……

 

如何学好图像处理——我的一些箴言

 

1)对于初级入门者

 

一个扎实的基础和对于图像处理理论的完整的、系统的整体认识对于后续的深入研究和实践应用具有非常非常重要的意义。

我经常喜欢拿武侠小说《天龙八部》中的一段情节来向读者说明此中的道理,相信读者对这部曾经被多次搬上银幕的金庸作品已经耳熟能详了。书中讲到有个名叫鸠摩智的番僧一心想练就绝世武学,而且他也算是个相当勤奋的人了。但是,他错就错在太过于急功近利,甚至使用道家的小无相功来催动少林绝技。看上去威力无比,而且可以在短时间内“速成”,但实则后患无穷。最终鸠摩智走火入魔,前功尽废,方才大彻大悟。这个故事其实就告诉我们打牢基础是非常重要的,特别是要取得更长足的发展,就更是要对基本原理刨根问底,力求甚解,从而做到庖丁解牛,游刃有余。

一些看似高深的算法往往是许多基础算法的组合提升。例如,令很多人望而却步的SIFT特征构建过程中,就用到了图像金字塔、直方图、高斯滤波这些非常非常基础的内容。但是,它所涉及的基础技术显然有好几个,如果缺乏对图像处理理论的系统认识,你可能会感觉事倍功半。因为所有的地方好像都是沟沟坎坎。

关于课程——

在这个阶段其实对于数学的要求并不高,你甚至可以从一些感性的角度去形象化的理解图像处理中很多内容(但不包括频域处理方面的内容)。具体到学习的建议,如果有条件(例如你还在高校里读书)你最好能选一门图像处理方面的课程,系统地完整的地去学习一下。这显然是入门的最好办法。如此一来,在建立一个完整的、系统的认知上相当有帮助。如果你没办法在学校里上一门这样的课,网上的一些公开课也可以试试。但现在中文MOOC上还没有这方面的优质课程推荐。英文的课程则有很多,例如美国加州伦斯勒理工学院Rich教授的数字图像处理公开课——https://www.youtube.com/channel/UCaiJlKxXamoODQtlx486qJA?spfreload=10。

关于教材——

显然,只听课其实还不太够,如果能一并读一本书就最好了。其实不用参考很多书,只要一本,你能从头读到尾就很好了。如果你没有条件去上一门课,那读一本来完整的自学一下就更有必要了。这个阶段,去网上到处找博客、看帖子是不行的。因为你特别需要在这个阶段对这门学问建立一个系统的完整的知识体系。东一块、西一块的胡拼乱凑无疑是坑你自己,你的知识体系就像一个气泡,可能看起来很大,但是又脆弱的不堪一击。

现在很多学校采用冈萨雷斯的《数字图像处理》一书作为教材。这是一本非常非常经典的著作。但是我必须要提醒读者:

1)这是一本专门为Electronic Engineering专业学生所写的书。它需要有信号与系统、数字信号处理这两门课作为基础。如果你没有这两门课的基础,你读这本书要么是看热闹,要么就是看不懂。

下面是冈书中的一张插图。对于EE的学生来说,这当然不是问题。但是如果没有我说的那两门课的基础,其实你很难把握其中的精髓。H和h,一个大小一个小写,冈书中有的地方用H,有的地方用h,这都是有很深刻用意的。原作者并没有特别说明它们二者的区别,因为他已经默认你应该知道二者是不同的。事实上,它们一个表示频域信号,一个表示时域信号,这也导致有时候运算是卷积,有时候运算是乘法(当然这跟卷积定理有关)。所以我并不太建议那些没有这方面基础的学生在自学的时候读这本书。

 

2)冈萨雷斯教授的《数字图像处理》第一版是在1977年出版的,到现在已经快40年了;现在国内广泛使用的第二版是2002年出版的(第三版是2007年但是其实二者差异并不大),到现在也有20年左右的时间了。事实上,冈萨雷斯教授退休也有快30年了。所以这本书的内容已经偏于陈旧。数字图像处理这个领域的发展绝对是日新月异,突飞猛进的。特别在最近二三十年里,很多新思路,新方法不断涌现。如果你看了我前面推荐的Rich教授的公开课(这也是当前美国大学正在教学的内容),你一下子就会发现,原来我们的教育还停留在改革开放之前外国的水平上。这其实特别可怕。所以我觉得冈萨雷斯教授的《数字图像处理》作为学习过程中的一个补充还是不错的,但是如果把它作为主参考,那真的就是:国外都洋枪洋炮了,我们还在大刀长矛。

 

那么现在问题来了,对于图像处理学习者而言到底看什么书好呢?我的意见是你可以选择下面两本书中的任何一本《数字图像处理原理与实践(Matlab版)》,以及《数字图像处理:技术详解与Visual C++实践》,当然选择的标准之一就是到底你更擅长使用MATLAB还是C++。

   

 

 

 

2)对于中级水平者

 

纸上得来终觉浅,绝知此事要躬行。对于一个具有一定基础的,想更进一步的中级水平的人来说,这个阶段最重要的就是增强动手实践的能力。

还是说《天龙八部》里面的一个角色——口述武功、叹为观止的王语嫣。王语嫣的脑袋里都是武功秘籍,但问题是她从来都没练过一招一式。结果是,然并卵。所以光说不练肯定不灵啊。特别是,如果你将来想从事这个行业,结果一点代码都不会写,那几乎是不可想象的。学习阶段,最常被用来进行算法开发的工具是Matlab和OpenCV。你可以把这两个东西都理解为一个相当完善的库。当然,在工业中C++用得更多,所以Matlab的应用还是很有限的。前面我们讲到,图像处理研究内容其实包括:图像的获取和编解码,但使用Matlab和OpenCV就会掩盖这部分内容的细节。你当然永远不会知道,JPEG文件到底是如何被解码的。

如果你的应用永远都不会涉及这些话题,那么你一直用Matlab和OpenCV当然无所谓。例如你的研究领域是SIFT、SURF这种特征匹配,可以不必理会编解码方面的内容。但是如果你的研究话题是降噪或者压缩,可能你就绕不开这些内容。最开始学的时候,如果能把这部分内容也自己写写,可能会加深你的理解。以后做高级应用开发时,再调用那些库。所以具体用什么,要不要自己写,是要视你所处的阶段和自己的实际情况而定的。以我个人的经验,在我自学的时候,我就动手写了Magic House,我觉得这个过程为我奠定了一个非常夯实的基础,对于我后续的深入研究很有帮助。

 

下面这个文中,我给出了一些这方面的资源,代码多多,很值得参考学习:图像处理与机器视觉网络资源收罗

http://blog.csdn.net/baimafujinji/article/details/32332079

 

3)对于高级进阶者

 

到了这个程度的读者,编程实现之类的基本功应该不在话下。但是要往深,往高去学习、研究和开发图像处理应用,你最需要的内容就变成了数学。这个是拦在很多处于这个阶段的人面前的一大难题。如果你的专业是应用数学,当然你不会感觉有问题。但如果是其他专业背景的人就会越发感觉痛苦。

如果你的图像处理是不涉及机器学习内容的,例如用Poisson方程来做图像融合,那你就要有PDE数值解方面的知识;如果你要研究KAZE特征,你就必须要知道AOS方面的内容。如果你研究TV降噪,你又要知道泛函分析中的BV空间内容……这些词你可能很多都没听过。总的来说,这块需要的内容包括:复变函数、泛函分析、偏微分方程、变分法、数学物理方法……

如果你要涉足机器视觉方法的内容,一些机器学习和数据挖掘方法的内容就不可或缺。而这部分内容同样需要很强大的数学基础,例如最大似然方法、梯度下降法、欧拉-拉格朗日方程、最小二乘估计、凸函数与詹森不等式……

当然,走到这一步,你也已经脱胎换骨,从小白到大神啦!路漫漫其修远兮,吾将上下而求索。

 

(全文完)

 

 

2018-06-12 20:29:09 program_developer 阅读数 2187

“微信公众号”


本文介绍图像处理、计算机视觉、图像前背景分离技术等领域的术语。这里给出若干相关术语及本文对这些术语的解释。

1. 前背景分离(matting):也称抠图,即将图像或视频的某一感兴趣的部分从原始图像或视频中分离出来,主要功能是为了和另一个图像或视频进行合成,形成新的图像或视频。

2. 颜色空间(color space):颜色模型是使用一组值(通常三个、四个值或者颜色成分)表示颜色的抽象数学模型,比如RGB和CMYK都是颜色模型。在颜色模型和一个特定的参照颜色空间之间加入一个特定的映射函数就在参照颜色空间中确定了一个明确的色域,并且与颜色模型一起定义为一个新的颜色空间。

3. 前景蒙版(alpha matte):也称前景透明度或透明度蒙版,是前背景分离的结果,是一个灰度图,每一个像素点的灰度值表示原始图像每个像素属于前景物体的程度,白色代表某一个像素确定属于前景,黑色代表某一个像素确定属于背景。

4. 三值蒙版(trimap):是一些前背景分离方法使用的用户输入和约束条件,用户在原图像上指定哪些像素点是确定的前景,用白色表示;哪些像素点是确定的背景,用黑色表示;哪些像素点是不确定的部分,用某种灰色表示。三值蒙版越精细准确,得到的前背景分离结果越好,但对用户的要求更高,处理时间越长。

5. 简单标记(scribble):是一些前背景分离方法使用的用户输入和约束条件,用户在原图像上以一个或多个白色点或线条标记确定的前景,以一个或多个黑色点或线条标记确定的背景,标记越多、越具有代表性,得到的前背景分离结果越好,对用户的要求也更高。简单标记与三值蒙版相比较,用户输入更简单方便,能大大减少处理时间。

6. 边缘检测算子(edge detection operator):边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化,包括深度上的不连续、表明方向不连续、物质属性变化和场景照明变化。图像边缘检测大幅度地减少了数据量,留下了图像重要的结构属性。边缘检测算子包括:Roberts Cross算子、Prewitt算子、Sobel算子、Canny算子、罗盘算子等。Canny算子是最常用的边缘检测方法。

7. 视差图(disparity map):视差就是从有一定距离的两个点上观察同一个目标所产生的方向差异。从目标看两个点之间的夹角,叫做这两个点的视差,两点之间的距离称作基线。只要知道视差角度和基线长度,就可以计算出目标和观测者之间的距离。视差图是以图像对中任一幅图像为基准,其大小为该基准图像的大小,元素值为视差值的图像。

8. 深度图(depth map):本文中的深度图是黑白二值图,是通过对图像的视差图再处理或视频背景建模后获取深度的结果,作为本文前背景分离方法的约束条件。综合考虑原始图像的颜色信息和深度信息,可以得到更好的前背景分离效果。

9. 前背景分离方程(matting equation):自然图像I可看作由前景图像F和背景图像B组合而成,I中的每个像素点是F和B中对应像素点颜色的线性组合。

  (1)

为像素点的前景透明度,。(1)式中,已知,而未知,是一个缺少条件的方程组。使用RGB颜色空间则有:

  (2)

(2)式有7个未知量,却只有3个方程,如果不加其他条件,(2)式有无穷多解。有人眼来分辨一幅图像哪些部分属于前景,哪些部分属于背景,只有一个或几个可以接受的结果,前背景分离模型为将这一过程自动化,可对前景和背景合理假设,或者增加图像数量,使方程组的解变少,使解与人眼分辨结果尽可能接近。


读论文《图像前背景分离的研究与实现》的笔记。

地址:https://www.docin.com/p-1084120800.html

2014-11-30 20:35:04 xiayang1023 阅读数 4369

废话不多说,先上图。

原图


圆形的清晰区域


竖直的清晰区域


水平的清晰区域


嘿嘿,看上去还可以哈~~我们这里说的背景虚化呢,自然没有能力做到自动识别背景与前景的,所以只能算是一个半自动的过程:由用户来指定哪片区域是清晰的,哪片区域是模糊的,然后在清晰的区域与模糊的区域之间做一个简单的过渡。

我们在这里提供了三张模式,分别是圆形的清晰区域,竖直的清晰区域和水平的清晰区域。示意图如下所示

圆形


横向


纵向


如果你还想折腾出其他的形状,可以参考我后面的代码自己折腾一下。

这里不打算讲高斯模糊之类的东西,相信现有的博客写高斯模糊早已写烂了。我也只是借用了图像模糊里面的一个思想而已:使用周围像素的平均值来代替当前像素。高斯模糊里面对像素点周围不同位置的像素点还赋予了不同的权重,我为了简单,索性让所有的权重都一样。产生的效果也还行。

下面就把全部代码都奉上。


package algorithm.blur;

import java.awt.Color;
import java.awt.image.BufferedImage;

public class InteractiveBlur
{

	// 掩码最小值
	public static final int MIN_MASK_SIZE = 3;

	// 掩码最大值
	public static final int MAX_MASK_SIZE = 15;
	
	//掩码最大值的一半
	public static final int HALF_MAX_MASK_SIZE = 7;

	// 最小值与最大值的差
	public static final int DIFF_MASK_SIZE = MAX_MASK_SIZE - MIN_MASK_SIZE;

	// 点在模糊区域中
	public static final int AREA_BLUR = 1;

	// 点在清晰区域中
	public static final int AREA_CLEAR = 2;

	// 点在过渡区域中
	public static final int AREA_TRAN = 3;

	// 圆形的清晰区域
	public static final int TYPE_CIRCLE = 1;

	// 垂直的清晰区域
	public static final int TYPE_VERTCIAL = 2;

	// 水平的清晰区域
	public static final int TYPE_HORIZONTAL = 3;

	//外部区域以外的都是模糊的
	private static int outSize;
	
	//内部区域以内的都是清晰的
	private static int innerSize;

	//区域
	private static int area;

	
	private static Color[][] colorMatrix;




	/**
	 * 获取图像
	 * 
	 * @param image
	 *            源图像
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param size
	 *            作用范围
	 * @param type
	 *            类型
	 * */
	public static BufferedImage getImage(BufferedImage image, int x, int y, int size, int type)
	{
		InteractiveBlur.innerSize = size;
		InteractiveBlur.outSize = (int) (size * 1.5);
		// 获取rgb矩阵
		colorMatrix = getColorMatrix(image);

		switch (type)
		{
		case TYPE_VERTCIAL:
			return getVecticalImage(image, x, size);
		case TYPE_HORIZONTAL:
			return getHozizontalImage(image, y, size);
		default:
			return getCircleImage(image, x, y, size);
		}
	}

	/**
	 * 获取圆形的清晰区域
	 * 
	 * @param image
	 *            源图像
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param size
	 *            作用范围
	 * */
	private static BufferedImage getCircleImage(BufferedImage image, int centerX, int centerY, int size)
	{
		int width = image.getWidth();
		int height = image.getHeight();

		BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++)
		{
			for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++)
			{
				int distance = getDistance(x, y, centerX, centerY);
				area = getArea(distance);
				outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));
			}
		}
		return outputImage;
	}

	/**
	 * 获取纵向的背景虚化图像
	 * 
	 * @param image
	 *            源图像
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param size
	 *            作用范围
	 * */
	public static BufferedImage getVecticalImage(BufferedImage image, int centerX, int size)
	{
		int width = image.getWidth();
		int height = image.getHeight();

		BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++)
		{
			int distance  = Math.abs(x - centerX);
			area = getArea(Math.abs(x - centerX));

			for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++)
			{
				outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));

			}
		}
		return outputImage;
	}

	/**
	 * 获取水平的背景虚化图像
	 * 
	 * @param image
	 *            源图像
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param size
	 *            作用范围
	 * */
	public static BufferedImage getHozizontalImage(BufferedImage image, int centerY, int size)
	{
		int width = image.getWidth();
		int height = image.getHeight();
		BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		for (int y = HALF_MAX_MASK_SIZE; y < height - HALF_MAX_MASK_SIZE; y++)
		{
			int distance = Math.abs(y - centerY);
			area = getArea(distance);
			
			for (int x = HALF_MAX_MASK_SIZE; x < width - HALF_MAX_MASK_SIZE; x++)
			{
				outputImage.setRGB(x, y, getRGBValue(image, x, y,distance));

			}
		}
		return outputImage;
	}

	
	private static int getRGBValue(BufferedImage image, int x, int y,int distance)
	{
		if (area == AREA_BLUR)
		{
			return getBlurRGBValue(x, y, MAX_MASK_SIZE);
		}
		else if (area == AREA_TRAN)
		{
			// 过渡区间
			int maskSize = MIN_MASK_SIZE + DIFF_MASK_SIZE * (distance - innerSize) / (outSize - innerSize);
			// 将masksize变为奇数
			maskSize = (maskSize / 2) * 2 + 1;

			return getBlurRGBValue(x, y, maskSize);
		}
		else
		{
			return image.getRGB(x, y);
		}
	}

	/**
	 * 获取模糊后的图像的rgb值
	 * 
	 * @param colorMatrix
	 * @param x
	 * @param y
	 * @param maskSize
	 * */
	private static int getBlurRGBValue(int x, int y, int maskSize)
	{
		int sum = maskSize * maskSize;
		int halfMaskSize = maskSize / 2;

		int sumR = 0, sumG = 0, sumB = 0;
		for (int i = -halfMaskSize; i <= halfMaskSize; i++)
		{
			for (int j = -halfMaskSize; j <= halfMaskSize; j++)
			{
				sumR += colorMatrix[x + i][y + j].getRed();
				sumG += colorMatrix[x + i][y + j].getGreen();
				sumB += colorMatrix[x + i][y + j].getBlue();
			}
		}
		sumR /= sum;
		sumG /= sum;
		sumB /= sum;

		sumR = sumR << 16;
		sumG = sumG << 8;

		return sumR|sumG|sumB;
	}

	// 判断点在那个区域
	private static int getArea(int distance)
	{
		int area;
		if (distance > outSize)
		{
			area = AREA_BLUR;
		}
		else if (distance < innerSize)
		{
			area = AREA_CLEAR;
		}
		else
		{
			area = AREA_TRAN;
		}
		return area;
	}

	/**
	 * 获取两点之间的距离
	 * 
	 * @param x1
	 *            第一个点的X坐标
	 * @param y1
	 *            第一个点的y坐标
	 * @param x2
	 *            第二个点的X坐标
	 * @param y2
	 *            第二个点的y坐标
	 * */
	private static int getDistance(int x1, int y1, int x2, int y2)
	{
		int x = x1 - x2;
		int y = y1 - y2;
		return (int) Math.sqrt(x * x + y * y);
	}
	
	
	/**
	 * 获取图像的color矩阵
	 * 
	 * @param image
	 * */
	private static Color[][] getColorMatrix(BufferedImage image)
	{
		int width = image.getWidth();
		int height = image.getHeight();
		Color[][] matrix = new Color[width][height];
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				matrix[x][y]  = new Color(image.getRGB(x, y));
			}
		}
		return matrix;
	}
}