首先,简单的把曾经做的工作按时间顺序排一下吧,既不太清,不过大致的时间顺序是这样的。
我的导师很好,他很久以前就跟我说,让我做双目视觉方面的研究,不过一直没有作,当时是因为功课太多。真正开始有关这方面的研究是从暑假开始的,从暑假开始我就参与了一个项目,在其中,和另一个女孩一起做双目视觉方面的研究
1。2004年的暑假7、8月份,我大致处于看一些有关双目视觉的文章,并且考虑如何实现机器人在球场中的自定位阶段。在这个阶段中,我对双目视觉有了一些了解。当时对双目视觉的概念是首先要对摄像机进行标定,然后是两个摄像头之间的图像的匹配问题。并且认为,摄像机标定都有了比较成熟的算法,而图像的匹配问题是难点。这些理解都只是从一些文章上看到的,并没有实际去做去想。现在认为,摄像机标定确实是有成熟的方法,不过还是有不少人去从各个方面研究(包括用于标定的参照物等等),而这些只是研究,真正的算法的框架等等,也许就是大体的原有的那些。如果要做一个项目,只要用成熟的算法就够了。如果是做研究,可以去研究这些,但是要深入地去研究这些摄像机标定的算法,数学的功底不好是不行的。对于图像的匹配,我当时感觉好难。因为文章中都是说没有统一的行之有效的方法,没错,这都是事实。在这方面,我觉得自己不如和我合作的那个女孩。方法是没有统一的,但是对于具体的问题是有方法的,而且,对于现在我参与的项目中,开始最简单的也就是要识别一个小球而已,匹配小球的球心就可以了。研究可以用各种的办法,但是,真正做项目,却是要学会选择真正简单的行之有效的方法就可以了,用得好就是本事。另外还有一个插曲,当时,上网找双目视觉的资料,看到一个女孩的叙述,说自己做的也是双目视觉方面的工作,但是,那个女孩说,她感觉那上面主要的就是一些数值算法,但是,我还真的有些相信了,现在想想,其实,那个女孩的认识是错误的。我现在的认识是,主要的还是图像处理方面的工作,不知道将来会不会有别的认识,但是现在的认识还只是如此。至于,小车在球场中的定位问题,我想当时可能考虑得太早,不过当时在师兄的督促下,也推导了一下公式,几经修改,最后,感觉也算是满意了,可是,我的东西都乱放,所以,那份改好的文档,除了给了师兄一份以外,自己可能就没有留存了,只是在邮箱中还有一份,可是这仅有的一份也感觉不是最后的版本了(在这其中有好多版本,都或多或少有错误)。小车的定位,当时也许是考虑得太早了,因为视觉方面的东西还没有下来。
在这其中,我不能不提到我的好朋友,她当时知道我要做这个,帮我去联系了一个做图像处理的人(说是她的男朋友的好朋友),想让我和他交流交流,可是,我和他没有太多的联系,想想自己走的弯路,也是自己不好问的结果。我要好好的感谢我的好朋友,我知道,我和她是互相拥有的,心灵相通,可是,我觉得自己对她没有她对我好。
2。2004年8、9月份。由于项目中用的是usb摄像头,没有图像采集卡,要进行图像方面的处理,就需要自己捕捉视频流,然后再对图像进行处理。和我一起合作的女孩,其实已经作了一个用vfw实现的视频捕捉的程序,做得相当不错。于是,我问她要了源代码,然后,也从中国学术期刊网上下了一些论文(因为发现介绍这种技术的书太少了),想要好好研究一下。后来突然看到一篇文章中写道,vfw中的提供的函数库就是已经封装在windows操作系统上了,当时就突然想到,在wince下面可能都不能提供这方面的支持。在书店里看到过一本讲wince方面的书,当时随便翻了翻,里面提到wince下面支持directshow,而directshow可以用来捕捉视频流的。我觉得自己特别幸运,当我想学directshow的时候,正好有directshow方面的两本书刚刚出版,在书店热销中。对于入门,中文书还是不错的,能让你有一个系统的概念。特别是,我当初对directshow一点了解都没有的情况下。于是从微软的网站上下了directX 9(当时也是刚出来的),开始学习用directshow进行视频流的捕捉。主要参照了那本directshow的中文书和一本外文的电子文档,也看了一下directshow的帮助文档,参照里面的例子,实现了视频流的捕捉和保存,并能将捕捉到的图像保存为bmp位图的格式。现在想想,当初做这些花了挺长时间,其实,应该很快就能做出来的。不过,也在论坛上看到一个帖子,说到了驱动的问题。在一般的windows平台下,驱动有两种模型,一种是vfw,一种是wdm,其中,vfw是已经过时了的(我对驱动没有太多的研究,不知道这样说妥不妥),而现在的驱动一般都是符合wdm模型的。directshow有一种机制,能把符合wdm模型的驱动分装成一个source filter,但是,没有驱动是不可以的。这就存在一个问题,wince下是必须要有摄像头的驱动的,才能用directshow。于是,大家就都开始找驱动,可是,最后的结果是wince下没有现成的这款摄像头的驱动的,可能唯一的办法就是自己开发。这些都是后话。当时还是在学directshow,想法是在wince下开发双目视觉,还是需要directshow的,只要有了驱动,就可以了。而后来,当对wince下的驱动有了一些了解后,并询问了网上的一个挺热心的人(他做过wince下的驱动,也做过wdm模型的驱动),后知道,wdm模型驱动和wince下的驱动模型是不一样的。具体为什么不一样,因为我对wdm驱动模型不了解,只知道如果自己开发wince下的驱动,一般用的是流驱动模型。直到这个时候,我还对用directshow封装开发好的驱动,然后再在wince下用directshow进行视频流的捕捉,这一套方案,深信不疑。
要做一些实际的东西了,当我能用自己编写的程序应用directshow技术,捕捉视频流和把捕捉的图像保存后,我就打算做一下摄像机的标定了。虽然,directshow这个技术,我只是涉及到一些皮毛,编写的程序也很粗糙。关于摄像机的标定也是用的最简单的方法,有一个棋盘格,然后,找棋盘格上的交点。现在想想,那里面最主要的就是图像处理的方法了。用到了彩色图像的边缘检测;用大津法(OTSU)法自动求灰度图像分割的阈值,通过求得的阈值,将图像二值化;用形态学上的图像的细化的方法,对二值图像进行细化;通过进行hugh变换,求图像中的直线,对横线和纵线分别求,并把直线画在原来的图像和处理后的图像上;求横线和纵线的交点坐标,为此还要对横线和纵线进行排序。在这里主要是解方程组,为了求矩阵的逆,为方便采用了vc和matlab相连的方法,最后求得的图像点的坐标也在原图和变换后的图像中表示了出来。在这里说明一下,仅仅为了求矩阵的逆,我用了matlab和vc相连的方法,在当时看来,刚开始做的时候,想的是简单一些,可是,却是不明智的。因为,一点是用到的matlab部分太少,不值得,而当初,为了把参数传给matlab我花了很长的时间,在网上查到的参数的传递顺序不对,只是自己慢慢试出来的。另一点是,其实用现成数值计算的求矩阵的逆的源代码就可以了,而且还会简单。作这个标定的程序,花了不少的时间,也是对图像处理的算法等等都不熟悉。后来,和我合作的女孩直接用matlab的工具箱作标定,也作了实验,验证了标定的结果,肯定会比我做的效果好。也就是我做的这个,基本上就是属于失败的,除了自己在其中学到了一些图像处理的方法,对简单的标定有了一些感性的认识外,对这个项目没有任何的帮助。要提一下,在图像处理方面,由于我不好问,其实,自己在走,走了不少弯路。我不知道有角点检测,这个也是前一段时间,导师让所有进行双目视觉研究的人都来开会,讨论双目视觉方面的东西,然后,我才知道的。当时,一个老师演示了用OpenCV中的函数库进行角点检测的程序,感觉效果还真的不错。而在我看来,简单的摄像机标定,就是在那些角点的检测上了,如果我能早知道就好了。有时候理论和实际是完全不同的,实际也是自己的动手的过程。标定中图像处理的大体步骤,我是按一篇硕士论文中写的做的,虽然有些方法用的不同,但是,我觉得自己用的方法,比他用得更好些。当时,他在论文中写的是误差很小,也列出了各种数据。不过,据我看来,可能误差,不能太小的。
3。2004年10、11月。从十一放假后,我差不多就想要看看能不能有自己作驱动的希望了,当时,标定的程序虽然是出来了,但是具体的精度没有细致的验证,只是觉得精度不会高,因为从找到的图像中的点就可以看出来,还是有些误差的。并且,一起合作的女孩用的是标准的工具箱做标定,效果怎么样,都会比我做的好,我觉得对一个实际的项目来说,在做下去,是没有意义的了。我曾对我以前的同学说,没有驱动怎么办?她当时马上说,自己做!后来,所以,我也就想看看能不能自己作驱动了。上各个论坛上看了,也找了些有关驱动方面的书,可是能找到的大部分都是WDM模型的。刚开始的时候,很迷茫,也下了XP的DDK(driver develop kit),但是还是不知道从什么地方入手。有关介绍wince下的驱动开发的很少。不过后来不知道怎么想的,就决定先看看wince下的驱动模型,还想到了要开发的是usb摄像头的驱动,所以,应该再看看usb协议的。于是,我看了一个人翻译的usb 1.0协议,也算是对usb协议有了些了解。我上biplip.com的论坛上问,在wince下编写usb摄像头的驱动有些什么要求,版主给了我挺好的建议,在今天看来,从我现在的理解来看,也相当不错的。他告诉我要看帮助文档,这是真的。正如他所说的,不看帮助文档是不行的,越是E文的,越要看,真的很感谢他。我也上了驱动开发网的wince论坛,那里有一个热心人,到后来,我问他问题,也就直接给他发信了,他也每回都很认真的回复了,他自己说做过wdm模型的驱动,也做过wince下的驱动,也就是他对我说wdm模型的驱动和wince下的驱动是不一样的。他很热心。我知道要作驱动必须对系统有比较深的了解,于是,开始看wince的帮助文档,看如何定制平台,其实这是挺简单的,如果从简单的角度看的话,但是,也有些东西,没有开发板是不行的,这一部分,我做的也是很肤浅,不会通过改变系统文件,来定制平台,由于没有试验过,所以所看的都是些纸上谈兵,没有实战的经验,所以,也就1、2个月的时间,到现在也就忘得差不多了,这样想想,其实,学会做工作日记还是很重要的。到后来,我知道了在wince下面如果是用户自己编写的程序,一般都是流驱动模型的,对于usb设备的驱动,只要在上层实现10个流接口函数,在下层实现3个流接口函数,就可以了。真正和usb打交道的是系统会提供的几个函数。通过调用这几个函数,就能把数据取出来了。也看了一下系统提供的usb设备驱动的例子,当时看的是打印机的。然后,一个师兄发给一个网址,说里面有Linux的usb摄像头驱动的例子。师兄还是师兄,看的会远些的。后来,我也认识到要开发wince下的usb摄像头的驱动,其实,还是可行的。在下层的3个函数的实现中,可以参照wince下提供的例子,而在上层的10个函数的实现中,可以看Linux驱动的例子。不过,由于种种原因,当我认识到这一点,打算好好做一下的时候,我就*放弃了。这次放弃,让我受到了些许的打击,也就是导致我在这个学期剩下的日子中很堕落的原因之一吧,其实是自己的心态一直没有调整过来。由于不作驱动了,那么,就开始考虑当驱动做好之后应该如何用这个驱动了。因为当时驱动还没有编出来,我就自己编写了只是用作试验用的wince下驱动,里面只是有10个流接口的空函数而已,然后通过写注册表,用读写文件的命令去获取驱动提供的数据。当这个做完之后,我想由于是两个摄像头,双目视觉,就是要获取数据的同步的,于是又自己试验了一下线程间同步,同时获取数据。不过那个程序是简单的,为了试验,让一个线程产生数据,另外还有获取数据的线程。实验结果也算是成功的。这样,感觉上只剩下真正图像处理方面的东西了。另外现在想说一下,我当时认为的用directshow来在wince下面捕获视频流的想法,在那个时候已经意识到是不可以的了。我在自己定制的平台上,用directshow确实能播放mp3,但是播放不了视频流,然后,还突然意识到,其实驱动是自己写的,那么就可以直接获得驱动中的数据了,没有必要自己再绕一个大圈子。我后来对曾经的男朋友谈起这个,他说,我是有宽敞的大道不走,却去自己走小道,确实如此。我绕了这么大个圈子,然后又回到了起点。另外还要提一下,那个最后作驱动的男生,不管他做得怎么样,但是,有些佩服他的钻劲。不过,他也隐瞒了一个事实,驱动中最主要的还是控制,至少在摄像头中是如此,现在他也只是得到了摄像头的数据而已,当然也是很不错的了,但是,在一个论坛上说的一句话让我现在记忆仍然深刻,那就是得到数据只是工作的三分之一,剩下的大部分的工作在对摄像头的控制方面。不过,如果让他在这样做下去,也是难为他了。因为,其实,现在他也不想做了,很明显的。于是很糊涂,这两个月就这样过去了。看了一些系统方面的文章,了解了一下操作系统,PlatformBuilder,和usb协议,也就是这样了。
4。2004年12月。这个月是属于堕落的一个月。在这个月中,我做了一下图像处理,看了一下图像处理方面的书籍,也问了一个做图像处理的师兄,师兄对我的问题给了很热心的回答。他建议我先看看matlab的图像处理,也介绍了一本图像处理方面的书给我看,后来我弄到了这本书的电子版。师兄说得对,图像处理方面的还是应该先看看matlab,学会了思想,看到了效果,然后再用vc编程实现也是可以的。后来为了图像处理的方便,我做了一个模板,以后做图像处理,就可以直接用这个模板了,只需要改其中的很小的一部分。上个星期,做了一个filter,用在directshow上面的,很简单,不过发现自己的想法很幼稚,这是后话。
最后,要谢谢所有帮助过我的人,谢谢!虽然我这个学期没有做什么工作。