Category: Computer Vision (机器视觉)

[Note] Learning to See by Moving

这是一篇用CNN做特征学习的文章,题目比较格调。目标是训练得到可以用来做场景识别、物体识别等等任务的特征。 和之前的工作相比,训练时需要的监督信息不是图片所属的类别,而是两张图片之间的位置变换。准确地说,是拍摄两张相关图片的相机的相对位置变换。 具体的网络结构如上图。输入两张图片,训练这个网络来判断两张图片之间的变换(Transformation)。每两个BaseCNN取得的特征(Lk)连接起来作为TopCNN的输入,TopCNN输出变换向量。训练结束之后TopCNN就不用了,直接用BaseCNN对输入图片取特征。 在使用相同数量的有标记数据的情况下,用这种相对更容易得到的监督信息训练出来的网络来做分类网络的初始化,比随机初始化分类效果更好。 虽然这个方法并不是完全的无监督学习,但是在移动机器人这种平台上,两张照片的相对位置变换确实是很容易得到的信息。按照这种方法确实可以很方便的给机器人增加场景识别功能。理想情况下,只需要在所在环境下移动的时间采集一些图片来学习特征,简单的通过人机交互标定几个场景,这种用CNN得到的特征应该会有很不错的表现吧。 Reference: Pulkit Agrawal, Joao Carreira, Jitendra Malik, Learning to See by Moving

[Note] Discovering Hidden Factors of Variation in Deep Networks

一篇很有意思的文章。在一个半监督学习的框架下把需要预测的部分和其他隐含的变化因素(Hidden variations)分开。 比如我们现在的问题是表情分类,给定七种不同的表情,喜怒忧思悲恐惊(老中医..),我们可以训练出一个来判断任一输入图片中人的表情,记为\(y\)。 于此同时,我们还从输入图片中得到了代表其他和任务无关部分的信息,记为\(z\)。具体来说,两个不同的人的照片可以是同样的表情。但是除了表情相同之外,两张照片因为来自不同的人当然有很多其它的不同。除了表情之外其它的隐含信息就是\(z\)。 具体的实现上是基于auto encoder的,在encoding的时候设置两部分输出\(y\)和\(z\)。其中\(y\)的部分就同有监督学习一样。 目标函数: \[ \hat{\theta}, \hat{\phi} = \arg \underset{\theta,\phi} \min \sum_{\{x,y\}\in \cal{D}} \alpha U(x,\hat{x}) + \beta S(y,\hat{y}) + \gamma C(\hat{y},z) \] 其中\(\hat{\theta}, \hat{\phi}\)是encoder和decoder的参数,\(\alpha,\beta,\gamma\)是个部分的权值。第一部分就是auto encoder的无监督学习,第二部分是针对需要预测的量的有监督学习,第三部分是作者提出的 cross-covariance penalty (XCov)。目标函数的第三部分XCov意在最小化\(y\)和\(z\)的相关程度,让两者分开。 实验部分也很有意思,给定一个输入图片得到\(y\)和\(z\)之后。可以固定\(z\)然后改变\(y\),从而使得decoder部分可以重建出同样一个人的不同表情。 Reference: Brian Cheung and Jesse A. Livezey and Arjun K. Bansal and Bruno A. Olshausen, Discovering Hidden Factors of Variation in Deep Networks,

[推荐] 王天珍老师的文章

来自科学网博客,王天珍老师的博文: 视觉研究的前世今生(上) 视觉研究的前世今生(中) 视觉研究的前世今生(下) 虽然很多概念不是很明白,但是感觉非常值得一读。这不是关于Computer Vision的研究,主要讨论是对人类视觉的研究。一开始读起来感觉像是在回顾很久远的时代里人们对人类视觉研究的初步探索,读到最后才惊觉原来人们至今对人类视觉的原理仍然知之甚少。我不觉得CV一定要去模拟生物特性来才能得到好的效果。但是人类视觉毕竟是一个强大复杂的系统,非常的有意思。 看到这些文章就想起来上次CVPR上的关于Professor Tsao的邀请报告,讲到她们对猴脑是如何响应视觉刺激而对猴脑的不同部位的不同刺激又是如何影响到视觉感知的研究。虽然我们的CV算法已经可以在很多视觉任务上面得到很好的结果,但是我们对于人类的视觉系统似乎还是不甚了解啊。

[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:

[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

[CV]检测灰色块

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