2007年5月29日星期二

Testing Davison's MonoSLAM(Updated!)

Two months ago, I tried Davision's MonoSALM which is very interesting. For research convenience, I successfully ported the project to both linux(ubuntu 6.10 & 7.04, gcc-4.1.2) and windows(WinXP,VS2005) platform with USB camera support. Similar work has been done by Bob Mottram, where he translated the project into c#.

As some other researchers may be interested in Davison's MonoSLAM, and just like me, want to experience the demo under both windows and linux with USB Camera support. So at here, I took down some of the key tips of my porting experience.

1.USB camera support
Davison's original demo only support 1394 camera under linux, but I didn't have one. So first I added USB camera support in order to experience the demo.

1.1 Under linux -- V4L2 Support
The following work was done under ubuntu 6.10 & 7.04(gcc-4.1.2), and you many have to change it for some other linux versions.

Download v4l2 driver according to the kernel version and install it properly. Try spacaview(availabel on the same website) to test the USB camera. A list of supported USB camera can be fond here, which includes almost all the popular USB camera.

Spcaview is a smart but powerful tool to control the USB camera under linux, and it provides a good encapsulation to V4L2 APIs. I extraced some of the source code and built them into a library(libspcav4l) for easy usage in other applications. My transported project uses this library too.

The VW34 library used by MonoSLAM provides an abstraction to the manipulation of image source, either from file sequences or video capture device. Its general mechanism looks like this :
1) A looper runs continuously on the backgournd to read image file or capture video data from the caputre device. Once it gets the image data, it then notify the upper layer(image processing layer) to fetch the data.
2) The upper layer responds to the notification from the lower loop and process the image data in a callback function registered during the initialization phase.

One of the drawback of this mechanism is that, the looper runs continuously and takes up a lot of CPU resources. In fact, the approach adopted by windows' WDM driver is much more reasonable and elegant : whenever the video data arrives, WDM notifiles the upper layer to fetch it. That is a interruption approach, not loop approach.

The related code can be found at VW34/VWGLOW/Interface folder. Refering to VW34/VWFirewire, I added an interface named VWUSBCam, which calls functions in libspcav4l and added VWUSBCam interface to MonoSLAMGlow/monoslamglow*. Now the USB camera works for MonoSLAM!


1.2 Under Windows -- DirectShow Support
DShow provides a routine to easily manipulate the usb camera. Same as under linux, I added usb camera support with DShow to VWUSBCam interface.


2. Poring to Windows
It's usually troublesome to port a linux application to windows, especially when the application uses many libraries under linux. Fortunately, Oxford's VW34 is designed to be platform independent, and that saved me a lot of time. monoslamglow and scenelib are purely coded with c++, which is also cross-platform.

STL can be seen everywhere in Davison's MonoSLAM. This is good, for STL is efficient and elegant. But some fatal bugs lurk in the code due to the misusing of STL, for example vector::erase. Scott Meyer's Effective STL is really a good reference to write both effective and robust code with STL.

As VC6 does not fully support templates, so I chose VS2005 to compile the projects. Some additinal libraries should be prepared first. They are :

glut-3.7.6 : opengl wraper
wxWidgets-2.6.4 : wxWidgets support

Both the two libraries are platform independent and you can get them freely.I compiled and build them into static libraries.

other libraries used in MonoSLAM :

glow_104
scenelib
vw34

All the libraries are compiled into static libraries. The compiler may complaint "unresolved link" or some other errors due to the project setting or syntax problem. Just follow these prompts and fix them one by one.
What I want to mention is that, VW34 wrapps VNL which is part of VXL library, and after successfully compiling of the source code, plenty of "multiple symbols error" prompts may jump out while linking. I checked the VXL's FAQ and found the solution :
change the project setting in VS2005 as following :
Project->Settings->C/C++ Tab->Category: Code Generation->Use run-time library: Multithreaded DLL

Now I have a copy of MonoSLAM runs on windows with USB camera support. Next I fixed some treacherous bugs mainly due to the misusage of STL.

3. Fix bugs
Here I listed several most treacherous bugs of MonoSLAM. The amazing thing is that, these bugs keep quiet under linux, due to difference between gcc & vs2005 compiler, as well as the difference between implementations of SGI's and Microsoft's STL.
But, in my view, they are really bugs, and linux just "hides" them! So I'll list them up and give the solutions respectively.

3.1. Multiple Inheritance
The first problem encountered is that, once the main GUI window redrawed, it crashed.
It is very curisou, and may be cased by the bugs in wxWidget, opengl, glut or glow. And I had on idea of it ~~

As usual, I debuged the code, and looked deep into the whole mechanism of the paint procedure of monoslamglow. Same as other GUI applications, the mechanism is message driven and call a callback function to redraw the window. After carefully tracking all the variables, I found the handler of the callback object changed during the process which crashed the application!

The inheritance tree looks like this :

MonoSLAMGlow
<-- GlowWindow <-- VWEvents::EventHandler <-- GlowPushButtonReceiver <-- GlowCheckBoxReceiver Multiple inheritance is complicated, especially when vitual inheritance is involved. You can get a idea of how complicate it is from Lippman's Inside the c++ object model.

All the four base class has virtual functions. The handler to callback object invalidated when converting to VWEvent::EventHandler polymorphicly. Lippman pointed out that the polymorphism of c++ itself is very complicate which involves adjusting pointer's address and the actual implementation is compiler-dependend.
I found that the adjusted address of pointer to the derived class had an addrss offset compared to its actual address. So, I adjusted the inheritance order of the base class, that was, put VWEvent::EventHandler at the first place, and the GUI application worked fine!

3.2. STL's pitfalls : vector::erase
Scott Meyer pointed out some dark corners of the c++ language and STL's pitfalls in effective stl. And it happened that Davison's MonoSLAM was caught by one of the pitfalls, that was vector::erase !

After erasing an object from a vector, all the iterators previously pointing to the object in the vector will be invalidate.

The above rule was emphasized again and again by Meyer. Though simple, yet easy to fall into this pitfall, as MonoSLAM did.

At first, MonoSLAM crashed for the error "incompatible iterator!" after running for a short while. Curious error, isn't it ? Experience told me that something may be wrong with stl's container, such as vector, map, set, list, etc. But locating the error was rather difficult because stl's container appeared everywhere in the code. After a careful debugging and scrutinizing the code, I found following code :

for(vector::iterator feat = feature_init_info_vector.begin();
feat != feature_init_info_vector.end();feat ++)
{
if(feat->...){}
else{
delete_partially_initialised_feature(feat); // call vector::erase inside
}
//...
}

similar codes could be found at other places.

It seemed pretty good from logical sense: go through all the objects in the vector and delete unqualified ones.
But it was wrong, according to the above rule!

Once feature_init_info_vector deleted an object, it would reallocate memory and copy the remaining object into new memory. So the feat iterator invalidated after calling delete_partially_initialised_feature, in other words, feat pointed to a old, invalidated memory object, not that in the new allocated feature_init_info_vector! That's why the application complained for "incompatible iterator"!

The solution is very easy, with Meyer's advice, return a iterator pointing to the new allocated feature_init_info_vector and assign it to feat. Ok, that's done !

4. Conclusion
Above is my experience with porting MonoSLAM to windows with USB camera support. Currently, it works well under both linux and windows. There may be some other hidden bugs, I'll fixed them when they emerges.

2007年5月28日星期一

book recipes

comments on some of the books read during spare time.

1. A first course in probability
Ross, Sheldon M.

An excellent book on fundermental concepts of probability with so many interesting examples which bring me good execises on logical reasoning.

2. Cg--A tutorial on Real-Time programming

A tutorial on GPU programming.
During my research on CV, I've found many researches turn to GPU programming for real-time performance of their algorithms, such as GPU-KLT, GPU-SIFT. The main idea is to put heavy burdons of computations to GPU in modern graphic cards which are quite suitable for parallel computing with special processing units, such as pixel and vetex shaders.

3. GPU Gems-- Programming Techniques, Tips, and Tricks for Real-Time Graphics

An good book for GPU programming tips and experience.
However it concers so much knowledge on computer graphics, e.g. lighting, shading, I am a little confused by these concepts. If having time, I'll read some books on computer graphic too.

4. Introduction to Algorithm(MIT)

As its title, this book gives me a good and through introduction to algorithms. Really helpful!

cv研究点滴

研究生以来一直在cv中打转,这也看看,那也试试,觉得cv还是很有意思的,如目标识别、匹配跟踪等等。个人觉得此领域非常广,并且逐渐倾向于与AI结合,以更好地模仿人类的视觉过程。这个领域的大牛也很多,看看他们的工作,有时觉得有点不可思议--在计算机上差不多实现了类似于人类的视觉过程或是思维过程,只能望其项背~~

此帖将记录一些个人在cv研究中的点滴体会,差不多是research log吧。

ubuntu的一些使用配置

一年多来一直在ubuntu下工作和学习,这个系统目前不断地在更新,issure a release every half year,确实也挺好用,在此记录一些关于ubuntu使用及配置的方法,为自己和他人提供方便的参考。此帖在今后会不断更新,主要涉及ubuntu下多媒体、编程环境、桌面效果等的配置情况。

1. Bleeding-edge ffmpeg on Ubuntu Feisty

First, get your dependencies:

sudo apt-get build-dep ffmpeg
sudo apt-get install liblame-dev libfaad2-dev \
libfaac-dev libxvidcore4-dev liba52-0.7.4 \
liba52-0.7.4-dev libx264-dev checkinstall \
build-essential subversion

Next, grab the ffmpeg source: svn checkout -r 8998 svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg

If you’re feeling adventurous, you can try the very latest code by omitting the -r 8998 part of that line. Revision 8998 is the latest at the time of writing, and worked for me. Now you can configure and build ffmpeg. This takes a little while:

cd ffmpeg
./configure --enable-gpl --enable-pp --enable-libvorbis \
--enable-libogg --enable-liba52 --enable-libdts \
--enable-dc1394 --enable-libgsm --disable-debug \
--enable-libmp3lame --enable-libfaad --enable-libfaac \
--enable-xvid --enable-pthreads --enable-x264
make

Finally, install it.

checkinstall

gives you the option to edit some parameters: I set the name to ffmpeg and the version to 3:0.svn20070511

sudo checkinstall

2007年5月20日星期日

孤标傲世偕谁隐,花落人亡两不知!

陈晓旭去世了,
林妹妹走了……

她塑造了我心目中的黛玉,或者说她便是黛玉的化身.
每次想到黛玉,眼前总是能浮现出陈晓旭的影子:

"两弯似蹙非蹙罥烟眉,一双似喜非喜含情目;态生两靥之愁,娇袭一身之病;
闲静时如娇花照水,行动出似弱柳扶风;心较比干多一窍,病如西子胜三分。"



帖一首 葬花吟 , 缅怀葬花之人,愿晓旭一路走好...

葬花吟

花谢花飞花满天,红消香断有谁怜?
游丝软系飘春榭,落絮轻沾扑绣帘?
闺中女儿惜春暮,愁绪满怀无释处;
手把花锄出绣闺,忍踏落花来复去?
柳丝榆荚自芳菲,不管桃飘与李飞;
桃李明年能再发,明年闺中知有谁?
三月香巢已垒成,梁间燕子太无情!
明年花发虽可啄,却不道人去梁空巢也倾。
一年三百六十日,风刀霜剑严相逼;
明媚鲜妍能几时,一朝飘泊难寻觅。
花开易见落难寻,阶前闷杀葬花人;
独倚花锄泪暗洒,洒上空枝见血痕。
杜鹃无语正黄昏,荷锄归去掩重门;
青灯照壁人初睡,冷雨敲窗被未温。
为奴底事倍伤神,半为怜春半恼春:
怜春忽至恼忽去,至又无言去不闻。
昨宵庭外悲歌发,知是花魂与鸟魂?
花魂鸟魂总难留,鸟自无言花自羞;
愿奴胁下生双翼,随花飞到天尽头。
天尽头,何处有香丘?
未若锦囊收艳骨,一抔净土掩风流;
质本洁来还洁去,强于污淖陷渠沟。
尔今死去侬收葬,未卜侬身何日丧?
侬今葬花人笑痴,他年葬侬知是谁?
试看春残花渐落,便是红颜老死时;
一朝春尽红颜老,花落人亡两不知!