2010年7月30日星期五

[zz]新东方励志:毅力,是一种快乐的持续

[来源:新东方 作者:张一楠]

  在这个世界上,当你想有所成就的时候,最先想到的应该是找到自己的原始冲动,然后用毕生的时间全力以赴、梦萦魂牵地去实现它。

  所谓原始冲动,就是你自己的天赋所在,你最狂热最感兴趣,不做就会死的那件惟一的事情。

  每天用你最喜欢的方式做你最喜欢的事情,这是一种莫大的幸福。然后,每天重复这种快乐的做事方式和做事心情,久而久之,形成习惯。天长日久,这种习惯就会成为性格。性格决定命运。性格不是天生的,性格就是这样培养出来的。所以,要让你的命运出现转机,就要找到自己最喜欢的事情。

  当你因为兴趣而做一件事情的时候,这个世界上就没有毅力和坚持之类的事情。外人看到的你的毅力,仅仅是因为你做这件事情时那种快乐的心情。其实,在这个世界上,“毅力”是根本不存在的品质,因为所谓的“毅力”就是你因为快乐而可以长期做一件事情而不会放弃的态度。所以,毅力是一种快乐,不是一种痛苦。从这个角度上来说,有些懒惰的人,并不是他们真的懒惰,而是因为他们没有找到自己的原始冲动并把它培养成习惯而已。

  我自己是最好的例子。我初中的时候找到自己的最爱是英语,然后用自己喜欢的方式学习它。比如,每天早晨都坐在奶奶身边读英语,每天读半个小时。奶奶不懂英语,但是每天都夸我:“俺乖乖读得真好!”我很有成就感,每天坐在奶奶身边读英语。奶奶就闭着眼睛静静地听着。我觉得,每天早晨,陪着奶奶读英文是世界上最幸福的事情。我从初一读到初三,从高一读到高三,大学里依然坚持晨读。慢慢地,同学们对我的英语成绩只能羡慕而无法超越。我晨读英语的习惯,是一种幸福的坚持,没有感觉到丝毫的痛苦。我也没想到,晨读英语需要毅力,它只是我的原始冲动而已。

  还有一个例子,一个我非常欣赏的男人的故事。他是一个防盗系统安装工程师,他的工作就是每天去客户的门前安装防盗器械,每次挖洞的时候,他的文字灵感就如“滔滔江水,连绵不绝”。每当此时,他就会坐在梯子上,把他喷薄而出的美丽文字记录下来。当年的他,就是这样,一边干活一边记录下这些让他兴奋不已的文字精灵。半年下来,居然积累了200多首歌词。他选出自己最得意的100首装订成册,寄了100份到各大唱片公司。没想到泥牛入海,毫无音信。但他并不伤心,因为他对文字有发自心底的热爱,像喷涌而出的岩浆,火红火红的,谁都拦不住。他是因为热爱而写,不是为了别的。我觉得,这个男人心中最柔软的部分已经留给了他的最爱——具有缠绵情怀的中国汉字。1997年7月7日凌晨,他像往常一样去安装防盗系统。这时有人打电话给他,他坐在梯子上接了电话,这个打电话给他的人叫做吴宗宪。

  故事的结局是,工程师成为海峡两岸最具声望的歌词作者,他写的歌词包括《东风破》、《菊花台》、《青花瓷》等,他的名字叫方文山。周杰伦歌曲中大部分经典的歌词都出自他的神来之笔。

  找到你自己的原始冲动,那么,坚持,就成为一种快乐的持续。这种持续,才是真正的毅力。

2010年7月22日星期四

BGS-KDE算法:读”Non-parametric Model for Background Subtraction“

本文是ECCV 2000年的文章,"Non-parametric Model for Background Subtraction",作者是Ahmed Elgammal,Rutgers大学副教授(这个大学好似没听过,查了一下排名在150名左右),他的主页在这里,专注于人的行为分析、跟踪等。他这篇文章可以找得到,还有一个在线版在这里。

这篇文章是2000年的,十年前的文章,也是第一个提出使用KDE方法的。所谓KDE方法是指:Kernel Denity Estimation,即使用核函数来估计概率。核心思想就是根据最近N帧图像,建立N个样本作为背景Kernel模型,在检测的时候,使用相应的kernel函数来估计当前像素值出现的概率,如果大于某一个门限,即为背景。

KDE算法是一个General的方法,如果把所有的Kernel函数取为高斯函数,则KDE函数就退化为generalized的混合高斯模型,这里每一个样本就是一个高斯模型。

值得注意的是:整个KDE算法是基于这样的假设,背景是变化很频繁的,不足以用几个高斯模型来表示,但是在很短的时间间隔内,还是符合一定的分布的,也就是本文所谓的local-in-time,例如高斯模型。

1. 基本背景模型

概率密度估计:Density Estimation

KDE方法也是基于像素的,以下描述都是对于每个像素的。设 x1, x2, x3,....xN是像素的最近N个样本,使用这些样本值,来当前像素点的概率密度函数如:

                           Pr(xt)=[K(xt-x1)+K(xt-x2)+ ... +K(xt-xN)]/N  (1) 

其中,K表示Kernel函数,xt表示像素在时刻t的值。如果Pr(xt)<T,这里T是一个全局门限,说明可以概率小,可以判定为前景,反之为背景。

这里,如果K为高斯函数,就很像混合高斯模型了。而且Pr(xt)公式可以使用查找表方法计算,可以极大提高运算速度。相比与混合高斯模型,因为KDE算法只是依赖于最近的N个样本,很容易“forget”以前的状况,所以可以灵活控制其精确度。


核函数宽度估计:Kernel Width Estimation(我把它称为高斯函数的标准差估计) 

      如果使用高斯函数上面的公式1就可以更加具体化,把高斯函数代入公式1,具体公式见原文,公式中有一个关键参数--高斯分布的标准差,此参数反映了当前像素的变化剧烈情况,可以通过如下方式来估计此参数:对每个颜色通道,N个连续的样本,相邻的两个值的差值|xi - x(i+1)|,在这些连续的(xi, x(i+1) )对中,求得中值m。此中值m与标准差有直接对应关系:
                    delta = m/(0.68*1.414)
        è¿™é‡Œä¸ºä»€ä¹ˆä½¿ç”¨è¿™æ ·ä¸­å€¼æ¥ä¼°è®¡æ ‡å‡†å·®å‘¢ï¼Ÿè¿™æ˜¯å› ä¸ºåœ¨N个样本中,连续的两个值 (xi, x(i+1) )很大可能是属于同一个local-in-time的高斯分布。这样的估计是有效的。

2. 抑制误检(False Detection)

本文把误检来源分为两种,一种是噪声,一种是背景的轻微运动,例如树枝晃动、水面等。第一种物件由于是全局散落的,可以通过滤波或者形态学的方法滤除,后一种由于有空间的聚集特性,很难用传统的滤波方法消除。

分析一下第二种误检的来源,就可以知道,虽然在当前像素点的KDE中不能匹配上,因为这个像素点很可能是在领域中移动过来的,所以这里就可以在当前像素点的一个领域中寻找最佳的匹配,还是使用前面的概率估计公式,在领域中寻找最佳的匹配,即概率的最大值。
             Pn(xt)=max{Pr(xt| By)},
其中By表示xt的领域像素点。若Pn(xt)大于某个门限th1,则确定为背景。

通过上述方法,虽然能去掉一些误检,但是,同时会把一些真实的前景给去掉。考虑到真实的前景有这样的有这样的特点,整个被检测出来的前景一定是在从附近的某个地方移动到这里来的,而不是几个像素点。这里定义一个概率Pc,表示整个被检测出来的连续区域是从附近移动过来的概率。定义如下:
            Pc = Pn(xi)的乘积
其中,xi是被检测出来的连续的区域内的像素。对于一个真实的前景目标,整个被检测出来的连续区域,对于上面的公式的计算结果应该是很小的。

所以综合上面的两个方面,如果一个像素点同时满足Pn>th1和Pc>th2,则表示这是一个误检,重新说一下,应该是第二种误检。

3. 背景更新

背景更新的策略有两种:

  1. 选择性更新:即只是把新的样本(sample)添加到那些被判定为背景的像素点模型
  2. 盲目更新:即把新的样本添加到任何像素点模型

这两个方法各有弊端,例如第一种方法很依赖与判定的结果是不是正确,如果错了,就会一错再错。第二种方法比较盲目,会把静止前景或者运动很慢的前景融入到背景模型中。本文提出了一个结合两个更新策略的方法,使既能很快的适用新的背景改变,又能对前景,又能足够精确的检测出前景,使用两个model来达到这个目的:Short-term mdel 和 Long-term model:

Short-term model: 这是一个最近(very recent)场景N个样本模型,此模型对场景的变化适应很快,而且对前景检测很敏感。使用选择性策略更新背景模型;

Long-term model: 这个模型保存相对稳定的背景模型,而且改变非常的缓慢。这个模型也包含N个样本,但是此N个样本的所取自的时间窗口比short-term model要宽很多。这个模型使用盲目更新策略更新。

这两个模型检测结果的交集,可以消除短期模型的持续错误前景(false positive),也可消除长期模型结果中的误检。这里也会造成一个问题,就是同时消除了一些正确的前景,例如在短期的模型中检测出来的静止前景。本文的解决方法是,在短期模型中检测出来的前景,如果与前面的合并结果相邻的话,就判定为最后的前景。(这种解决方法,我有待考察,我并不明白为什么这样处理就可以解决此问题)

4. 阴影检测

阴影检测是背景差分中的难点之一,阴影的特点就是颜色相似,而亮度变低。本文使用了色度坐标(Chromaticity Coordinate)来运算,r=R/(R+G+B), g=G/(R+G+B), b=B/(R+G+B),其中r+g+b=1,所以一个像素的色度坐标就可以表示为(r, g)二元组。这个二元组,只是记录了色度信息,完全丢失了亮度信息,可能会造成很多的漏检。这里就另外引入一个亮度信息s=R+G+B,所以同样用一个三元组<r, g, s>来表示一个像素,这里色度和亮度信息就完全区分开来了。如果满足色度r,g分量相近,而a<st/sb<1的话,就可能判定为阴影。

在本文中,还是使用KDE的方法如下:使用前面的KDE的方法,设A={x1, x2,...,xn}为一像素的样本,xt为当前像素值,在集合A中选取alpha<(xt/xi)<betaçš„xi组成集合B,对B集合中的元素xi使用二维的(r, g)做KDE运算。这里集合B就称为与当前像素“相关的”背景样æœ
¬ï¼Œè¿™æ ·æœ‰åˆ©äºŽæé«˜è¿ç®—效率。

总结:

本文是KDE算法的开山之作,提到的和想努力解决的问题也很多。本文的KDE模型是核心,如第1小节中描述的;误检抑制,通过领域内的方法,抑制背景的小运动误差,如第2小节中的描述;长短期背景模型,企图解决背景更新快慢的问题,如第3小节所示;使用色度加亮度坐标,企图解决阴影的问题,如第4小节所示。这些方法都是值得学习的。本文方法的实时性,文中说是在400MHz的奔腾CPU,处理320x240的图片能达到15-20 fps,这样的速度可观的,有机会要实现一下本算法。

2010年7月19日星期一

Python学习笔记--表达式

1. 赋值表达式

赋值表达式有如下几个特点:

  • * 复制表达式创建一个引用;在Python中,变量中存储的只是对象的引用,赋值其实就是创建一个变量名到实际对象的一个引用
  • * 变量名在第一次赋值的时候将会自动创建,无须声明和定义
  • * 变量使用前必须被赋值

由于变量名中没有任何数据类型信息(记住,只是对象的引用),所以可以灵活对变量赋值任何类型的数据:eg:

x = 2 x = 'abc' x = [1,2,3] 在python中,有一种特殊的赋值--upacking assignment解包赋值,eg:

X, Y = 'abc', 'cde'        # tuple

[X, Y] = ['abc', 'abc]    # list

X, Y = 'ab'                  # string 可见,对于Sequence类型对象,都可以使用解包赋值,要求左边的变量数和右边的元素一致。  

2010年7月17日星期六

摘自高效能人士笔记

摘自别人《高效能人士的7个习惯》的读书笔记“由内而外(inside-out)”的意思是从自身做起,甚至更彻底一些,从自己的内心做起,包括自己的思维定式、人格操守和动机。由内而外的观点认为 个人的成功必须先于公众领域的成功;只有先信守对自己的承诺,才能信守对他人的承诺。由内而外是一个持续的更新过程,以主宰人类成长和进步的自然法则为基 础,是螺旋向上的,它让我们不断进步,知道实现独立自强与有效的相互依赖。

2010年7月12日星期一

Python学习笔记--引用vs复制

Python中,变量的都是默认存储对象的引用,而不是对象本身。例如:

>>> X = [1, 2, 3]

>>> L = ['a', X, 'b'] # Embed references to X's object.

>>> D = {'x':X, 'y':2}

这里X,L,D三个变量中的引用都指向了同一个对象[1,2,3],在其中任意一个修改,都会影响其他的变量。
有时候我们可能并不希望出现这样的情况,我们可能需要每个变量中都有一个对象的单独拷贝。实现方法如下:



  • * 使用无限制的slice来拷贝sequence对象,eg:A = L[:]

  • * 对于Dictionary,使用copy函数来实现对象拷贝 eg:B = D.copy()

  • * 一些函数也会产生对象的拷贝,例如list

  • * 标准库copy可以用来完成完全的拷贝, eg:import copy,然后调用X=copy.deepcopy(Y);



值得注意的是,前面的第一二种方法得到的拷贝,都是最高层的拷贝,而并部拷贝嵌套的数据结构,如果要彻底的拷贝,就可以使用最后一种方法,他是递归的拷贝所有的嵌套的对象。

Python学习笔记--TUples,Files

1. Tuples 元组


Tuples其实和List基本一致,都是有序的对象集合,与List不同的是,tuples是immutable的。
Tuples在使用小括号()包围起来的一系列对象。Tuples不支持任何函数
Tuples有如下一些特点:


  • * 任意对象的有序集合

  • * 通过下表offset存取

  • * Immutable

  • * 定长,异质,任意嵌套</li
  • * 对象索引的数组,而不是对象本色




Tuples的一些操作:



T = () #空元组

T = (1, ) # 一个元素的元组,后面要加一个逗号

T = (0, 'Hi', 1.2, 3) # 异质

T = ('ab', ('cd', 'ef')) #嵌套

T[i:j] #slicing

for t in T #迭代

T1 + T2 #连接


由于Tuple不支持任何函数,如果想对Tuple排序,应该怎么做呢?方法如下:


>>> T = ('cc', 'aa', 'dd', 'bb')

>>> tmp = list(T)

>>> tmp.sort( )

>>> tmp

['aa', 'bb', 'cc', 'dd']

>>> T = tuple(tmp)

>>> T

('aa', 'bb', 'cc', 'dd')

这里可以看到使用list()和tuple()函数进行相互转换,值得注意的是,这两个函数都是产生新的对象。


另外,tuple的immutable只是适用于tuple的最上层,如下例子可以说明:



>>> T = (1, [2, 3], 4)

>>> T[1][0] = 'spam' # Works

>>> T

(1, ['spam', 3], 4)

>>> T[1] = 'spam' # Fails

TypeError: object doesn't support item assignment

这里T[1]是一个List,list是mutable的。



2. Files 文件


文件是Python中的特殊的数据对象,此对象关联外部文件,相关函数可以直接对文件进行操作。
File的相关操作如下:


output = open('/dir/filename', 'w')

input = open('data','r') # file may be open as 'w' for write
# 'r' for read or 'a' for append

S = input.read() # 读取文件全部数据到一个字符串中

S = input.read(N) #读取N字节

S = input.readline() #读取下一行,以行结束符号=为标志

L = input.readlines() #读取整个文件到一个字符串的行的列表中

output.write(s) #向文件中写字符串s

output.wirtelines(L) #把列表中L中的所有行写入文件中

output.close() #关闭文件

在Python中,一个对象不再被引用的时候会自动回收内存,在回收file对象的时候,会首先关闭文件。手动close一个文件,虽然不是必须的,但是是一个好的习惯.

2010年7月9日星期五

测试vim+vimpress写博客

vim+vimpress写博客


Vimpress插件是在vim编辑器中写wordpress博客的插件。


这里vim使用了一个加强版,在这里下载。


我在使用过程中出现了乱码,参照这里修改:http://dante.im/vim-encoding/

2010年7月5日星期一

Python学习笔记--List和Dictionary

1. List列表 概述


List是Python中最灵活的有序集合类型。List中的元素可以是任何类型:number, string甚至list。List有一下特点:



  • * List是任意对象的有序集合

  • * 使用下标索引其中的元素

  • * 可变长度,异质(list中元素可以是不同类型),内嵌(list of list)

  • * mutable,序列的操作都适用(index,slice...)

  • * list是引用的集合,而不是对象本身




L = [ ] #空list

L = [1, 2, ‘text’ ] #异质

L = [1, 3, [1, 2] ] #嵌套

L[1], L[1:3], L[i][j], len[L] # index, slice

L1+L2, L * 3 # 链接和复制

for x in L   2 in L

L2.append(4) L2.extend([5,6,7]) L2.sort( ) L2.index(1) L2.reverse( ) # 方法

del L2[k]  del L2[i:j] L2.pop( ) L2[i:j] = [ ] # 删除

L2[i] = 1  L2[i:j] = [4,5,6] # 赋值, mutable

range(4)  range(0, 4) # 产生整数列表

L4 = [x**2 for x in range(5)]  #列表推导式,(现在还不知道是什么意思) 



2. Dictionay字典 概述


如果说列表List是有序对象集合的话,字典就是无序对象集合,他们之间最主要的差别就是,字典通过关键字(key)存取值,而不是offset。


字典有如下特点:





  • * 通过Key读取,而不是offset

  • * 任意对象的无序集合

  • * 可变长度,异质,可任意嵌套

  • * Mutable映射表

  • * 字典是对象引用的hash表,而不是对象本身



可见Dictionary和List基本是一直,除了全面所说的存取方式。


D = {} #空字典,注意是大括号

D1 = {'spam':2, 'egg':'None'} # 字典元素的定义方法

D2 = {'food':{'ham':1,'egg':2}} # 嵌套定义

D1['spam'] D2['food']['ham'] # 存取方法
D1.has_key('egg'), 'egg' in D1, D2.values(), ... # Dictionary相关的方法

D3 = dict(zip(keyslist, valuslist)) #Dictionary的构建(我现在还不清除这种用法)



由于Dictionary不是一个序列,所以不能直接使用迭代,要使用迭代的话,可以如下:
for item in D.keys():


Dictionary使用注意:



  • * Dictionary是Mapping,而不是Sequence,在Dictonary中的各元素没有先后的顺序关系,所以对于Sequence的操作对Dictonary都不使用。如:连接,分片索引(slicing)

  • * 对Dictionary的新的key赋值,就是增加一个新的元素。对已有的key赋值就是修改此元素

  • * Dictionary的key不一定要是字符串string,其实任意不可变(immutable)的对象都可以,例如整数等



2010年7月1日星期四

Python学习笔记--string 字符串

1. 字符串的定义

可以使用单引号(' '),双引号(" "):这两个表示的方式完全等价。
还可以使用三引号(单双引号都可以),可以进行多行的字符串的定义。
Raw字符串,即完全原样字符串,不经心转义,eg:r'c:\py\text'
Unicode字符串,多字节字符串, eg:u'text',u'ab\u0020cd'
Unicode --> normal:str(u"text")
normal --> Unicode:unicode("text")

2. 字符串操作

加法+:字符串的连接,'abc'+'def'
乘法*:字符串重复,'Hi!' * 3
求字符串的长度len()
字符串循环索引:
            ss = 'Hello'
            for c in ss: print c,  # H e l l o
            "H" in ss  # 1 or true
            "z" in ss   # 0 or false
字符串索引和分块:
           ss[0]  # 'H'
           ss[-2] # 'l'
           ss[1:3] #'el'
           ss[:-1]  #'Hell'
           ss[m:n], m和n可以缺省,m缺省为0, n缺省为ss的长度
           ss[start: end: step], eg, ss[1:5:2], ss[ : :-1]
字符串转换工具:
           不能直接把数值和字符串(即使这个字符串很像一个数字)使用加号“+”连接,因为加号“+”可能是表示字符串连接,也可能表示数值加法,所以Python就把这种情况视为语法错误。
           string--> number: eg. int("42"), float("1.23E-10"), string.atoi("42")
           number-->string:  eg. str(42), `42`, 这里的运算符backquotes(`object`),把之间的对象object转换成字符串。
           eval 函数用来执行Python代码。
改变字符串:
          首先要注意,字符串是不可改变的--immutale: can't chang in-place。所以要改变字符串,其实就是要使用相应的上述操作创造一个新的字符串。
          eg. ss='spam' ;  ss[0]='A' 将触发错误。

3. 字符串格式化

Python在string中重载了%运算符,这里类似了C语言中的sprintf函数中%的作用,占位符,eg:
>>> exclamation = "Ni" 
>>> "The knights who say %s!" % exclamation 
'The knights who say Ni!' 
这里使用exclamation变量替换了左边字符串中的%s

 >>> "%d %s %d you" % (1, 'spam', 4) 
'1 spam 4 you' 
如果是多个变量的时候,要使用小括号包围起来,形成一个元组tuple

 >>> "%s -- %s -- %s" % (42, 3.14159, [1, 2, 3]) 
'42 -- 3.14159 -- [1, 2, 3]'
这里把int,float,array类型的数据自动转换成string类型