1.正常曝光的照片
2.曝光不足的照片
3.曝光过渡的照片
4.反差过低的照片
5.反差过高的照片
鲁棒是Robust的音译,也就是健壮和强壮的意思。
鲁棒性(robustness)就是系统的健壮性。它是在异常和危险情况下系统生存的关键。比如说,计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下,能否不死机、不崩溃,就是该软件的鲁棒性。所谓“鲁棒性”,是指控制系统在一定(结构,大小)的参数摄动下,维持某些性能的特性。根据对性能的不同定义,可分为稳定鲁棒性和性能鲁棒性。以闭环系统的鲁棒性作为目标设计得到的固定控制器称为鲁棒控制器。
卡尔曼滤波器 – Kalman Filter
1. 什么是卡尔曼滤波器
(What is the Kalman Filter?)
在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”。跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人!
卡尔曼全名Rudolf Emil Kalman,匈牙利数学家,1930年出生于匈牙利首都布达佩斯。1953,1954年于麻省理工学院分别获得电机工程学士及硕士学位。1957年于哥伦比亚大学获得博士学位。我们现在要学习的卡尔曼滤波器,正是源于他的博士论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》(线性滤波与预测问题的新方法)。如果对这编论文有兴趣,可以到这里的地址下载: http://www.cs.unc.edu/~welch/media/pdf/Kalman1960.pdf。
简单来说,卡尔曼滤波器是一个“optimal recursive data processing algorithm(最优化自回归数据处理算法)”。对于解决很大部分的问题,他是最优,效率最高甚至是最有用的。他的广泛应用已经超过30年,包括机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。近年来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。
2.卡尔曼滤波器的介绍
(Introduction to the Kalman Filter)
为了可以更加容易的理解卡尔曼滤波器,这里会应用形象的描述方法来讲解,而不是像大多数参考书那样罗列一大堆的数学公式和数学符号。但是,他的5条公式是其核心内容。结合现代的计算机,其实卡尔曼的程序相当的简单,只要你理解了他的那5条公式。
在介绍他的5条公式之前,先让我们来根据下面的例子一步一步的探索。
假设我们要研究的对象是一个房间的温度。根据你的经验判断,这个房间的温度是恒定的,也就是下一分钟的温度等于现在这一分钟的温度(假设我们用一分钟来做时间单位)。假设你对你的经验不是100%的相信,可能会有上下偏差几度。我们把这些偏差看成是高斯白噪声(White Gaussian Noise),也就是这些偏差跟前后时间是没有关系的而且符合高斯分配(Gaussian Distribution)。另外,我们在房间里放一个温度计,但是这个温度计也不准确的,测量值会比实际值偏差。我们也把这些偏差看成是高斯白噪声。
好了,现在对于某一分钟我们有两个有关于该房间的温度值:你根据经验的预测值(系统的预测值)和温度计的值(测量值)。下面我们要用这两个值结合他们各自的噪声来估算出房间的实际温度值。
假如我们要估算k时刻的是实际温度值。首先你要根据k-1时刻的温度值,来预测k时刻的温度。因为你相信温度是恒定的,所以你会得到k时刻的温度预测值是跟k-1时刻一样的,假设是23度,同时该值的高斯噪声的偏差是5度(5是这样得到的:如果k-1时刻估算出的最优温度值的偏差是3,你对自己预测的不确定度是4度,他们平方相加再开方,就是5)。然后,你从温度计那里得到了k时刻的温度值,假设是25度,同时该值的偏差是4度。
由于我们用于估算k时刻的实际温度有两个温度值,分别是23度和25度。究竟实际温度是多少呢?相信自己还是相信温度计呢?究竟相信谁多一点,我们可以用他们的covariance来判断。因为Kg^2=5^2/(5^2+4^2),所以Kg=0.78,我们可以估算出k时刻的实际温度值是:23+0.78*(25-23)=24.56度。可以看出,因为温度计的covariance比较小(比较相信温度计),所以估算出的最优温度值偏向温度计的值。
现在我们已经得到k时刻的最优温度值了,下一步就是要进入k+1时刻,进行新的最优估算。到现在为止,好像还没看到什么自回归的东西出现。对了,在进入k+1时刻之前,我们还要算出k时刻那个最优值(24.56度)的偏差。算法如下:((1-Kg)*5^2)^0.5=2.35。这里的5就是上面的k时刻你预测的那个23度温度值的偏差,得出的2.35就是进入k+1时刻以后k时刻估算出的最优温度值的偏差(对应于上面的3)。
就是这样,卡尔曼滤波器就不断的把covariance递归,从而估算出最优的温度值。他运行的很快,而且它只保留了上一时刻的covariance。上面的Kg,就是卡尔曼增益(Kalman Gain)。他可以随不同的时刻而改变他自己的值,是不是很神奇!
下面就要言归正传,讨论真正工程系统上的卡尔曼。
3. 卡尔曼滤波器算法
(The Kalman Filter Algorithm)
在这一部分,我们就来描述源于Dr Kalman 的卡尔曼滤波器。下面的描述,会涉及一些基本的概念知识,包括概率(Probability),随即变量(Random Variable),高斯或正态分配(Gaussian Distribution)还有State-space Model等等。但对于卡尔曼滤波器的详细证明,这里不能一一描述。
首先,我们先要引入一个离散控制过程的系统。该系统可用一个线性随机微分方程(Linear Stochastic Difference equation)来描述:
X(k)=A X(k-1)+B U(k)+W(k)
再加上系统的测量值:
Z(k)=H X(k)+V(k)
上两式子中,X(k)是k时刻的系统状态,U(k)是k时刻对系统的控制量。A和B是系统参数,对于多模型系统,他们为矩阵。Z(k)是k时刻的测量值,H是测量系统的参数,对于多测量系统,H为矩阵。W(k)和V(k)分别表示过程和测量的噪声。他们被假设成高斯白噪声(White Gaussian Noise),他们的covariance 分别是Q,R(这里我们假设他们不随系统状态变化而变化)。
对于满足上面的条件(线性随机微分系统,过程和测量都是高斯白噪声),卡尔曼滤波器是最优的信息处理器。下面我们来用他们结合他们的covariances 来估算系统的最优化输出(类似上一节那个温度的例子)。
首先我们要利用系统的过程模型,来预测下一状态的系统。假设现在的系统状态是k,根据系统的模型,可以基于系统的上一状态而预测出现在状态:
X(k|k-1)=A X(k-1|k-1)+B U(k) ……….. (1)
式(1)中,X(k|k-1)是利用上一状态预测的结果,X(k-1|k-1)是上一状态最优的结果,U(k)为现在状态的控制量,如果没有控制量,它可以为0。
到现在为止,我们的系统结果已经更新了,可是,对应于X(k|k-1)的covariance还没更新。我们用P表示covariance:
P(k|k-1)=A P(k-1|k-1) A’+Q ……… (2)
式(2)中,P(k|k-1)是X(k|k-1)对应的covariance,P(k-1|k-1)是X(k-1|k-1)对应的covariance,A’表示A的转置矩阵,Q是系统过程的covariance。式子1,2就是卡尔曼滤波器5个公式当中的前两个,也就是对系统的预测。
现在我们有了现在状态的预测结果,然后我们再收集现在状态的测量值。结合预测值和测量值,我们可以得到现在状态(k)的最优化估算值X(k|k):
X(k|k)= X(k|k-1)+Kg(k) (Z(k)-H X(k|k-1)) ……… (3)
其中Kg为卡尔曼增益(Kalman Gain):
Kg(k)= P(k|k-1) H’ / (H P(k|k-1) H’ + R) ……… (4)
到现在为止,我们已经得到了k状态下最优的估算值X(k|k)。但是为了要另卡尔曼滤波器不断的运行下去直到系统过程结束,我们还要更新k状态下X(k|k)的covariance:
P(k|k)=(I-Kg(k) H)P(k|k-1) ……… (5)
其中I 为1的矩阵,对于单模型单测量,I=1。当系统进入k+1状态时,P(k|k)就是式子(2)的P(k-1|k-1)。这样,算法就可以自回归的运算下去。
卡尔曼滤波器的原理基本描述了,式子1,2,3,4和5就是他的5 个基本公式。根据这5个公式,可以很容易的实现计算机的程序
CamShift算法
简介
CamShift算法,即"Continuously Apative Mean-Shift"算法,是一种运动跟踪算法。它主要通过视频图像中运动物体的颜色信息来达到跟踪的目的。我把这个算法分解成三个部分,便于理解:
Back Projection计算。
Mean Shift算法
CamShift算法
1 Back Projection计算
计算Back Projection的步骤是这样的:
1. 计算被跟踪目标的色彩直方图。在各种色彩空间中,只有HSI空间(或与HSI类似的色彩空间)中的H分量可以表示颜色信息。所以在具体的计算过程中,首先将其他的色彩空间的值转化到HSI空间,然后会其中的H分量做1D直方图计算。
2. 根据获得的色彩直方图将原始图像转化成色彩概率分布图像,这个过程就被称作"Back Projection"。
在OpenCV中的直方图函数中,包含Back Projection的函数,函数原型是:
void cvCalcBackProject(IplImage** img, CvArr** backproject, const CvHistogram* hist);
传递给这个函数的参数有三个:
1. IplImage** img:存放原始图像,输入。
2. CvArr** backproject:存放Back Projection结果,输出。
3. CvHistogram* hist:存放直方图,输入
下面就给出计算Back Projection的OpenCV代码。
1.准备一张只包含被跟踪目标的图片,将色彩空间转化到HSI空间,获得其中的H分量:
IplImage* target=cvLoadImage("target.bmp",-1); //装载图片
IplImage* target_hsv=cvCreateImage( cvGetSize(target), IPL_DEPTH_8U, 3 );
IplImage* target_hue=cvCreateImage( cvGetSize(target), IPL_DEPTH_8U, 3 );
cvCvtColor(target,target_hsv,CV_BGR2HSV); //转化到HSV空间
cvSplit( target_hsv, target_hue, NULL, NULL, NULL ); //获得H分量
2.计算H分量的直方图,即1D直方图:
IplImage* h_plane=cvCreateImage( cvGetSize(target_hsv),IPL_DEPTH_8U,1 );
int hist_size[]={255}; //将H分量的值量化到[0,255]
float* ranges[]={ {0,360} }; //H分量的取值范围是[0,360)
CvHistogram* hist=cvCreateHist(1, hist_size, ranges, 1);
cvCalcHist(&target_hue, hist, 0, NULL);
在这里需要考虑H分量的取值范围的问题,H分量的取值范围是[0,360),这个取值范围的值不能用一个byte来表示,为了能用一个byte表示,需要将H值做适当的量化处理,在这里我们将H分量的范围量化到[0,255].
4.计算Back Projection:
IplImage* rawImage;
//----------------------------------------------
//get from video frame,unsigned byte,one channel
//----------------------------------------------
IplImage* result=cvCreateImage(cvGetSize(rawImage),IPL_DEPTH_8U,1);
cvCalcBackProject(&rawImage,result,hist);
5.结果:result即为我们需要的.
2) Mean Shift算法
这里来到了CamShift算法,OpenCV实现的第二部分,这一次重点讨论Mean Shift算法。
在讨论Mean Shift算法之前,首先讨论在2D概率分布图像中,如何计算某个区域的重心(Mass Center)的问题,重心可以通过以下公式来计算:
1.计算区域内0阶矩
for(int i=0;i for(int j=0;j M00+=I(i,j) 2.区域内1阶矩: for(int i=0;i for(int j=0;j { M10+=i*I(i,j); M01+=j*I(i,j); } 3.则Mass Center为: Xc=M10/M00; Yc=M01/M00 接下来,讨论Mean Shift算法的具体步骤,Mean Shift算法可以分为以下4步: 1.选择窗的大小和初始位置. 2.计算此时窗口内的Mass Center. 3.调整窗口的中心到Mass Center. 4.重复2和3,直到窗口中心"会聚",即每次窗口移动的距离小于一定的阈值。 在OpenCV中,提供Mean Shift算法的函数,函数的原型是: int cvMeanShift(IplImage* imgprob,CvRect windowIn, CvTermCriteria criteria,CvConnectedComp* out); 需要的参数为: 1.IplImage* imgprob:2D概率分布图像,传入; 2.CvRect windowIn:初始的窗口,传入; 3.CvTermCriteria criteria:停止迭代的标准,传入; 4.CvConnectedComp* out:查询结果,传出。 (注:构造CvTermCriteria变量需要三个参数,一个是类型,另一个是迭代的最大次数,最后一个表示特定的阈值。例如可以这样构造criteria:criteria=cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)。) 返回的参数: 1.int:迭代的次数。 实现代码:暂时缺 3) CamShift算法 在了解了MeanShift算法以后,我们将MeanShift算法扩展到连续图像序列(一般都是指视频图像序列),这样就形成了CamShift算法。CamShift算法的全称是"Continuously Apaptive Mean-SHIFT",它的基本思想是视频图像的所有帧作MeanShift运算,并将上一帧的结果(即Search Window的中心和大小)作为下一帧MeanShift算法的Search Window的初始值,如此迭代下去,就可以实现对目标的跟踪。整个算法的具体步骤分5步: Step 1:将整个图像设为搜寻区域。 Step 2:初始话Search Window的大小和位置。 Step 3:计算Search Window内的彩色概率分布,此区域的大小比Search Window要稍微大一点。 Step 4:运行MeanShift。获得Search Window新的位置和大小。 Step 5:在下一帧视频图像中,用Step 3获得的值初始化Search Window的位置和大小。跳转到Step 3继续运行。 2.实现 在OpenCV中,有实现CamShift算法的函数,此函数的原型是: cvCamShift(IplImage* imgprob, CvRect windowIn, CvTermCriteria criteria, CvConnectedComp* out, CvBox2D* box=0); 其中: imgprob:色彩概率分布图像。 windowIn:Search Window的初始值。 Criteria:用来判断搜寻是否停止的一个标准。 out:保存运算结果,包括新的Search Window的位置和面积。 box:包含被跟踪物体的最小矩形。 说明: 1.在OpenCV 4.0 beta的目录中,有CamShift的例子。遗憾的是这个例子目标的跟踪是半自动的,即需要人手工选定一个目标。我正在努力尝试全自动的目标跟踪,希望可以和大家能在这方面与大家交流。
1.原理
2006.03.15 来自:CSDN 选自Mailbomb 的blog
程序员每天该做的事
1、总结自己一天任务的完成情况
最好的方式是写工作日志,把自己今天完成了什么事情,遇见了什么问题都记录下来,日后翻看好处多多
2、考虑自己明天应该做的主要工作
把明天要做的事情列出来,并按照优先级排列,第二天应该把自己效率最高的时间分配给最重要的工作
3、考虑自己一天工作中失误的地方,并想出避免下一次再犯的方法
出错不要紧,最重要的是不要重复犯相同的错误,那是愚蠢
4、考虑自己一天工作完成的质量和效率能否还能提高
一天只提高1%,365天你的效率就能提高多少倍你知道吗? (1+0.01)^365 = 37 倍
5、看一个有用的新闻网站或读一张有用的报纸,了解业界动态
闭门造车是不行的,了解一下别人都在做什么,对自己能带来很多启示
6、记住一位同事的名字及其特点
你认识公司的所有同事吗?你了解他们吗?
7、清理自己的代码
今天完成的代码,把中间的调试信息,测试代码清理掉,按照编码风格整理好,注释都写好了吗?
8、清理自己的桌面
当日事当日毕,保持清洁干劲的桌面才能让你工作时不分心,程序员特别要把电脑的桌面清理干净
程序员每月该做的事
1、至少和一个同事一起吃饭或喝茶
不光了解自己工作伙伴的工作,还要了解他们的生活
2、自我考核一次
相对正式地考核自己一下,你对得起这个月的工资吗?
3、对你的同事考核一次
你的同事表现怎么样?哪些人值得学习,哪些人需要帮助?
3、制定下月的计划,确定下月的工作重点
4、总结自己工作质量改进状况
自己的质量提高了多少?
5、有针对性地对一项工作指标做深入地分析并得出改进的方案
可以是对自己的,也可以是对公司的,一定要深入地分析后拿出自己的观点来。要想在老板面前说得上话,做的成事,工作上功夫要做足。
6、与老板沟通一次
最好是面对面地沟通,好好表现一下自己,虚心听取老板的意见,更重要的是要了解老板当前关心的重点
程序员每年该做的事
1、年终总结
每个公司都会做的事情,但你真正认真地总结过自己吗?
2、兑现给自己、给家人的承诺
给老婆、儿子的新年礼物买了没有?给自己的呢?
3、下年度工作规划
好好想想自己明年的发展目标,争取升职/加薪、跳槽还是自己出来干?
4、掌握一项新技术
至少是一项,作为程序员一年要是一项新技术都学不到手,那就一定会被淘汰。
掌握可不是看本书就行的,要真正懂得应用,最好你能够写一篇教程发表到你的blog
5、推出一种新产品
可以是一个真正的产品,也可以只是一个类库,只要是你创造的东西就行,让别人使用它,也为世界作点贡献。当然如果真的很有价值,收点注册费也是应该的
6、与父母团聚一次
常回家看看,常回家看看
OpenCV学习笔记(一)概述和系统配置
一、概述
OpenCV是英特尔公司于1999年在俄罗斯设立的软件开发中心“Software Development Center”开发的。该公司一直致力于基于个人电脑的计算机视觉应用的开发,可以实时追踪的视觉用户接口技术的普及为目标。初步拟定应用于Human-Computer Interaction(HCI,人机互动)、物体确定、面孔识别、表情识别,移动物体追踪、自主运动(Ego-motion)、移动机器人等领域。因此,“OpenCV 2.1将提供给玩具制造商及机器人制造商等从事计算机视觉相关技术的各类企业/团体”
OpenCV将以公开源码的方式提供,也就是接受方有权在修改之后另行向第三方提供。源代码(C语言)中包括有库(Library)的所有功能。详细情况刊登在OpenCV的WWW站点上。
英特尔公司解释说,“速度更高的微处理器、廉价的数码相机以及USB 2等技术使高速视频捕获(Video Capture)成为可能,因此,基于普通个人电脑的实时计算机视觉将有望实现”。
OpenCV的最新版本为beta5。
二、OpenCV组成部分
目前OpenCV包含下面几个部分:
cvcore:一些基本函数(各种数据类型的基本运算等)
cv: 图像处理和计算机视觉功能(图像处理,结构分析,运动分析,物体跟踪,模式识别,摄像机定标)
cvaux:一些实验性的函数(view morphing,三维跟踪,pca,hmm)
highgui 用户交互部分(GUI,图像视频I/O,系统调用函数)
另外还有cvcam,不过linux版本已经抛弃。windows版本中将directX支持加入highgui后,cvcam将被彻底去掉。
三、OpenCV特点
OpenCV是Intel公司开发的图像处理和计算机视觉函数库,它有以下特点:
1) 开放C源码
2) 基于Intel处理器指令集开发的优化代码
3) 统一的结构和功能定义
4) 强大的图像和矩阵运算能力
5) 方便灵活的用户接口
6)同时支持MS-WINDOWS、LINUX平台
四、下载OpenCV
http://www.sourceforge.net/projects/opencvlibrary。
五、参考资料
=》源代码及文档下载:SOURCEFORGE.NET
http://sourceforge.net/projects/opencvlibrary/
=》INTEL的OPENCV主页:
http://www.intel.com/research/mrl/research/opencv/
=》YAHOO OPENCV 的邮件列表:
http://groups.yahoo.com/group/OpenCV/
=》CMU(卡耐基-梅隆大学)的计算机视觉主页:
http://www-2.cs.cmu.edu/afs/cs/project/cil/ftp/html/vision.html
=》OPENCV 更为详细的介绍
http://www.assuredigit.com//incoming/sourcecode/opencv/chinese_docs/index.htm
=》OPENCV 的常用问题与解答
http://www.assuredigit.com//incoming/sourcecode/opencv/chinese_docs/faq.htm
=》OPENCV 的安装指南
http://www.assuredigit.com//incoming/sourcecode/opencv/chinese_docs/install
=》更多的最新资料,请访问
http://blog.csdn.net/hunnish和http://rocee.bokee.com
六、创建一个 DeveloperStudio 项目来开始 OpenCV
1. 在 Developer Studio 中创建新的应用程序:
选择菜单 "File"->"New..."->"Projects" . 选择 "Win32 Application" 或 "Win32 console application" - 后者是更简单的方法。
键入项目名称,并且选择存储位置
可以为项目创建一个单独的 workspace ("Create new workspace") , 也可以将新的项目加入到当前的 workspace 中 ("Add to current workspace").
单击 "next"
选择 "An empty project", 点击 "Finish", "OK".
经过以上步骤,Developer Studio 会创建一个项目目录 (缺省情况下,目录名就是项目名), .dsp 文件以及.dsw,.ncb ... ,如果你创建自己的workspace.
2添加文件到 project 中:
选择菜单"File"->"New..."->"Files" .
选择"C++ Source File", 键入文件名,点击"OK"
增加 OpenCV 相关的 头文件目录 #include :
#include "cv.h"
/* #inlcude "cvaux.h" // experimental stuff (if need) */
#include "highgui.h"
或者你可以拷贝部分已有的文件 (如:opencv/samples/c/morphology.c) 到项目目录中,打开它,并且加入到项目中 (右键点击编辑器的视图 -> "Insert File into Project" -> ).
3配置项目:
选择菜单"Project"->"Settings..."以激活项目配置对话框 .
在左边选择你的项目.
调节设置,对 Release 和 Debug 配置都有效:
选择 "Settings For:"->"All Configurations"
选择 "C/C++" tab -> "Preprocessor" category -> "Additional Include Directories:". 加入用逗号分隔的相对路径 (对文件 .dsp 而言) 或绝对路径
d:/opencv/cxcore/include,d:/opencv/cv/include,d:/opencv/otherlibs/highgui, d:/opencv/cvaux/include(optionally,)
选择 "Link" tab -> "Input" category -> "Additional library path:".
加入输入库所在的路径 (cxcore[d].lib cv[d].lib hihghui[d].lib cvaux[d].lib)
d:/opencv/lib
调节 "Debug" 配置:
选择 "Settings For:"->"Win32 Debug".
选择 "Link" tab -> "General" category -> "Object/library modules". 加入空格分隔的 cvd.lib,cxcored.lib highguid.lib,cvauxd.lib (optionally)
可以改变输出文件的名称和位置。如想把产生的 .exe 文件放置于项目目录而不是Debug/ 子目录下,可在 "Link" tab -> "General" category -> "Output file name:" 中键入 ./d.exe
调节 "Release" 配置
选择 "Settings For:"->"Win32 Release".
选择 "Link" tab -> "General" category -> "Object/library modules". 加入空格分隔的cv.lib cxcore.lib highgui.lib cvaux.lib (optionally)
4增加从属性项目到 workspace 中:
选择菜单: "Project" -> "Insert project into workspace".
选择 opencv/cv/make/cv.dsp.
同样步骤对 opencv/cvaux/make/cvaux.dsp, opencv/otherlibs/highgui/highgui.dsp.
设置从属性:
选择菜单: "Project" -> "Dependencies..."
对 "cv" 选择 "cxcore",
对 "cvaux" 选择 "cv", "cxcore",
对 "highgui" 选择 "cxcore",
对你的项目,选择所有的: "cxcore", "cv", "cvaux", "highgui".
从属性配置保证了在源代码被改变的情况下,自动重新编译 opencv 库.
5就这么多。可以编译并且运行一切了。
七、库设置:
静态库设置:
Opencv程序需要静态库设置,其release版本的静态库在系统的lib目录下,其debug版本的静态库需要重新全编译所有的程序。
动态库设置:
OPenCV启动时需要一些动态库的支持,这些动态库必须放在系统目录下或者当前目录下。
Cv097.dll,cvaux097.dll,cvcam097.dll,cxcore097.dll highguid097.dll,libguide40.dll