「java图像滤波」java图像处理技术
本篇文章给大家谈谈java图像滤波,以及java图像处理技术对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、java手写体英文数字识别系统 识别预处理如何实现 采用什么语言比较好
- 2、Java图像去噪怎么实现?
- 3、急!!,二值化后的图像,用JAVA中值滤波算法,去除椒盐噪点!!!
- 4、如何java编程实现巴特沃斯低通滤波器
- 5、图像处理之双边滤波算法
- 6、如何用java去除图片水印?
java手写体英文数字识别系统 识别预处理如何实现 采用什么语言比较好
转载 1 引言
手写体数字识别是文字识别中的一个研究课题,是多年来的研究热点,也是模式识别领域中最成功的应用之一。由于识别类型较少,在实际生活中有深远的应用需求,一直得到广泛的重视。近年来随着计算机技术和数字图像处理技术的飞速发展,数字识别在电子商务、机器自动输入等场合已经获得成功的实际应用。尽管人们对手写数字的研究己从事了很长时间的研究,并己取得了很多成果,但到目前为止,机器的识别本领还无法与人的认知能力相比,这仍是一个有难度的开放问题,所以对手写数字识别的进一步研究,寻求如何更高效更准确更节能地实现手写数字的自动录入和识别的解决方案对提高经济效益、推动社会发展都有深远的意义。
近年来, 人工神经网技术发展十分迅速, 它具有模拟人类部分形象思维的能力, 为模式识别开辟了新的途径, 成了模拟人工智能的一种重要方法,特别是它的信息并行分布式处理能力和自学习功能等显著优点, 更是激起了人们对它的极大的兴趣。BP(Back Propagation)网络是神经网络中一种,是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,可以很好地解决非线性问题,在函数逼近、模式识别和数据压缩等方面都有很广泛的应用。我们在认真地研究了神经网络的基本原理和机制的基础上, 结合手写体数字识别这一具体课题, 提出了用BP神经网络方法来实现手写体数字识别的方案。
2 手写体数字识别概述
2.1 手写数字识别简述
模式识别是六十年代初迅速发展起来的一门学科。由于它研究的是如何用机器来实现人及某些动物对事物的学习、识别和判断能力,因而受到了很多科技领域研究人员的注意,成为人工智能研究的一个重要方面。
字符识别是模式识别的一个传统研究领域。从50年代开始,许多的研究者就在这一研究领域开展了广泛的探索,并为模式识别的发展产生了积极的影响。
手写体数字识别是多年来的研究热点也是字符识别中的一个特别问题。手写体数字识别在特定的环境下,如邮政编码自动识别系统,税表和银行支票自动处理系统等一般情况。当涉及到数字识别时,人们往往要求识别器有很高的识别可靠性,特别是有关金额的数字识别时,如支票中填写的金额部分,更是如此。因此针对这类问题的处理系统设计的关键环节之一就是设计出高可靠性和高识别率的手写体数字识别方法。这个领域取得了飞速的发展,部分是由于更好的学习算法,部分是由于更优良的训练集。美国国家科学学会(NIST)建立了
一个包含60000个经过标注的数字的数据库,它已经成为对新的学习算法进行比较的性能测试标准。然而可以说还没有哪个手写体数字识别器达到完美的识别效果。
在过去的数十年中,研究者们提出了许许多多的识别方法,按使用的特征不同,这些方法可以分为两类:基于结构特征的方法和基于统计特征的方法。统计特征通常包括点密度的测量、矩、特征区域等。结构特征通常包括园、端点、交叉点、笔划、轮廓等,一般来说,两类特征各有优势。例如,使用统计特征的分类器易于训练,而且对于使用统计特征的分类器,在给定的训练集上能够得到相对较高的识别率;而结构特征的主要优点之一是能描述字符的结构,在识别过程中能有效地结合几何和结构的知识,因此能够得到可靠性较高的识别结果。本文针对手写数字识别选用BP神经网络这种基于传统统计学基础上的分类方法,用于分割和识别,并取得了较好的识别效果。
2.2 手写数字识别的一般过程
手写体数字识别的过程如图2-1所示,一般分为预处理、特征提取、数字串的分割、分类器、等模块。原始图像是通过光电扫描仪,CCD器件或电子传真机等获得的二维图像信号。预处理包括对原始图像的去噪、倾斜校正或各种滤波处理。手写体数字具有随意性,其字符大小、字间距、字内距变化很大,分割难度较大。手写数字串的分割是其中最重要的环节,是制约识别率的瓶颈所在。去噪是预处理中极重要的环节。系统面对的是从实际环境中切分出的字符图像,可能有粘连的边框、随机的墨点、切分不正确引入的其他字符笔划等使前景点增加的噪声,还可能有断线等使背景增加的噪声,目前适应各种环境的通用去噪算法还不成熟。预处理中的规格化也不仅仅是同比例的放缩,它不仅要保持拓扑不变,更要最大限度地突出所取特征。在众多应用环境中,特征提取、分类器、多分类器集成是整个识别系统的核心。大体上来说特征可以分为结构特征和统计特征两类。由于分类器的选择取决于所提取的特征,因此相应的识别方法便有结构方法和统计方法。
总之,从手写体数字识别原理可见,手写体数字识别技术主要包括以下几点:
1)图像预处理,包括彩色图像转成灰度图像、二值化,归一化,滤除干扰噪声等;
2)基于数字图像的特征选择和提取;
3)数字串的分割;
4)模式分类识别。
其中,第二和第四部分是手写数字识别的重点,直接关系到识别的准确率和效率,也是本论文研究的重点所在。
结果图2-1 识别流程
2.3 手写数字识别的一般方法及比较
手写数字识别在学科上属于模式识别和人工智能的范畴。在过去的四十年中,人们提出了很多办法获取手写字符的关键特征,提出了许多识别方法和识别技术。这些手段分两大类:
全局分析和结构分析。
多年的研究实践表明,对于完全没有限制的手写数字,几乎可以肯定:没有一种简单的方案能达到很高的识别率和识别精度,因此,最近这方面的努力向着更为成熟、复杂、综合的方向发展。研究工作者努力把新的知识运用到预处理,特征提取,分类当中。近年来,人工智能中专家系统方法、人工神经网络方法已应用于手写数字识别。在手写数字识别的研究中,神经网络技术和多种方法的综合是值得重视的方向。
针对模式特征的不同选择及其判别决策方法的不同,可将模式识别方法大致分为5大类这5种识别方法均可实现手写数字识别,但它们特点不同,必须根据条件进行选择。
(1)统计模式法
这是以同类模式具有相同属性为基础的识别方法。用来描述事物属性的参量叫做待征,它可以通过模式的多个样本的测量值统计分析后按一定准则来提取。例如:在手写数字识别系统中,我们可以把每个数字的图形分为若干个小方块(图),然后统计每一小方块中的黑像素构成一个多维特征矢量,作为该数字的特征。必须注意的是:在选择特征时,用于各类模式的特征应该把同类模式的各个样本聚集在一起,而使不同类模式的样本尽量分开,以保证识别系统能具有足够高的识别率。
(2)句法结构方法
在形式语言和自动机的基础上产生了句法结构这一方法。其基本原理是:对每一个模式都用一个句法来表示,而对一个待识别的未知样本,通过抽取该样本的基元来构造该样本的句子,然后分析此句子满足什么样的句法,从而推断出他该属于哪个模式类。这种方法的优点是它能反映模式的结构特征,而且对模式的结构特征变换不敏感,因此比较适合联机识别。但是由于抽取字符的基元比较困难,因而不是特别适合用于脱机识别,同时这一方法的理论基础还不可靠,抗干扰能力比较弱。
(3)逻辑特征法
就是其特征的选择对一类模式识别问题来说是独一无二的,即在一类问题中只有1个模式具有某1种(或某1组合的)逻辑特征,此方法律立了关于知识表示及组织,目标搜索及匹配的完整体系;对需通过众多规则的推理达到识别目标的问题,有很好的效果,但当样品有缺损,背景不清晰,规则不明确甚至有歧义时,效果不好。
(4)模糊模式方法
就是在模式识别过程中引入了模糊集的概念,由于隶属度函数作为样品与模板相似程度的量度,故能反映整体的、主要的特性,模糊模式有相当不匀称的抗干扰与畸变,从而允许样品有相当程度的干扰与畸变,但准确合理的隶属度函数往往难以建立。目前有学者在研究,并将其引入神经网络方法形成模糊神经网络识别系统。
(5)神经网络方法
就是使用人工神经网络方法实现模式识别。可处理某些环境信息十分复杂,背景知识不清楚,推理规则不明确的问题,允许样品有较大的缺损、畸变。神经网络方法的缺点是其模型在不断丰富完善中,目前能识别的模式类不够多,神经网络方法允许样品有较大的缺损和畸变,其运行速度快,自适应性能好,具有较高的分辨率。
上述几种识别方法各有特点。结构法比较直观,能较好反映事物的结构特性:问题是基元的提取很不容易,各基元的关系也比较复杂,抗干扰性能也较差。统计法用计算机来抽取特征,比较方便,抗干扰性能强;缺点是没有充分利用模式的结构特性。神经网络方法由于处理的并行性,可以快速同时处理大容量的数据,工作时具有高速度和潜在超高速,并且,网络的最终输出是由所有神经元共同作用的结果,一个神经元的错误对整体的影响很小,所以其容错性也非常的好。基于以上的考虑,本文的手写数字识别采用了神经网络的方法。
3 图像预处理与特征提取
手写体图像数据在没有进行一定的图像预处理和特征提取之前,不能立即应用到程序中进行神经网络训练和字符识别工作。从图像处理角度来说,手写体的字符识别对字符是不是有颜色是不关心的,而对此图像的清晰度是很关心的。所以在图像进行一系列的图像处理工作是很有必要的。图像的预处理是正确、有效提取图像特征的基础,有效的图像特征作为网络的输入值才能进行正确的神经网络训练和最终得到正确、有效的网络权重。
3.1 数字图像预处理
3.1.1 灰度化处理
彩色图像包含了大量的颜色信息,不但在存储上开销很大,在处理上也会降低系统的执行速度,因此在对图像进行识别等处理中经常将彩色图像转变为灰度图像,以加快处理速度。由彩色转换为灰度的过程称为灰度化处理。灰度图像就是只有强度信息而没有颜色信息的图像,存储灰度图像只需要一个数据矩阵,矩阵每个元素表示对应位置像素的灰度值。彩色图像的像素色为RGB(R,G,B),灰度图像的像素色为RGB(r,r,r) ,R,G,B可由彩色图像的颜色分解获得。而R,G,B的取值范围是0-255,所以灰度的级别只有256级。灰度化的处理方法主要有如下三种:最大值法、平均值法和加权平均值法。本文用到的加权平均值法来处理,即更换每个像素的颜色索引(即按照灰度映射表换成灰度值)。 权重选择参数为:
红:0.299
绿:0.587
蓝:0.114
例如某像素点颜色对应的灰度值计算公式为:
NewPixColor?(BYTE)(0299*Red?0.587*Green?0.114*Blue) 系统输入的源图像支持3通道或者4通道图像,支持Format24bppRgb, format32bppRgb, Format32bppArgb和Format8bppIndex这4种像素格式。
3.1.2 二值化处理
二值图像是指整幅图像画面内仅黑、白二值的图像。在数字图像处理中,二值图像占有非常重要的地位。在实际的识别系统中,进行图像二值变换的关键是要确定合适的阈值,使得字符与背景能够分割开来,二值变换的结果图像必须要具备良好的保形性,不丢掉有用的形状信息,不会产生额外的空缺等等。采用二值图像进行处理,能大大地提高处理效率。 二值化的关键在于阈值的选取,阈值的选取方法主要有三类:全局阈值法、局部阈值法、动态阈值法。全局阀值二值化方法是根据图像的直方图或灰度的空间分布确定一个阀值,并根据该阀值实现灰度图像到二值化图像的转化。全局阀值方法的优点在于算法简单,对于目标和背景明显分离、直方图分布呈双峰的图像效果良好,但对输入图像量化噪声或不均匀光照等情况抵抗能力差,应用受到极大限制。局部阀值法则是由像素灰度值和像素周围点局部
灰度特性来确定像素的阀值的。Bernsen算法是典型的局部阀值方法,非均匀光照条件等情况虽然影响整体图像的灰度分布却不影响局部的图像性质,局部阀值法也存在缺点和问题,如实现速度慢、不能保证字符笔划连通性、以及容易出现伪影现象等。动态阀值法的阀值选择不仅取决于该像素灰度值以及它周围像素的灰度值,而且还和该像素的坐标位置有关,由于充分考虑了每个像素邻域的特征,能更好的突出背景和目标的边界,使相距很近的两条线不会产生粘连现象。在图像分割二值化中,自动闽值选取问题是图像分割的关键所在。事实证明,闽值的选择的恰当与否对分割的效果起着决定性的作用。
本文采用全局阈值的方法,实现将图像二值化的功能。如果某个像素的值大于等于阈值,该像素置为白色;否则置为黑色。系统程序目前仅支持8bpp灰度图像的转换,阈值介于0~255之间,程序中取220。
3.1.3 去离散噪声
原始图像可能夹带了噪声,去噪声是图像处理中常用的手法。通常去噪用滤波的方法,比如中值滤波、均值滤波,本文中去除离散噪声点采用中值滤波的方法。中值滤波法是一种非线性平滑技术,它将每一象素点的灰度值设置为该点某邻域窗口内的所有象素点灰度值的中值,让周围的像素值接近的真实值,从而消除孤立的噪声点。
3.1.4 字符分割
在识别时系统只能根据每个字符的特征来进行判断,为了最终能准确识别手写体数字,必须将单个字符从处理后的图像中逐个提取分离出来。具体做法是将图像中待识别的字符逐个分离出来并返回存放各个字符的位置信息的链表。当把图像分割完成后,从一定意义上来说便是形成了不同的小图,每一张小图就是一个数字,才能对这些小图进行尺寸大小一致的调整。
3.1.5 细化
3.2 图像特征提取
特征提取是字符识别中的一个重要组成部分,是模式识别的核心之一。经过预处理后,根据识别方法的要求抽取图像特征,作为识别的依据。一般而言,选择的特征一方面要求能够足够代表这个图像模式,另一方面要求它们的数量尽可能少,这样能有效地进行分类和较小的计算量。特征提取的好坏会直接影响其识别的分类效果,进而影响识别率,因此特征选择是模式识别的关键。但是,目前还没有一个有效的、一般的抽取、选择特征的方法。抽取、选择特征的方法都是面对问题的,因此针对不同的识别问题往往有不止一种的抽取、选择特征的方法。
Java图像去噪怎么实现?
流程不外乎是
读取图像文件;
扫描噪点;
去除噪点;
保存图像文件。
Java2D操作好像使用BufferedImage读取图像文件最方便,有一阵没弄这了,忘了。应该可以读取JPG,PNG,GIF图像。
识别噪点应该有专门的算法,我没研究过,百度一下应该能找到专门算法,然后写段代码就可以。我个人以为是独立一个像素与周围一定范围内的像素差异过大,就认为是噪点。可以有亮度,色相上的差别。BufferedImage可以读取每个像素的RGB,从而能识别色相的差别;还有个矩阵,用来由RGB计算亮度的,也就可以计算亮度差别了,这个网上都能找到。
输出也使用BufferedImage就可以。
关键是每个像素都要和周围像素比较,还要计算亮度,最少是三重循环了,如何提高效率是个大问题了。这个代码写好了也算一个高手了。
急!!,二值化后的图像,用JAVA中值滤波算法,去除椒盐噪点!!!
椒盐噪声的话一般可以用中值滤波器去除, 中值滤波器很容易实现, 依此遍历图像中每个像素点, 每个像素点与其周围的8个点像素值做一下排序操作, 找到这九个点中的中值点赋给当前遍历点的像素就可以了, 算法很简单吧. 我这有c++的源码, 楼主要想要的话发邮件到我的邮箱769569350@qq.com我可以把程序发给你.
如何java编程实现巴特沃斯低通滤波器
float middle_filter(float middle_value [] , intcount){ float sample_value, data; int i, j; for (i=1; i for(j=count-1; j=i,--j){ if(middle_value[j-1]=middle_value[j]{ data=middle_value[j-1]; middle_value[j-1]=middle_value[j]
图像处理之双边滤波算法
双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部处理的特点。之所以能够达到保边去噪的滤波效果是因为滤波器由两个函数构成:
一个函数是像素欧式距离决定滤波器模板的系数,另一个是由像素的灰度差值决定滤波器模板的系数。
其综合了高斯滤波器(Gaussian Filter)和α-截尾均值滤波器(Alpha-Trimmed mean Filter)的特点。高斯滤波器只考虑像素间的欧式距离,其使用的模板系数随着和窗口中心的距离增大而减小;Alpha截尾均值滤波器则只考虑了像素灰度值之间的差值,去掉α%的最小值和最大值后再计算均值。
双边滤波器使用二维高斯函数生成距离模板,使用一维高斯函数生成值域模板。
双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,其公式如下:
其中(k,l)为模板窗口的中心坐标;(i,j)为模板窗口的其他系数的坐标;σd为高斯函数的标准差。 使用该公式生成的滤波器模板和高斯滤波器使用的模板是没有区别的。
值域模板系数的生成公式如下:
其中,函数f(x,y)表示要处理的图像,f(x,y)表示图像在点(x,y)处的像素值;(k,l)为模板窗口的中心坐标;(i,j)为模板窗口的其他系数的坐标;σr为高斯函数的标准差。
将上述两个模板相乘就得到了双边滤波器的模板,其公式如下:
如何用java去除图片水印?
//运行以下程序即可
public class ImageInit {
BufferedImage image;
private int iw, ih;
private int[] pixels;
public ImageInit(BufferedImage image) {
this.image = image;
iw = image.getWidth();
ih = image.getHeight();
pixels = new int[iw * ih];
}
public BufferedImage changeGrey() {
PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih,
pixels, 0, iw);
try {
pg.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 设定二值化的域值,默认值为100
int grey = 100;
// 对图像进行二值化处理,Alpha值保持不变
ColorModel cm = ColorModel.getRGBdefault();
for (int i = 0; i iw * ih; i++) {
int red, green, blue;
int alpha = cm.getAlpha(pixels[i]);
if (cm.getRed(pixels[i]) grey) {
red = 255;
} else {
red = 0;
}
if (cm.getGreen(pixels[i]) grey) {
green = 255;
} else {
green = 0;
}
if (cm.getBlue(pixels[i]) grey) {
blue = 255;
} else {
blue = 0;
}
pixels[i] = alpha 24 | red 16 | green 8 | blue; // 通过移位重新构成某一点像素的RGB值
}
// 将数组中的象素产生一个图像
Image tempImg = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(iw, ih, pixels, 0, iw));
image = new BufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg, 0, 0, null);
return image;
}
public BufferedImage getMedian() {
PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih,
pixels, 0, iw);
try {
pg.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 对图像进行中值滤波,Alpha值保持不变
ColorModel cm = ColorModel.getRGBdefault();
for (int i = 1; i ih - 1; i++) {
for (int j = 1; j iw - 1; j++) {
int red, green, blue;
int alpha = cm.getAlpha(pixels[i * iw + j]);
// int red2 = cm.getRed(pixels[(i - 1) * iw + j]);
int red4 = cm.getRed(pixels[i * iw + j - 1]);
int red5 = cm.getRed(pixels[i * iw + j]);
int red6 = cm.getRed(pixels[i * iw + j + 1]);
// int red8 = cm.getRed(pixels[(i + 1) * iw + j]);
// 水平方向进行中值滤波
if (red4 = red5) {
if (red5 = red6) {
red = red5;
} else {
if (red4 = red6) {
red = red6;
} else {
red = red4;
}
}
} else {
if (red4 red6) {
red = red4;
} else {
if (red5 red6) {
red = red6;
} else {
red = red5;
}
}
}
int green4 = cm.getGreen(pixels[i * iw + j - 1]);
int green5 = cm.getGreen(pixels[i * iw + j]);
int green6 = cm.getGreen(pixels[i * iw + j + 1]);
// 水平方向进行中值滤波
if (green4 = green5) {
if (green5 = green6) {
green = green5;
} else {
if (green4 = green6) {
green = green6;
} else {
green = green4;
}
}
} else {
if (green4 green6) {
green = green4;
} else {
if (green5 green6) {
green = green6;
} else {
green = green5;
}
}
}
// int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]);
int blue4 = cm.getBlue(pixels[i * iw + j - 1]);
int blue5 = cm.getBlue(pixels[i * iw + j]);
int blue6 = cm.getBlue(pixels[i * iw + j + 1]);
// int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);
// 水平方向进行中值滤波
if (blue4 = blue5) {
if (blue5 = blue6) {
blue = blue5;
} else {
if (blue4 = blue6) {
blue = blue6;
} else {
blue = blue4;
}
}
} else {
if (blue4 blue6) {
blue = blue4;
} else {
if (blue5 blue6) {
blue = blue6;
} else {
blue = blue5;
}
}
}
pixels[i * iw + j] = alpha 24 | red 16 | green 8
| blue;
}
}
// 将数组中的象素产生一个图像
Image tempImg = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(iw, ih, pixels, 0, iw));
image = new BufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg, 0, 0, null);
return image;
}
public BufferedImage getGrey() {
ColorConvertOp ccp = new ColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
return image = ccp.filter(image, null);
}
// Brighten using a linear formula that increases all color values
public BufferedImage getBrighten() {
RescaleOp rop = new RescaleOp(1.25f, 0, null);
return image = rop.filter(image, null);
}
// Blur by "convolving" the image with a matrix
public BufferedImage getBlur() {
float[] data = { .1111f, .1111f, .1111f, .1111f, .1111f, .1111f,
.1111f, .1111f, .1111f, };
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data));
return image = cop.filter(image, null);
}
// Sharpen by using a different matrix
public BufferedImage getSharpen() {
float[] data = { 0.0f, -0.75f, 0.0f, -0.75f, 4.0f, -0.75f, 0.0f,
-0.75f, 0.0f };
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data));
return image = cop.filter(image, null);
}
// 11) Rotate the image 180 degrees about its center point
public BufferedImage getRotate() {
AffineTransformOp atop = new AffineTransformOp(
AffineTransform.getRotateInstance(Math.PI,
image.getWidth() / 2, image.getHeight() / 2),
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
return image = atop.filter(image, null);
}
public BufferedImage getProcessedImg() {
return image;
}
public static void main(String[] args) throws IOException {
String filePath="F:/k7qp5.png";
FileInputStream fin = new FileInputStream(filePath);
BufferedImage bi = ImageIO.read(fin);
ImageInit flt = new ImageInit(bi);
flt.changeGrey();
flt.getGrey();
flt.getBrighten();
bi = flt.getProcessedImg();
String pname = filePath.substring(0, filePath.lastIndexOf("."));
File file = new File(pname + ".jpg");
ImageIO.write(bi, "jpg", file);
}
}
关于java图像滤波和java图像处理技术的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-13,除非注明,否则均为
原创文章,转载请注明出处。