㈠ 求256色转灰度图 图像平移 图像旋转 二值化 图像缩放的代码 c或c#或c++或java都行
c++ 加上 opencv 可以实现
㈡ 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中值滤波算法,去除椒盐噪点!!!
椒盐噪声的话一般可以用中值滤波器去除, 中值滤波器很容易实现, 依此遍历图像中每个像素点, 每个像素点与其周围的8个点像素值做一下排序操作, 找到这九个点中的中值点赋给当前遍历点的像素就可以了, 算法很简单吧. 我这有c++的源码, 楼主要想要的话发邮件到我的邮箱[email protected]我可以把程序发给你.
㈣ Sku超量阈值设置 java怎么实现
较为常用的图像二值化方法有:1)全局固定阈值;2)局部自适应阈值;3)OTSU等。局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。
㈤ 用Java对图像进行二值化处理时,kittler函数能直接用吗
取点的RGB值,,,,和预设的值比较,大于是白、小于是黑
㈥ java代码怎么实现图像二值化
较为常用的图像二值化方法有:1)全局固定阈值;2)局部自适应阈值;3)OTSU等。
局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。
这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。
亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。
常用的局部自适应阈值有:
1)局部邻域块的均值;
2)局部邻域块的高斯加权和。
㈦ 如何用java去除图片水印
//运行以下程序即可
publicclassImageInit{
BufferedImageimage;
privateintiw,ih;
privateint[]pixels;
publicImageInit(BufferedImageimage){
this.image=image;
iw=image.getWidth();
ih=image.getHeight();
pixels=newint[iw*ih];
}
publicBufferedImagechangeGrey(){
PixelGrabberpg=newPixelGrabber(image.getSource(),0,0,iw,ih,
pixels,0,iw);
try{
pg.grabPixels();
}catch(InterruptedExceptione){
e.printStackTrace();
}
//设定二值化的域值,默认值为100
intgrey=100;
//对图像进行二值化处理,Alpha值保持不变
ColorModelcm=ColorModel.getRGBdefault();
for(inti=0;i<iw*ih;i++){
intred,green,blue;
intalpha=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值
}
//将数组中的象素产生一个图像
ImagetempImg=Toolkit.getDefaultToolkit().createImage(
newMemoryImageSource(iw,ih,pixels,0,iw));
image=newBufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null),BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg,0,0,null);
returnimage;
}
publicBufferedImagegetMedian(){
PixelGrabberpg=newPixelGrabber(image.getSource(),0,0,iw,ih,
pixels,0,iw);
try{
pg.grabPixels();
}catch(InterruptedExceptione){
e.printStackTrace();
}
//对图像进行中值滤波,Alpha值保持不变
ColorModelcm=ColorModel.getRGBdefault();
for(inti=1;i<ih-1;i++){
for(intj=1;j<iw-1;j++){
intred,green,blue;
intalpha=cm.getAlpha(pixels[i*iw+j]);
//intred2=cm.getRed(pixels[(i-1)*iw+j]);
intred4=cm.getRed(pixels[i*iw+j-1]);
intred5=cm.getRed(pixels[i*iw+j]);
intred6=cm.getRed(pixels[i*iw+j+1]);
//intred8=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;
}
}
}
intgreen4=cm.getGreen(pixels[i*iw+j-1]);
intgreen5=cm.getGreen(pixels[i*iw+j]);
intgreen6=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;
}
}
}
//intblue2=cm.getBlue(pixels[(i-1)*iw+j]);
intblue4=cm.getBlue(pixels[i*iw+j-1]);
intblue5=cm.getBlue(pixels[i*iw+j]);
intblue6=cm.getBlue(pixels[i*iw+j+1]);
//intblue8=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;
}
}
//将数组中的象素产生一个图像
ImagetempImg=Toolkit.getDefaultToolkit().createImage(
newMemoryImageSource(iw,ih,pixels,0,iw));
image=newBufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null),BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg,0,0,null);
returnimage;
}
publicBufferedImagegetGrey(){
ColorConvertOpccp=newColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY),null);
returnimage=ccp.filter(image,null);
}
//
(){
RescaleOprop=newRescaleOp(1.25f,0,null);
returnimage=rop.filter(image,null);
}
//Blurby"convolving"theimagewithamatrix
publicBufferedImagegetBlur(){
float[]data={.1111f,.1111f,.1111f,.1111f,.1111f,.1111f,
.1111f,.1111f,.1111f,};
ConvolveOpcop=newConvolveOp(newKernel(3,3,data));
returnimage=cop.filter(image,null);
}
//
publicBufferedImagegetSharpen(){
float[]data={0.0f,-0.75f,0.0f,-0.75f,4.0f,-0.75f,0.0f,
-0.75f,0.0f};
ConvolveOpcop=newConvolveOp(newKernel(3,3,data));
returnimage=cop.filter(image,null);
}
//11)
publicBufferedImagegetRotate(){
AffineTransformOpatop=newAffineTransformOp(
AffineTransform.getRotateInstance(Math.PI,
image.getWidth()/2,image.getHeight()/2),
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
returnimage=atop.filter(image,null);
}
(){
returnimage;
}
publicstaticvoidmain(String[]args)throwsIOException{
StringfilePath="F:/k7qp5.png";
FileInputStreamfin=newFileInputStream(filePath);
BufferedImagebi=ImageIO.read(fin);
ImageInitflt=newImageInit(bi);
flt.changeGrey();
flt.getGrey();
flt.getBrighten();
bi=flt.getProcessedImg();
Stringpname=filePath.substring(0,filePath.lastIndexOf("."));
Filefile=newFile(pname+".jpg");
ImageIO.write(bi,"jpg",file);
}
}
㈧ 为什么加上二值化就会有语法上的错误
Java程序中的每个变量要么是基本数据类型(boolean, char, byte, short, int, long, float, double),要么是对对象的引用
C++有许多种基本类型,额外还有struct, union, enum, 数组和指针,C++指针可以指向对象,也可以不指向对象
Java没有枚举、联合类型,因为Java认为没有必要。将可有可无的语言元素去掉是Java对C/C++做出的一大改变,因此,普遍认为Java较C++更轻便,更精简
Java采用Unicode字符集,C++通常用ASCII字符集。但ASCII是Unicode的子集,对于习惯于ASCII的程序员感觉不到区别
Java中的boolean类型不能转换成其他类型,反之亦然。C++最近引进了bool类型,代表布尔类型,整型也作为逻辑判断
模板是一种“泛型编程思想”,它有别于“面向对象编程思想”。C++在很大程度上已经支持了这种新型编程方法,特别是STL的出现
Java目前仍未支持泛型编程,不过据说Sun公司有在Java中引入模板的计划
C++支持“运算符的重载”,这是它的一个很重要的多态特征,是数据抽象和泛型编程的利器。它允许直接对对象进行四则运算,正像基本数据类型那样
Java不支持这种多态机制,也是为降低复杂性
两种语言都支持方法重载(overloading)
在C++中,为了允许运行时动态决定哪个函数被调用,一个函数必须用virtual修饰。virtual关键字被自动继承,用以支持多态
凡是没有用virtual修饰的成员函数(包括static)都是静态绑定的,即在编译时决定调用哪个版本
而在Java中,除了static、final、private是静态绑定以外,所有方法一律按动态绑定处理
C++中有“拷贝构造函数”的概念,在三种情况下,自动调用它
用一个对象初始化另一对象
对象作实参进行函数调用
对象作函数的返回值
通常,当一个对象需要做“深拷贝”(钱能:《C++程序设计教程》)时,我们需要为它事先定义“拷贝构造函数”、“赋值运算符的重载函数”和“析构函数”;否则编译器将以“按位”的形式自动生成相应的缺省函数。倘若类中含有指针成员或引用成员,那么这三个默认的函数就隐含了错误
Java则没有这种语法结构和语义逻辑
C++支持inline函数,可以避免函数的堆栈调用,提高运行效率
Java无这种语义
C++中,构造函数的初始化列表是这样使用的:首先按继承顺序调用基类的构造函数构造基类对象,然后按声明顺序调用成员对象的构造函数构造成员对象,最后对列表中出现的成员变量做初始化
Java不采用初始化列表这种构造机制
它们的构造顺序基本一致:
静态变量初始化
静态初始化块(Java)
调用基类的构造函数构造基类对象
实例变量的初始化
构造函数的其余部分
Java使用abstract关键字修饰抽象方法或抽象类
C++的对等语法是“纯虚函数”和“抽象类”
两者都使用抽象类作为继承层次中的基类,提供一般概念,由子类实现其抽象方法,且抽象类都不能被直接实例化为对象
Java中有final关键字,修饰类、方法或变量
final类不能被继承
final方法不能被子类覆盖
final变量就是常量
C++中没有这个关键字,常量可以使用const或#define定义
const还可以修饰成员函数,即“常成员函数”,当一个const成员函数修改成员数据,或调用非const成员函数时,编译器会报错
我们应将不修改成员数据的函数声明为const
Java和C++中的static关键字语法和语义基本相同
static成员变量又叫类变量,被类的所有对象共享
A::x (C++):必须在类体外初始化
A.x (Java):必须在类体内初始化
static成员方法又叫类方法,访问static变量
A::f( ) (C++)
A.f( ) (Java)
两者都有内部类和局部类的语法和语义
Java中没有友元函数和友元类的概念,严格支持封装,不允许外部方法访问类的私有成员
而C++支持friend关键字,允许外部方法访问类的私有成员,因此不是一种纯面向对象的编程语言
Java中类或interface可以用public修饰,也可以不修饰;而C++类不能修饰
三种访问权限的语义相同,语法略有差别
C++中还有继承权限修饰符,Java则没有
class A: protected B, public C (C++)
class A extends B (Java)
Java有super关键字,指代父类对象,通常被用于调用父类的构造方法或一般方法
C++则没有super关键字
两者都有this,指代当前对象
Java有package的概念,可以将类组织起来,便于打包和部署,也有利于类的安全。C++没有这个概念,一个类可以被任意类访问
Java applet可以被嵌入HTML文档中,然后由Web浏览器下载和执行
Java API有对网络通讯的特别支持
C++则无内置网络功能
C++程序员必须显式地实现动态内存管理,在析构函数中用delete运算符或free( )函数释放对象和其他动态分配的数据空间,否则会造成“内存泄露”
而在Java中,垃圾收集是自动的。当对象的最后一个引用变量被释放掉,这个对象就成为垃圾收集器的候选对象了
因此Java不支持析构函数
finalize( )方法主要被用来释放先前打开的非内存资源,如文件句柄
Java源代码被编译成字节码(.class文件),字节码是一种只有JVM才能识别的二进制低级代码,它与具体的处理器无关,要由安装在OS之上的JVM解释执行,转换成相应平台的机器码,因此Java是体系结构中立和跨平台的
而C++直接被编译成底层平台的二进制机器码,由CPU执行,是平台相关的
因此,当解释执行时,Java程序速度更慢
Java语言支持多线程,允许并发线程的同步与互斥操作
C++则没有这种内在机制
㈨ 关于java处理图像占用空间大的相关问题~~
看你的图像的色彩模型,
如果是RGB每个像素24bit,3个字节,占用1024*1024*3=3MiB内存
如果ARGB,一般都是每个像素32bit,4个字节,占用1024*1024*4=4MiB内存(Java也常用这个交换)
如果灰度模型,每个像素8bit,占用1MiB内存
如果2值化,每个像素1bit,占用1024*1024/8=128KiB内存,这在无压缩情况下容量最小。
常见视频I420模型,每个像素6bit,1024*1024能用768KiB获得近似真彩的效果.
图像处理在内存中就是这样,如果想空间小,就要增加运算时间使用压缩算法和调整色彩模型。