计算机 考研 面试题目大全
8086/8088的内部中断主要有5种。
(1)除法错中断
(2)单步中断
(3)断点中断
(4)溢出中断
(5)用户自定义的软件中断
在8086/8088内存的开始1K 字节建立了一个,每个由4个字节组成,低两位是IP 值,高两位是CS 值,这个CS:IP地址表示当相应中断发生时,程序的入口地址。
关闭中断标识,重要数据入栈,处理中断服务功能(你要实现的功能),数据出栈,恢复中断标识,开中断.
ExtJS
不同其他的javaScript 库,ExtJS为您的开发夯实了基础,只
需几行代码,你就可以制作出丰富的用户界面。
Ext 库是对雅虎YUI 的一个拓展,提供了它所不支持的特性:良好的API,真实的控件。虽然YUI 致力于用户界面,但是它却没有提供许多有用的功能。
Ext 的产生源自于开发者、开源贡献者们将YUI 扩展成一个强大的客户端应用程序库的努力。Ext 提供了一个简单丰富的用户界面,如同桌面程序一般。这使得开发者能够
把精力更多的转移到实现应用的功能上。Ext 官网上的示例会让你知道它是如何的不可思议:Ext 让通过如下的方式来让web 应用的开发变的十分简单:
•提供简单的,跨浏览器的控件,如:窗口、表格、表单。这些组件都是能够适应市场上的主流浏览器的。我们不需要做任何改动。
•用户是通过EventManager 来和浏览器做交互的,相应的事件有:用户的键盘输入,鼠标击打,浏览器监听(窗口改变大小,改变字体)等等;
•在和用户交互时不需要刷新页面,一切在后台进行。它允许你从服务器通过AJAX 来获取或者提交数据并且在第一时间执行你的反馈。
JavaEE
MVC:开始是存在于程序中的,M是指业务模型,V是指,C则是,使用MVC 的目的是将M 和V 的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用来表示。存在的目的则是确保M 和V 的同步,一旦M 改变,V应该同步更新。[1-2]
Hibernate 是一个实现的工具项目,它可以被嵌入到J2EE 服务器中使用,也可以直接从调用,通常的使用方式是将Hibernate 嵌入到Tomcat 和JBoss 等服务器中使用。
简单的说就是在表的记录与与表对应的的实例之间进行转换。
Spring:Spring表示是一个开源框架,是为了解决企业复杂性。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE 开发提供集成的框架。Spring 使用基本的JavaBean 来完成以前只可能由EJB 完成的事情。然而,Spring的用途不仅限于端的开发。从简单性、可测试性和松耦合的角度而言,任何Java 应用都可以从Spring 中受益。
◆目的:解决企业应用开发的复杂性
◆功能:使用基本的JavaBean 代替EJB,并提供了更多的企业功能
◆范围:任何Java 应用
简单来说,Spring是一个轻量级的()和面向切面()的框架。◆轻量——从大小与开销两方面而言Spring 都是轻量的。完整的Spring 可以在一个大小只有1MB 多的JAR 文件里发布。并且Spring 所需的处理开销也是微不足道的。此外,Spring 是非侵入式的:典型地,Spring应用中的不依赖于Spring 的特定类。
◆——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC 与JNDI 相反——不是从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
◆面向切面——Spring提供了的丰富支持,允许通过分离应用的业务与级(例如审计(auditing)和(transaction)管理)进行的开发。只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或支持。
◆容器——Spring包含并管理的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean 如何被创建——基于一个可配置(prototype),你的bean 可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB 容器,它们经常是庞大与笨重的,难以使用。
◆——Spring可以将简单的配置、组合成为复杂的应用。在Spring 中,被声明式地组合,典型地是在一个XML 文件里。Spring 也提供了很多基础功能(、持久化框架集成等等),将应用逻辑的开发留给了你。
◆MVC——Spring的作用是整合,但不仅仅限于整合,Spring框架可以被看做是一个企业解决方案级别的框
架。客户端发送请求,服务器控制器(由DispatcherServlet 实现的)完成请求的转发,控制器调用一个用于映射的类HandlerMapping,该类用于将请求映射到对应的处理器来处理请求。HandlerMapping将请求映射到对应的处理器Controller(相当于Action)在Spring 当中如果写一些处理器组件,一般实现Controller 接口,在Controller 中就可以调用一些Service 或DAO 来进行数据操作ModelAndView 用于存放从DAO 中取出的数据,还可以存放响应视图的一些数据。如果想将处理结果返回给用户,那么在Spring 框架中还提供一个视图组件ViewResolver,该组件根据Controller 返回的标示,找到对应的视图,将响应response 返回给用户。
所有Spring 的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring 中的各种模块提供了基础支持。
JAVAEE:是一套全然不同于传统应用开发的技术架构,包含许多组件,主要可简化且规范应用系统的开发与部署,进而提高可移植性、安全与再用价值。核心是一组技术规范与指南,其中所包含的各类组件、服务架构及技术层次,均有共同的标准及规格,让各种依循架构的不同平台之间,存在良好兼容性,解决过去企业后端使用的信息产品彼此之间无法兼容,企业内部或外部难以互通的窘境。
Struts:struts是开源软件。使用Struts 的目的是为了帮助我们减少在运用MVC 设计模型来开发Web 应用的时间。如果我们想混合使用Servlets 和JSP 的优点来建立可扩展的应用,struts 是一个不错的选择。它采用MVC 模式,能够很好地帮助java 开发者利用J2EE 开发Web 应用。和其他的java 架构一样,Struts也是面向对象设计,将MVC 模式"分离
显示逻辑和业务逻辑"的能力发挥得淋漓尽致。Structs 框架的核心是一个弹性的控制层,基于如Java Servlets,JavaBeans,ResourceBundles 与XML 等标准技术,以及Jakarta Commons 的一些类库。
JSON:JSON(JavaScriptObject Notation) 是一种轻量级的数据交换格式。它基于JavaScript (StandardECMA-2623rd Edition -December 1999)的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C 语言家族的习惯(包括C, C++,C#,Java, JavaScript, Perl, Python 等)。这些特性使JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。JSON可以将JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从Web 客户机传递给服务器端程序。
AJAX:在基于数据的应用中,用户需求的数据如联系人列表,可以从独立于实际网页的服务端取得并且可以被动态地写入网页中,给缓慢的Web 应用体验着色使之像应用一样。Ajax的核心是JavaScript 对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript 向服务器提出请求并处理响应,而不阻塞用户。不是一种新的语言,而是一种用于创建更好更快以及交互性更强的Web 应用程序的技术。
对计算机科学的认识
本专业是硬件与相结合、面向系统、侧重应用的宽口径专业。通过基础教学与专业训练,培养基础知识扎实、知识面宽、工程实践能力强,具有开拓创新意识,在领域从事、教育、开发和应用的高级人才。
当今计算机技术正朝着巨型化、微型化、网络化和智能化方向发展。
当今发展趋势,可以把它分为三维考虑。一维是是向"高"的方向。性能越来越高,速度越来越快,主要表现在计算机的主频越来越高。像前几年我们使用的都是286、386、主频只有几十兆。美国另一项计划的目标是2010年左右推出每秒一千万亿次机(Petaflops计算机),其处理机将采用量子器件,每个处理机每秒100亿次,共用10万个处理机并行。
另一个方向就是向“广”度方向发展,计算机发展的趋势就是无处不在,以至于像“没有计算机一样”。近年来更明显的趋势是网络化与向各个领域的渗透,即在广度上的发展开拓。
第三个方向是向"深"度方向发展,即向信息的智能化发展。网上有大量的信息,怎样把这些的东西变成你想要的知识,这是计算科学的重要课题,同时更加友好。目前计算机"思维"的方式与人类思维方式有很大区别,人机之间的间隔还不小。人类还很难以自然的方式,如语言、手势、表情与计算机打交道,计算机难用已成为阻碍计算机进一步普及的巨大障碍。估计5-10年内手写和口语输入将逐步成为主流的输入方式。手势(特别是手势)和脸部表情识别也已取得较大进展。使人沉浸在的(VirtualReality)技术是近几年来发展较快的技术,21世纪将更加迅速的发展。
1.C 的结构体和C++结构体的区别
1.1C 的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C 的结构体是没有构造函数、析构函数、和this 指针的。
1.2C 的结构体对内部成员变量的访问权限只能是public ,而C++允许public,protected,private 三种。
1.3C 语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
以上都是表面的区别,实际区别就是面向过程和面向对象编程思路的区别:
C 的结构体只是把数据变量给包裹起来了,并不涉及算法。
而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。
C 语言中是没有类的概念的,但是C 语言可以通过结构体内创建函数指针实现面向对象思想。
2.C++的结构体和C++类的区别
2.1C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。
2.2C++结构体的继承默认是public,而c++类的继承默认是private。
1.动态链接库与静态链接库的区别。
1.1静态链接库作为代码的一部分,在编译时被链接。
1.2动态链接库有两种使用方式:
一种是静态加载,即在应用程序启动时被加载;
一种是动态加载,即是该动态链接库在被使用时才被应用程序加载。
2.动态链接库和COM 组件的区别
2.1动态链接库的表现形式只能是dll[变态该名的除外],COM 组件的表现形式可以是dll 也可以是exe。
注:其实字体、驱动等也算是动态链接库的一种,这里略去...
2.2动态链接库的生成和编译器及系统相关,在Windows/Linux下系统,需要分别编译才能使用。
COM 组件是二进制编码,在Windows 和Linux 下可以直接使用,不需要重新
编译。
2.3COM 组件是按照COM 规范实现的dll 或者exe;动态链接库是一个可以导出函数的函数集合。
2.4动态链接库只能在本机被调用,COM组件支持分布式使用。
MAC 地址是不能通过IP 来查询的!
局域网如何根据ip 查mac
cmd
ping ip 地址
arp -a
即使ping 不通,只要他机开着,都可以看到MAC!!
显示和修改“(ARP)”缓存中的项目。ARP缓存中包含一个或多个表,它们用于存储IP 地址及其经过解析的或。计算机上安装的每一个或都有自己单独的表。如果在没有参数的情况下使用,则arp 命令将显示帮助信息。
-a[InetAddr][-N IfaceAddr]
显示所有接口的当前ARP 缓存表。要显示特定IP 地址的ARP 缓存项,请使用带有InetAddr 参数的arp -a,此处的InetAddr 代表IP 地址。如果未指定InetAddr,则使
用第一个适用的接口。要显示特定接口的ARP 缓存表,请将-N IfaceAddr 参数与-a 参数一起使用,此处的IfaceAddr 代表指派给该接口的IP 地址。-N参数区分大小写。BIOS
BIOS 设置是在BIOS 中的,BIOS芯片是上一块长方形或正方形芯片,只有在开机时才可以进行设置。
BIOS 是:直译过来后中文名称就是"基本输入输出系统"。其实,它是一组固化到内上一个上的,它保存着计算机最重要的基本输入输出的程序、系统设置信息、开机后自检程序和系统自启动程序。其主要功能是为提供最底层的、最直接的设置和控制。
数学中的梯度是什么意思?
在向量微积分中,标量场的梯度是一个向量场。标量场中某一点上的梯度指向标量场增长最快的方向,梯度的长度是这个最大的变化率。更严格的说,从欧氏空间Rn 到R 的函数的梯度是在Rn 某一点最佳的线性近似。在这个意义上,梯度是雅戈比矩阵的一个特殊情况。
在单变量的实值函数的情况,梯度只是导数,或者,对于一个线性函数,也就是线的斜率。
梯度一词有时用于斜度,也就是一个曲面沿着给定方向的倾斜程度。可以通过取向量梯度和所研究的方向的点积来得到斜度。梯度的数值有时也被成为梯度。
如果你是问在纯数学中的作用,那就是反映那个量变化的有多剧烈;多元微积分中则还反映在哪个方向上变化最剧烈.
云计算[1]是基于的相关服务的增加、使用和交付模式,通常涉及通过来提供动态易扩展且经常是的资源。定义:“云计算是通过网络提供可伸缩的廉价的分布式计算能力”。
云计算代表了以虚拟化技术为核心、以低成本为目标的动态可扩展网络应用基础设施,是近年来最有代表性的网络计算技术与模式。是:、、、[3]、、等传统和发展融合的产物。
云计算是通过使计算分布在大量的机上,而非本地计算机或远程服务器中,企业的运行将与更相似。这使得企业能够将资源切换到需要的应用上,根据需求访问和。
好比是从古老的单台发电机模式转向了电厂集中供电的模式。它意味着计算能力也可以作为一种商品进行流通,就像煤气、水电一样,取用方便,费用低廉。最大的不同在于,它是通过进行传输的。:的一种,由一群松散耦合的的一个超级,常用来执行一些大型任务;:IT资源的一种打包和计费方式,比如按照计算、存储分别计量费用,像传统的电力等公共设施一样;
算法的时间复杂度
一个花费的时间与算法中语句的执行次数。一个中的语句执行次数称为语句频度或时间频度。记为T(n)。
计算方法
1. 一般情况下,的基本操作重复执行的次数是模块n 的某一个函数f(n),因此,算法的记做:T(n)=O(f(n))
分析:随着模块n 的增大,执行的时间的增长率和f(n)的增长率成正比,所以f(n)越
小,算法的越低,算法的效率越高。
在计算的时候,先找出的基本操作,然后根据相应的各语句确定它的执行次数,再找出T(n)的同(它的同数量级有以下:1,log(2)n,n,nlog(2)n,n的平方,n的三次方,2的n 次方,n!),找出后,f(n)=该数量级,若T(n)/f(n)求极限可得到一常数c,则T(n)=O(f(n))
十种程序设计语言
PASCAL、C、Ada
FORTRAN、BASIC、、Java、C++、Go、Delphi、F#
SQL、PowerBuilder、
static 全局变量与普通的全局变量有什么区别?(外部变量)的说明之前再冠以static 就构成了静态的。本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个,当一个由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出,把改变为后是改变了它的存储方式即改变了它的生存期。把全局变量改变为后是改变了它的作用域,限制了它的使用范围。
static 函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个中说明,要使用这些函数的源文件要包含这个static 全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static 和普通有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static 函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
C 语言中讲讲static 变量和static 函数有什么作用
static 关键字有两种意思,你看上下文来判断
1,表示变量是静态存储变量
表示变量存放在静态存储区.
2,表示该变量是内部连接
(这种情况是指该变量不在任何{}之内,就象全局变量那样,这时候加上static)
,也就是说在其它的.cpp文件中,该变量是不可见的(你不能用).
当static 加在函数前面的时候
表示该函数是内部连接,之在本文件中有效,别的文件中不能应用该函数.
不加static 的函数默认为是全局的.
也就是说在其他的.cpp中只要申明一下这个函数,就可以使用它.
1、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变
量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static 函数与普通函数作用域不同。static函数仅在本文件中使用。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static 全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static 局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static 函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
2、如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C 文件中以static 形式来声明同名全局变量。
可以在不同的C 文件中声明同名的全局变量,前提是其中只能有一个C 文件中对此变量赋初值,此时连接不会出错。
比较两个浮点数大小
在计算机中表示一个,其结构如下:
尾数部分(定点小数)阶码部分(定点整数)
是2的指数形式来表示小数。因此一个小数用来表示,肯定是有误差的。
比如说两个运算过程,它们的结果都是2,但是由于过程不一样,它结果可能有差异,比如说可能一个结果为2,一个结果为1.9999999999.
因此用==号来比较,会得出错误的结果,比较相等的时候,用两个数的相减,当小于一个比较小的值时,就认为相等。
3D 打印打印,即技术的一种,它是一种以文件为基础,运用状或塑料等可粘合,通过逐层的方式来构造物体的。打印通常是采用数字技术材料来的。常在模具制造、等领域被用于制造模型,后逐渐用于一些产品的直接制造,已经有使用这种技术而成的零。该技术在珠宝、鞋类、、建筑、和(AEC)、,、和产
业、、、、以及其他领域都有所应用。[1]
而所谓的与普通打印机工作原理基本相同,只是打印材料有些不同,普通打印机的打印材料是墨水和纸张,而3D 打印机内装有、陶瓷、塑料、砂等不同的“打印材料”,与电脑连接后,通过电脑控制可以把“打印材料”一层层叠加起来,最终把计算机上的蓝图变成实物。通俗地说,3D 打印机是可以“打印”出真实的3D 物体的一种设备,比如打印一个机器人、打印玩具车,打印各种模型,甚至是食物等等。之所以通俗地称其为“打印机”是参照了普通打印机的技术原理,因为分层加工的过程与喷墨打印十分相似。这项打印技术称为立体打印技术。[2]
大数据
分析新数据源的业务需求需要人工智能、数据库、和统计分析知识等很多跨学科的知识。再者,的出现需要条件,第一个条件:海量的数据;第二个条件:计算机技术大数据量的处理能力;第三个条件:计算机的存储与运算能力;第四个条件:交叉学科的发展。
大数据只是的出现的一个条件。
更为复杂的新数据已经出现,而且生成的速度达到了前所未有的程度
社交网络数据、网络日志、存档数据和传感器数据都属于人们在分析中关注的新数据源尽管传统环境不断发展,但如今出现了许多更为复杂的新数据类型,企业需要分析这些数据类型,以便充实其已知信息。此外,这些新数据的生成速度远远超过了以往的纪录。
客户和潜在客户正在社交网络和评论网站中创建大量的新数据。此外,在线新闻项目、气象数据、竞争对手网站内容,甚至是数据市场如今都已经成为可供企业使用的候选数据源。在企业内部,随着客户转变为以在线渠道作为开展商业交易及与企业互动的首选方法,网络日志也在不断增加。分析所用的存档数据再次增多,为监测和优化业务运营而部署的传感器网络和机器数量也越来越多。结果就生成了大量新数据源、快速增加的数据量和迅速增加的新数据流,需要分析所有这些新数据。
在信息量如此庞大的背景下,为找寻关键问题的答案,现在的企业战略对于信息管理和利用能力的依赖性更胜于以往。
伴随着井喷式的数据增长,孤立的数据存储是造成信息管理和集成成本激增的主要原因。面对着分散于不同数据库的孤立数据,企业主管无法确保自己能够全面掌握客户、产品和供应商的情况。孤立的信息同样也令遵守行业或政府法规的难度加大。
在信息集成战略和技术的帮助下,能够在正确时间从任意来源检索数据,编排格式后再提供给企业内外的任意目标。信息集成能够帮助企业执行许多关键任务,其中包括将多个来源的数据加载到仓库当中,整合应用程序实例,以及将不同部门和分部的信息关联起来。通过将企业信息整合成单一来源(不论信息存储于什么位置),企业能够快速处理信息,缩短停机时间,减少客户服务问题,并在尽量不影响性能的情况下分配信息。
IBM 信息集成解决方案用于集成及转化数据和内容,进而提供权威、一致、及时、完整的信息,并且在数据的整个生命周期内控制数据质量。其近线性的无缝扩展能力以及以元数据为驱动的设计能够帮助企业将不同数据库统一成单一的整合信息库,以及识别和更正不准确或冗余的数据。
给你解释一下这些术语::就是个炒得很热的商业概念,其实说白了就是将计算任务转移到服务器端,用户只
需要个显示器就行了,不过服务器的计算资源可以。当然,要想大规模,这里还有些问题,特别是隐私保护问题。:说白了就是数据太多了。如今几兆的数据在20年前也是。但如今所说的特殊在哪呢?如今的问题是数据实在是太多了,这已经超过了的处理能力(区别与),所以对于大数据我们不得不用一些折衷的办法(比如),就是说没必要所有数据都需要,实际上有效数据很有限,用的方法把这些有限的知识提取出来就行了。·此外,数据,也是解决大数据问题的一些策略。:从数据中提取潜在知识,这些知识可以描述或者预测数据的特性。有代表性的数据挖掘任务包括分析、、等,这些你在任一本数据挖掘教材都可以了解。下面我说说和大数据的区别:数据挖掘只是大的一个方法。所说的大数据,或者如今商业领域所说的大数据,实际上指的就是数据挖掘,其实真正所谓大数据,或者Science 杂志中提到的大数据,或者提出的大数据,我的理解是,这些都远远大于数据挖掘的范畴,当然数据挖掘是其中很重要的一个方法。真正目的是如何将大数据进行。:这个词很虚,泛指了一大类。重点是学习这个词,如果想让计算机,目前绝大多数方法都采用了的方法。所以在科研界,只要是采用了这种并不断逼近的策略,一般都可以归到的范畴。此外,所谓学习,肯定要知道学什么,这就是所谓训练集,从训练集数据中计算机要学到其中的某个一般规律,然后用一些别的数据(即测试集)来看看学得好不好,之后才能用于实际应用。所以,选取合适的训练集也是个学问。:意思就是模式的识别。模式多种多样,可以是语言,可以是图像,可以是事物一这个词我是觉得有点虚,倒是具体的人脸、声音识别等,这些倒是挺实在的。也许是我不太了解吧。
另外说说你的其他问题。
传统不包括数据挖掘。对于这块我不是很了解,不过可以肯定的是,传统分析都有一定的分析方向,比如我就想知道这两个商品的关联情况,那数据库就行了。数据挖掘虽说有些历史,不过也挺时髦的,它是自动将那些关联程度大的商品告诉你,这期间不需要用户指定的具体对象。
如果想应对,数据挖掘这门课是少不了的。此外对数据库,特别是、,最好了解点。至于和,这些总的来说和数据挖掘关系不太大,除了一些特殊的领域外。
总之,概念挺热,但大数据还很不成熟,无论从研究上还是上。我目前在作大数据背景下的算法研究,说实话,目前基本没有拓展性非常强的算法,所以未来大数据的发展方向,我也挺迷茫。
PS:将数据挖掘应用于商业,最最重要的就是如何确定挖掘角度,这需要你对具体应用的
领域知识非常了解,需要你有非常敏锐的眼光。至于数据挖掘的具体算法,这些就交给我们专门搞研究的吧!(对算法的理解也很重要,这可以把算法拓展到你的应用领域)直方图
灰度直方图的定义
灰度直方图是灰度级的函数,描述图像中该灰度级的像素个数(或该灰度级像素出现的频率):其横坐标是灰度级,纵坐标表示图像中该灰度级出现的个数(频率)。灰度直方图是数字图像中最简单且有用的工具,这一篇主要总结OpenCV 中直方图CvHistogram 的结构和应用。
灰度直方图的定义
灰度直方图是灰度级的函数,描述图像中该灰度级的像素个数(或该灰度级像素出现的频率):其横坐标是灰度级,纵坐标表示图像中该灰度级出现的个数(频率)。
一维直方图的结构表示为
高维直方图可以理解为图像在每个维度上灰度级分布的直方图。常见的是二维直方图。如红-蓝直方图的两个分量分别表示红光图像的灰度值和蓝光图像灰度值的函数。其图像坐标(Dr,Db)处对应在红光图像中具有灰度级Dr 同时在蓝光图像中具有灰度级Db 的像素个数。这是基于多光谱——每个像素有多个变量——的数字图像,二维中对应每个像素统计个变量。
OpenCV 中的直方图CvHistogram
注意我们在上面理解直方图的意义时更多把他想象成一幅“图”,继而理解图中横坐标,纵坐标的意义。而在OpenCV 中,应该更多把直方图看做“数据结构”来理解。
OpenCV 中用CvHistogram 表示多维直方图():
[cpp]typedef struct CvHistogram
{
int type;
CvArr*bins; //存放每个灰度级数目的数组指针
float thresh[CV_MAX_DIM][2];//均匀直方图
float**thresh2; //非均匀直方图
CvMatND mat; //直方图数组的内部数据结构
}
CvHistogram;
这个结构看起来简单(比IplImage*元素少多了。。。)其实并不太好理解。
第一个成员type 用来指定第二个成员bins 的类型。OpenCv 中常见到CvArr*的接口,可以用以指定诸如CvMat、CvMatND、IplImage的类型,其实CvArr*的是一个指向void 的指针。在函数内部有时需要得到确切的指向类型,这就需要type 来指定。
thresh 用来指定统计直方图分布的上下界。比如[0255]表示用来统计图像中像素分别在灰度级[0255]区间的分布情况,CV_MAX_DIM对应直方图的维数,假如设定二维红-蓝直方图的thresh 为[0255;100200],就是分别统计红色图像灰度级在[0255]以及蓝色图像在灰度级[100200]的分布情况。
thresh 用以指定均匀直方图的分布,我们按每个像素理解自然是“均匀分布”,其实也可以统计像素在几个区间的分布。如果统计像素在2个区间的分布,则对应[0255]的上下界,均匀分布统计的区间即[0127][127255]分布的概率,这也是为什么thresh 第二个维数默认为2——会自动均分上下界;而thresh2指定非均匀的分布,这就需要指定每个区间的上下界,如果要统计直方图在区间(0,10,100,255)的分布,那需要指定thresh2的一个维度为[010100255],所以用float**形式表示。
mat 简单说就是存储了直方图的信息,即我们统计的直方图分布概率。
创建直方图cvCreateHist()
OpenCV 中用cvCreateHist()创建一个直方图:
[cpp]CvHistogram*cvCreateHist(
int dims, //直方图维数
int*sizes,//直翻图维数尺寸
int type, //直方图的表示格式
float**ranges=NULL,//图中方块范围的数组
int uniform=1//归一化标识
);
size 数组的长度为dims,每个数表示分配给对应维数的bin 的个数。如dims=3,则size 中用[s1,s2,s3]分别指定每维bin 的个数。
type 有两种:CV_HIST_ARRAY意味着直方图数据表示为多维密集数组CvMatND; CV_HIST_TREE意味着直方图数据表示为多维稀疏数组CvSparseMat。
ranges 就是那个复杂的不好理解的thresh 的范围,他的内容取决于uniform 的值。uniform 为0是均匀的,非0时不均匀。
计算图像直方图的函数为CalcHist():
[cpp]void cvCalcHist(
IplImage**image, //输入图像(也可用CvMat**)
CvHistogram*hist, //直方图指针
int accumulate=0,//累计标识。如果设置,则直方图在开始时不被清
零。
const CvArr*mask=NULL//操作mask, 确定输入图像的哪个象素被计数
);
要注意的是这个函数用来计算一张(或多张)单通道图像的直方图,如果要计算多通道,则用这个函数分别计算图像每个单通道。
实践:一维直方图
下面实践一下用OpenCV 生成图像的一维直方图
[cpp]int main()
{
IplImage *src=cvLoadImage("baboon.jpg");
IplImage*gray_plane=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,gray_plane,CV_BGR2GRAY);
int hist_size=256; //直方图尺寸
int hist_height=256;
float range[]={0,255};//灰度级的范围
float*ranges[]={range};
//创建一维直方图,统计图像在[0255]像素的均匀分布
CvHistogram*gray_hist=cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);//计算灰度图像的一维直方图
cvCalcHist(&gray_plane,gray_hist,0,0);
//归一化直方图
cvNormalizeHist(gray_hist,1.0);
int scale =2;
//创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数(*scale)IplImage*hist_image=cvCreateImage(cvSize(hist_size*scale,hist_height),8,3);cvZero(hist_image);
//统计直方图中的最大直方块
float max_value=0;
cvGetMinMaxHistValue(gray_hist,0,&max_value,0,0);
//分别将每个直方块的值绘制到图中
for(inti=0;i
{
float bin_val=cvQueryHistValue_1D(gray_hist,i);//像素i 的概率
int intensity =cvRound(bin_val*hist_height/max_value);//要绘制的高度
cvRectangle(hist_image,
cvPoint(i*scale,hist_height-1),
cvPoint((i+1)*scale-1, hist_height-intensity),
CV_RGB(255,255,255));
}
cvNamedWindow("GraySource", 1);
cvShowImage("GraySource",gray_plane);
cvNamedWindow("H-S Histogram", 1);
cvShowImage("H-S Histogram", hist_image);
cvWaitKey(0);
}
试验结果:
对应的,我们可以用一样的思路统计每个通道的直方图,并绘制图像每个通道像素的分布:实践:二维直方图
我们也可以结合OpenCV 的例子生成二维直方图:
[cpp]IplImage*r_plane=cvCreateImage(cvGetSize(src),8, 1);
IplImage*g_plane=cvCreateImage(cvGetSize(src),8, 1);
IplImage*b_plane=cvCreateImage(cvGetSize(src),8, 1);
IplImage*planes[]={r_plane,g_plane};
//将HSV 图像分离到不同的通道中
cvCvtPixToPlane(src, b_plane,g_plane,r_plane,0);
//生成二维直方图数据结构
int r_bins=256,b_bins=256;
CvHistogram*hist;
{
int hist_size[]={r_bins,b_bins};
float r_ranges[]={0, 255};//hue is [0,180]
float b_ranges[]={0, 255};
float*ranges[]={r_ranges,b_ranges};
hist =cvCreateHist(2, hist_size,CV_HIST_ARRAY,ranges, 1);
}
//计算一张或多张单通道图像image(s)的直方图
cvCalcHist(planes, hist, 0, 0);
刚才的图我们是对应每个横坐标绘制纵坐标的直方块,二维的图需要绘制每个点:
[cpp]for(int h =0; h
for(int s =0; s
float bin_val=cvQueryHistValue_2D(hist, h, s ); //查询直方块的值
int intensity =cvRound(bin_val*255/max_value);
cvRectangle(hist_img,
cvPoint(h*scale,s*scale),
cvPoint((h+1)*scale-1, (s+1)*scale-1),
CV_RGB(intensity,intensity,intensity),
CV_FILLED);
}
}
最终生成二维直方图:
直方图的应用以后再讨论。前面介绍了,现在来尝试直方图的应用。
直方图均衡化
直方图均衡化(HistogramEqualization)是直方图最典型的应用,是图像点运算的一种。对于一幅输入图像,通过运算产生一幅输出图像,点运算是指输出图像的每个像素点的灰度
即在每个灰度级上都具有相同的象素点数过程。从分布图上的理解就是希望原始图像中y 轴的值在新的分布中尽可能的展开。变换过程是利用累积分布函数对原始分布进行映射,生成新的均匀拉伸的分布。因此对应每个点的操作是寻找原始分布中y 值在均匀分布中的位置,如下图是理想的单纯高斯分布映射的示意图:
(图片来源:《LearnningOpenCV》p189)
OpenCV 中的cvEqualizeHist
OpenCV 中有灰度直方图均衡化的函数cvEqualizeHist,接口很明朗:
[cpp]void cvEqualizeHist(const CvArr*src, CvArr*dst );
注意此函数只能处理单通道的灰色图像,对于彩色图像,我们可以把每个信道分别均衡化,再Merge 为彩色图像。
实践:图像直方图均衡化
[cpp]int main()
{
IplImage *image=cvLoadImage("baboon.jpg");
//显示原图及直方图
myShowHist("Source",image);
IplImage*eqlimage=cvCreateImage(cvGetSize(image),image->depth,3);//分别均衡化每个信道
IplImage*redImage=cvCreateImage(cvGetSize(image),image->depth,1);IplImage*greenImage=cvCreateImage(cvGetSize(image),image->depth,1);
IplImage*blueImage=cvCreateImage(cvGetSize(image),image->depth,1);cvSplit(image,blueImage,greenImage,redImage,NULL);
cvEqualizeHist(redImage,redImage);
cvEqualizeHist(greenImage,greenImage);
cvEqualizeHist(blueImage,blueImage);
//均衡化后的图像
cvMerge(blueImage,greenImage,redImage,NULL,eqlimage);
myShowHist("Equalized",eqlimage);
}
原始图像及灰度直方图如下:
均衡化后的直方图:
直方图匹配
直方图匹配又叫直方图规定化(HistogramNormalization/Matching)是指对一副图像进行变换,使其直方图与另一幅图像的直方图或特定函数形式的直方图进行匹配。应用场景如
不同光照条件下的两幅图像,我们可以在比较两幅图像前先进行匹配变化。
参考shlkl99上传的直方图匹配,将图像规定化为高斯分布函数。
[cpp]//将图像与特定函数分布histv[]匹配
void myHistMatch(IplImage*img,doublehistv[])
{
int bins =256;
int sizes[]={bins};
CvHistogram *hist=cvCreateHist(1,sizes,CV_HIST_ARRAY);
cvCalcHist(&img,hist);
cvNormalizeHist(hist,1);
double val_1=0.0;
double val_2=0.0;
uchar T[256]={0};
double S[256]={0};
double G[256]={0};
for (intindex =0; index
{
val_1+=cvQueryHistValue_1D(hist,index);
val_2+=histv[index];
G[index]=val_2;
S[index]=val_1;
}
double min_val=0.0;
int PG =0;
for (int i =0; i
{
min_val=1.0;
for(intj =0;j
{
if((G[j]-S[i])=0)
{
min_val=(G[j]-S[i]);
PG =j;
}
}
T[i]=(uchar)PG;
}
uchar *p=NULL;
for (intx =0; xheight;++x)
{
p =(uchar*)(img->imageData+img->widthStep*x);
for (inty =0; ywidth;++y)
{
p[y]=T[p[y]];
}
}
}
//生成高斯分布
void GenerateGaussModel(doublemodel[])
{
double m1,m2,sigma1,sigma2,A1,A2,K;
m1=0.15;
m2=0.75;
sigma1=0.05;
sigma2=0.05;
A1=1;
A2=0.07;
K =0.002;
double c1=A1*(1.0/(sqrt(2*CV_PI))*sigma1);
double k1=2*sigma1*sigma1;
double c2=A2*(1.0/(sqrt(2*CV_PI))*sigma2);
double k2=2*sigma2*sigma2;
double p =0.0,val=0.0,z =0.0;
for (intzt =0;zt
{
val =K +c1*exp(-(z-m1)*(z-m1)/k1)+c2*exp(-(z-m2)*(z-m2)/k2);
model[zt]=val;
p =p +val;
z =z +1.0/256;
}
for (inti =0;i
{
model[i]=model[i]/p;
}
}
实践:直方图匹配
对示例图片每个信道分别进行匹配处理
对比直方图
OpenCV 中提供了cvCompareHist 函数用以对比两个直方图的相似度:
[cpp]double cvCompareHist(
const CvHistogram*hist1, //直方图1
const CvHistogram*hist2, //直方图2
int method//对比方法
);
method 有CV_COMP_CORREL,CV_COMP_CHISQR,CV_COMP_INTERSECT,CV_COMP_BHATTACHARYYA四种方法,对应公式如下:
实践:对比不同光照条件的两幅图像直方图直方图的对比主要用以判断两幅图像的匹配度,我们试验以下两幅图像直方图对比的结果:
[cpp]int main()
{
IplImage *image=cvLoadImage("myhand1.jpg");
IplImage *image2=cvLoadImage("myhand2.jpg");
int hist_size=256;
float range[]={0,255};
float*ranges[]={range};
IplImage*gray_plane=cvCreateImage(cvGetSize(image),8,1);
cvCvtColor(image,gray_plane,CV_BGR2GRAY);
CvHistogram*gray_hist=cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);cvCalcHist(&gray_plane,gray_hist,0,0);
IplImage*gray_plane2=cvCreateImage(cvGetSize(image2),8,1);
cvCvtColor(image2,gray_plane2,CV_BGR2GRAY);
CvHistogram*gray_hist2
cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
cvCalcHist(&gray_plane2,gray_hist2,0,0);
//相关:CV_COMP_CORREL
//卡方:CV_COMP_CHISQR
//直方图相交:CV_COMP_INTERSECT
//Bhattacharyya距离:CV_COMP_BHATTACHARYYA
double
com=cvCompareHist(gray_hist,gray_hist2,CV_COMP_BHATTACHARYYA);
cout
}=
输出结果为:0.396814
cvCompareHist 的结果为【0,1】的浮点数,越小表示两幅图匹配度越高,0.0时两幅图精确匹配。(可以试验两幅完全一样的图即为0.0)。
针对上面两幅图,我们分别先进行直方图匹配变化:
之后使用cvCompareHist()对比两幅图像的直方图,输出结果为
0.267421
表明两幅图的匹配度变高了。
注意method 用不同的方法对比结果是不同的。
应用
通过对比我们可以设置EMD 的阈值来判定皮肤或手的ROI。《LearnningOpenCV》后面有相应的练习题:收集手的肤色直方图,对比室内,室外手的直方图的EMD 距离,利用这些测量值设置一个距离阈值。
a.利用该阈值检测第三幅图(如室外阴影),看能能否很好的检测肤色直方图。
b.随机选择不是肤色的背景块直方图,观测EMD 变化,试验与真实肤色对比时能否很好的拒绝背景。
如上也即是直方图对比可以应用的场景。