THE FASTEST C++ IMPLEMENTATION FOR ORIGINAL DPM — SOURCE CODE DOWNLOAD - BUG Fixed

本博客已经搬家!我已经在CSDN上重新注册了一个博客,该博客将不再使用,新博客地址:

http://blog.csdn.net/YU_Xianguo/article

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


此前我已经将Cascade DPM的C++代码以及Original DPM的C++编译库发布出来,很多人给我发邮件,希望能得到Original DPM的C++代码,现在我就把这个源代码发布出来。

发布内容:Original DPM,我也称之为完整版DPM,是Pedro. Felzenswalb发明的”deformable part based models for object detection”的程序实现,原始程序和参考文献已经在我另一篇文章cascade DPM – C++ implementation – open source里列出了,这里不再赘述。我的工作是将原始的Matlab代码voc-release5中检测部分用C++实现。检测部分有完整版DPM的,也有star-cascade版的,后者的c++程序之前已发布,这里发布的则是完整版DPM的C++代码。

为什么Original DPM?首先,原始的DPM算法充分体现了基于部件模型的目标检测思想,与P.Felzenswalb关于在语法框架下进行目标表示和检测的思想相应,学习该程序能较好地理解作者的目标检测思想,而级联是更早就有的一项技术,其主要思路是将任务分解成一步步去做,在每一步做完都检查一下有没有继续做的必要,这是一个相当工程的东西,在boost分类器里面就有级联思想,并非P.F教授的首创。第二,与级联算法相比,原始DPM的检测效果更好,一般训练一个级联分类器首先要训练原始DPM模型,然后继续在数据集上挖掘信息(PCA、级联训练)来得到级联模型。级联模型对训练数据集更加依赖,相比之下,原始DPM的推广能力要强得多。

本文发布的C++代码有什么特色?网上应该可以找到多个不同的关于原始DPM的C/C++实现,其中我觉得最好的一个版本便是集成在openCV库中的”latentSVM”算法(其实就是DPM的检测部分),与该代码相比,本文公布的代码更快、效果更好!原因在于:一、我写代码严格参照voc-release5的matlab代码,其计算结果和matlab代码完全一致!(matlab代码中的图像缩放用的resize函数是作者自己编写的,而我的代码是用openCV自带的图像缩放函数——速度更快,这造成了计算结果的些许差异。但是我在调试代码的时候,写过一个函数直接将matlab代码算出来的特征金字塔加载到c++程序里,使用同样的特征金字塔以后,我的代码给出和matlab代码完全一致的结果。)二、我用了近一年时间写这个代码,写代码的同时还在研究原始算法并写自己的硕士论文,通过不断摸索,对算法中很多地方做了优化处理,比如并行化、跳过中间环节的计算等等,直到我认为再也找不到可以减少的计算。

关于代码本身:代码用C++编写,依赖两个公开库——openCV和pthreah线程库。openCV是著名的计算机视觉公开库,不需多说。pthread也是公开的线程库,提供线程管理和互斥锁功能,是linux内置的库,在windows下使用需要下载安装,我在另一篇文章里有说。发布的代码是windows下的visual studio的solution,但程序中没有使用与系统相关的函数,可以很容易移植到linux下使用(实际上我已经在几乎不修改源代码的情况下在Ubuntu下编译并使用过了)。

其它:说一点愿景,关于我为什么公开此代码。说实话,很长一段时间内我都舍不得把该代码给别人,因为它凝聚了我很多心血,不想轻易送人。但是我现在研究方向已经与当初发生了较大变化,与其把这些代码放在我硬盘上最终被遗忘,不如让它们发挥应有的价值。人家P.F教授公开自己的算法代码并获得了VOC官方颁发的终身成就奖,我没人家万分之一牛,但是也希望能为后来者学习提供一些帮助。愿祖国更好!

代码下载:http://yunpan.cn/cLAZYKizwJ5ZH  访问密码 5d36

代码是dpm的检测部分,我已将voc-release5中包含的所有模型文件转化成相应txt文件并上传到网上,需要的话到我的另一篇文章THE FASTEST C++ IMPLEMENTATION OF DPM/LATENTSVM中下载.

代码只包含检测部分,如果你们使用voc-release5的matlab代码训练了自己的模型,可以用如下的m函数将模型保存为txt文件以使用:http://download.csdn.net/detail/j56754gefge/8354899

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2015年11月4日   部分BUG修改

感谢网友的使用和回馈,让我知道了代码中的部分bug,今天我对到目前为止所发现的2个bug作修改。修改后的代码将放到云盘中替换我原来的压缩文件,大家直接点击上文的链接下载即可。下面对这两个bug做出说明。

第一个bug:      感谢湖南师大的李老师的宝贵意见。

有网友反映,当使用自己训练的模型时,程序运行会报错,通过检查我发现这是因为matlab的模型都有一个bboxpred变量,而自己训练的模型里没有这个变量。其实只要自习看一下matlab代码就能发现,在matlab中,process.m文件时这样写的:

    if isfield(model, 'bboxpred')
      bboxpred = model.bboxpred;
      [ds, bs] = clipboxes(im, ds, bs);
      [ds, bs] = bboxpred_get(bboxpred, ds, reduceboxes(model, bs));
    else
      warning('no bounding box predictor found');
    end
  end

也就是说当模型中没有bboxpred变量时,直接忽略相应的步骤就行了。我在写程序时没考虑到这一点,所以造成了错误。

第二个bug:      感谢上海交大的吴同学的宝贵意见。

部分网友质疑我的程序计算得正确性,我在测试程序时针对voc自带的行人模型和车辆模型,用随便挑选的图片进行测试,结果是完全一致的,如下图所示


上图是我将matlab计算出的特征金字塔加载到C程序中得出的结果,是完全一致的。

但是有不少人跟我反应他们自己测试时发现结果不一致,说实话,一开始我是不太相信的,直到湖师大的李老师给我发来了他自己训练的模型,然后我检测发现确实不一样,而且出入较大。再次感谢上交的吴同学,他在很短的时间内就发现了程序中的另一个bug,就是我的FastDPM工程中的apply_rules.cpp / apply_rules2.cpp / apply_rules3.cpp,这三个文件中都有这样一句话:

int rootSym2 = model.RuleData[1].sym_nonTerminal[0];

把其中的1改成component就行了。这是我的失误,实在抱歉得很。

修改后的C程序,使用李老师发给我的行人检测模型,分别使用matlab和C来算(matlab的金字塔算出来给c程序用),最终结果如图所示:


当然,检测的阈值我随手给了个-1,可能不太对,导致结果不好看,但是这不影响我们关注的问题——两个程序给出几乎一致的结果。其中微小的差别很可能是因为我的程序中使用的非最大值抑制函数(NMS)的不同导致的,我的NMS函数继承自P'Dollar大神的工具箱,是个效率更高的方法,但是与matlab函数有略微不同。

还有个需要解释的问题,就是大家看我的程序,会发现我有很多同名文件,比如刚才的applyrules我就有3个文件,这3个文件的功能是一样的,其接口也是一样的,它们在程序中可以互换,也就是说你把主程序调用applyrules3函数的地方改成applyrules1应该不会改变结果,但是计算效率略有不同。第一个版本是最基础的版本,有兴趣看我程序的人,可以先从最简单的版本开始。

本博客已经搬家!我已经在CSDN上重新注册了一个博客,该博客将不再使用,新博客地址:

http://blog.csdn.net/YU_Xianguo/article

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/j56754gefge/article/details/40708679