[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:
这个数据我还没有用过,是最近才发布的一个更大型的LFW。可以用来做人脸识别。看起来很不错的样子。

自己感觉比较好用的数据集就是这些了。
感觉不知道应该写点什么,想来还是写写自己专业相关的内容会比较有趣。

[CV]检测灰色块

遇到一个看起来非常简单的问题:一张图片里面有一些某种颜色的色块,怎么样找到它们?
sample-mask
比较囧的是这个问题的起因。因为图片的标注文件丢了,不得不这么反向做检测来找回这些标注…想想人脸那么麻烦的结构都可以被检测出来,CV对付这种几乎完美的单颜色色块应该是小菜一碟吧。所以,大家虽然感觉反向检测自己处理的图片比较囧,但是完全不觉得这是个问题。同屋的哥们当场表示,他可以在10分钟之内搞定。

他的做法是我们一开始的想法,先按照色块的颜色(RGB: 128,128,128)把图片二值化,由于JPEG压缩,色块可能会有噪声。
sample-mask-binarized

然后我们准备对每行求和,对每列求和,会得到两个“直方图”,然后根据“峰”的位置和宽度就可以知道色块的位置和大小了。这个方法的确可以处理一张图里只有一个色块的情况,但是当图里有多个色块的时候,会出现“峰”的叠加,比如这张图,按行求和之后,由于有并排的色块。直方图就会变成这样:
sample-mask-histogram
这种情况之前这种方法就不好处理了。

结果这个看起来非常简单的问题,我们也折腾了好半天。最后还是得人指点,用连通分量来做,才得以解决。

做法是在二值化的图像上,找到不同的连通块 (Connected component),然后留下比较大的,就是灰色块了。为了处理噪声,当然需要用Gaussian做一做模糊之类的。效果还不错。(彩色色块表示检测出来的灰色色块)

large-sample-mask

large-sample-mask-result

问题总是没有看起来的那么简单。
matlab 代码放到 Github 上了: detect-gray-square

CVPR 2012 酱油记

没有文章,老板还是很nice的给了一次去参加CVPR的机会。虽然只是去酱油一把,但是可以到CV三会之一的CVPR看看,还是很高兴的。

提前一天到了罗德岛,这里貌似是美国最小的一个州。风景不错,但是也不觉得有什么很特别的地方。按照会议进程,头两天是Workshop和Tutorial。Tutorial是集中时间讲一个话题,比如这次有Deep Learning, Gaussian Process这种,这里列出了所有的Tutorial,有很多很吸引人的题目。Workshop是做一个小领域的人们讨论这个方向的文章。一趟下来感觉,除了很偏工程的Tutorial,没有事先看看相关的东西就去听还是比较吃力的。相对来说,Workshop比较容易懂。主要是因为Workshop里的文章多,总有一篇适合你… 两天的Workshop和Tutorial覆盖了各个方向,虽然还没有开始主会,已经感觉是码农进了大观园。感叹各种听不懂…

这两天比较有印象的是Perceptual Organization和Biometric Workshop的几篇文章和Vision Industry & Entrepreneur Workshop的两场演讲,Boaz Super列了很多最近的利用CV技术创业的公司,然后用一大堆数据告诉大家,CV是很有前途地。虽然也听了两次Deep Learning相关的Tutorial,唯一有印象的就是Kai Yu的Sparse Coding那场,他的SC相关的文章回头还得找出来看看。

三天主会还是比较紧的。主会时间是早上8点半开始第一场Posters,一天两场Oral,三场Posters,如果Poster很相关的话,基本上一整天都在那些海报前面走来走去。

我感兴趣的Image Classification相关的文章主要是在第二天和第三天。收获确实不小,看到了很多不熟悉的名词,还有些之前没想到的东西。不过也可能是因为自己比较土鳖,看啥都新鲜…可以和作者讨论是比较理想的状态,而且也很有意思,只是文章读得还是少了,能去讨论的情况不多。今年有好几篇讨论Fine-Grained Classification的文章,做这个的可能会越来越多吧。还有就是知道了Transfer Learning这个方向,和Classification也很相关的。训练样本和测试样本不是同一个环境下得到的,这个本身就是比较实际的问题。Object Recognition这块,还是很多文章在讨论BoW之上的改进,有几篇都是在讨论如何加入空间信息,不知道什么时候会有完全不一样的一套模型出来。然后比较有印象的就是各种Simultaneously,比如把分割,分类,标注等等在一个框架下一块儿做完。Oral里面对于Transfer Learning的两篇印象较深,有一篇是Boqing师兄的,讲得很清楚。

这几天,除了看各种文章,就是看到了各位大牛小牛,认识了一些朋友,不过因为没有文章,也不是很容易讨论起来…还有就是遇到了很多科大的师兄,还有同一级的同学,我科的各位一如既往的给力而且Nice,相当高兴。

有一天吃晚饭的时候因为没有找到地方,和三个外国朋友一桌。有一位是开公司的,不住的抱怨现在CVPR里能用的东西太少,算法太慢。想来也是,现在在做的分类算法就根本不能放在机器人上去用。不过技术总是厚积薄发的,总是很多人做了很久,然后忽然一个突破。虽然取得突破的方法可能看起来全新,之前做的那么多东西都没用上,但是前面的积累想来也是必要的吧。XD

2012.6.20 在回程的大巴上

SSE2 Vector Operation by Vlfeat

If you are writing something involving the math between vectors in C/C++, you may want to check out Vlfeat (http://vlfeat.org).

It is designed to be a library for Computer Vision related stuff, but it also bring you a wrapper for SSE2 acceleration for vector computation.

Say your original code for the calculation of vectors product looks like this:

float productOfVectors(const float *vecA, const float *vecB, const int dimension) {
   float value = 0.0f;
   for (int i = 0; i < dimension; i++)
   {
        value += (vecA[i] * vecB[i]);
   }
   return value;
}

It can save you time significantly by adding vlfeat to your project and replace it with this:

float productOfVectors(const float *vecA, const float *vecB, const int dimension) {
   float value = 0.0f;
   vl_eval_vector_comparison_on_all_pairs_f(&value, dimension, vecA, 1, vecB, 1, vl_get_vector_comparison_function_f(VlKernelL2));
   return value;
}

It's pretty easy but it really works. It takes use of the SSE2 instructions provided by your CPU which result in an non-trivial acceleration when you are doing large scale computation.

You can find more supported forms of calculation here, thanks for the developer's good job.