Haoxiang Li

[Code] Mixture-of-Gaussian C++ 实现

一个拟合高斯混合模型(GMM)的C++实现: https://github.com/CVLearner/Mixture-of-Gaussians 只依赖于Eigen,但是因为Eigen可以用到MKL的LAPACK/BLAS实现,所以间接地可以利用MKL加速。相比于OpenCV的实现,一个好处是可以用到多核。所以目前速度尚可,但还有提升空间。感觉上Eigen并没有完全利用到MKL的速度。

[CV]人脸识别检测数据集

做了一段时间的人脸识别和检测,在这里列一下用过的数据集。基本上,大家近期也都是在这几个数据集上检测自己的算法。网上这方面的总结虽然不少,但是一则有些是多年前的数据,或是规模太小或是链接已经失效,再则是数据集的测试协议定义不明,不尽适合用来和其它方法做比较。 1. Labeled Faces in the Wild: 做人脸识别,准确的说是人脸验证(Face Verification),UMass的LFW估计是最近被用的最多的了,LFW采用的测试协议也已经被几个新的数据集沿用了。人脸验证是指,给定两张人脸的照片,算法需要判断它们是不是来自同一个人。最新的结果(ICCV2013),在限制条件最少的协议下,识别的准确率现在已经高达96%了。[广告^_^] 在限制条件最严的协议下,我们的CVPR2013的结果曾经是最好的。最近被Fisher Vector超过了.. 我们还会回来的… 2. YouTube Faces DB: YouTube Video Faces也是用来做人脸验证的,和LFW不同的是,在这个数据集下,算法需要判断两段视频里面是不是同一个人。有不少在照片上有效的方法,在视频上未必有效/高效。[广告^_^] 在这个数据集上,我们的最新的结果超过81%,目前还没有看到更高的准确率。 3. FDDB: FDDB也是UMass的数据集,被用来做人脸检测(Face Detection)。这个数据集比较大,比较有挑战性。而且作者提供了程序用来评估检测结果,所以在这个数据上面比较算法也相对公平。FDDB的一个问题是它的标注是椭圆而不是一般用的长方形,这一点可以会导致检测结果评估不准确。不过因为标准统一,问题倒也不大。[广告^_^] 我们ICCV2013的文章在这个数据上面有不错的结果。 4. The Gallagher Collection Person Dataset: 这也是一个做人脸检测的数据集,是Andrew Gallagher的家庭相册。虽然不是给人脸识别设计的,但是很接近实际应用的场景。很适合用来测试自己的方法。 5. The Annotated Faces in the Wild (AFW) testset: 这还是一个做人脸检测的数据集,随UCI的Xiangxin Zhu在CVPR2012的文章发布。值得注意的是在他们的主页有公开的源代码。虽然人脸检测做了很久,但是效果比较好的,可以在网上方便的得到的检测库除了OpenCV以外并不多见。 6. CMU Dataset: 做人脸检测的数据集,这是一个很有些年头的数据集了,虽然大家最近不常用这个数据,但是这不代表这个老数据集很容易对付。最新的检测算法往往需要比较稠密的取比较复杂的特征,这在这个黑白而且分辨率不高的数据集上未必可行。 7. POS Labeled Faces in the Wild: […]

[Bug] g++4.6 参数顺序

遇到一个bug, 看起来像是g++-4.6的问题。 问题是这样的。这个源文件用到了OpenCV: //< file: test.cpp #include int main (int argc, char** argv) { cv::Mat image; return 0; } 用这样一行命令编译: g++-4.6 `pkg-config --libs opencv` -o test.bin test.cpp 遇到了错误: /tmp/ccs2MlQz.o: In function `cv::Mat::~Mat()': test.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)' /tmp/ccs2MlQz.o: In function `cv::Mat::release()': test.cpp:(.text._ZN2cv3Mat7releaseEv[cv::Mat::release()]+0x47): undefined reference to `cv::Mat::deallocate()' collect2: ld returned 1 exit status 错误的原因应该是g++没有正确的链接到OpenCV的库。各种尝试之后发现只要调换一下参数的位置就可以正常编译 -_-!! 改用这样一行命令编译就没有问题了。 […]

[Vim]用行号参与替换

一个小技巧。Vim有好处千种,”替换”只是其中一个。 除了强大的正则表达式,\=也是一个好用的工具。 比如要生成这么一个文件 This is number 1 This is number 2 This is number 3 This is number 4 This is number 5 This is number 6 This is number 7 This is number 8 This is number 9 This is number 10 方法当然有很多。用\=可以这么做: 先输入一行 This is number X 复制出另外9行 yy9p 得到 This is number […]

[OpenCV] detectMultiScale: output detection score

OpenCV provides quite decent implementation of the Viola-Jones Face detector. A quick example looks like this (OpenCV 2.4.5 tested): // File: main.cc #include using namespace cv; int main(int argc, char **argv) { CascadeClassifier cascade; const float scale_factor(1.2f); const int min_neighbors(3); if (cascade.load(“./lbpcascade_frontalface.xml”)) { for (int i = 1; i < argc; i++) { Mat img […]

PhD们的总结

感叹一下,牛人们不但paper写得好,也很善于总结经验。 一早(好像也不早了…)在Facebook上看到行内CMU牛人田渊栋的PhD生涯总结,行文流畅,条理清晰。不在这里贴全文了,可以在这里看到: [1] 博士五年总结 (一) – 田渊栋 [2] 博士五年总结 (二) – 田渊栋 [3] 博士五年总结 (三) – 田渊栋  写得太好了,值得花时间好好读一读。 也可以对比之前比较火的MIT的Philip Guo的Ph.D Grind看看: Ph.D Grind – Philip Guo 

[CV]检测灰色块

遇到一个看起来非常简单的问题:一张图片里面有一些某种颜色的色块,怎么样找到它们? 比较囧的是这个问题的起因。因为图片的标注文件丢了,不得不这么反向做检测来找回这些标注…想想人脸那么麻烦的结构都可以被检测出来,CV对付这种几乎完美的单颜色色块应该是小菜一碟吧。所以,大家虽然感觉反向检测自己处理的图片比较囧,但是完全不觉得这是个问题。同屋的哥们当场表示,他可以在10分钟之内搞定。 他的做法是我们一开始的想法,先按照色块的颜色(RGB: 128,128,128)把图片二值化,由于JPEG压缩,色块可能会有噪声。 然后我们准备对每行求和,对每列求和,会得到两个“直方图”,然后根据“峰”的位置和宽度就可以知道色块的位置和大小了。这个方法的确可以处理一张图里只有一个色块的情况,但是当图里有多个色块的时候,会出现“峰”的叠加,比如这张图,按行求和之后,由于有并排的色块。直方图就会变成这样: 这种情况之前这种方法就不好处理了。 结果这个看起来非常简单的问题,我们也折腾了好半天。最后还是得人指点,用连通分量来做,才得以解决。 做法是在二值化的图像上,找到不同的连通块 (Connected component),然后留下比较大的,就是灰色块了。为了处理噪声,当然需要用Gaussian做一做模糊之类的。效果还不错。(彩色色块表示检测出来的灰色色块) 问题总是没有看起来的那么简单。 matlab 代码放到 Github 上了: detect-gray-square