[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

程序设计启示 (摘记)

刚开始看代码大全,真是大部头,不知道毕业之前能不能看完,或者看完的时候有没有毕业…(泪)。应该是还没有看到干货部分,不过对于程序设计里的问题,有很多很好的总结,所以摘录一点在这里。这部分原文是 Design Heuristics,直译应该是“设计启示”,可是我觉得应该算是一些心得。想起来以前在图书馆见过有一本书叫做《软件启示录》,按照当年的习惯,应该看过并且仅看过前言 ^^ 罗列一下书上的总结,就不瞎翻译了。 Major Heuristics Find Real-World Objects Form Consistent Abstraction Encapsulate Implementation Details Inherit When Possible Hide Secrets (Information Hiding) Identify Areas Likely to Change Keep Coupling Loose Look for Common Design Patterns Useful Heuristics Aim For Strong Cohesion Build Hierarchies Formalize Class Contracts Assign Responsibilities Design for Test Avoid Failure Choose […]

Nested Array in Bash

用了Bash这么久,才知道Bash支持Array。但是却缺乏对嵌套数组,或者是多维数组的支持。自己的实验里面需要用到结构性的数据,这样看起来或者改起来会比较方便,而且因为这部分是用来处理实验结果,需要经常修改,所以不适合放到C++里面去写。 因此就有了需要Bash支持嵌套数组的需求。 最终的解决方法不是很漂亮,但是也足够我自己用了。这个想法的出发点是这样的: Bash在处理数组的时候会用到IFS这个环境变量。比如这样一段字符 Li,Age*1;Weight*2;Height*3;Friends*Sun^Wang Wang,Age*11;Weight*12;Height*13;Friends*Li^Sun 如果IFS是空格,我们就可以得到两个元素 Li,Age*1;Weight*2;Height*3;Friends*Sun^Wang Wang,Age*11;Weight*12;Height*13;Friends*Li^Sun 如果IFS是分号(;),我们可以得到另一个数组 Li,Age*1 Weight*2 Height*3 Friends*Sun^Wang Wang,Age*11 Weight*12 Height*13 Friends*Li^Sun 也就是说我们可以通过指定不同的IFS让一段字符成为不同的数组。 所以,我们可以通过对每一层使用不同的IFS来表达一个嵌套数组。比如上面那段字符,我们用不同的IFS字符,先用空格( ),再用逗号(,),之后用分号(;)…… 如此做下去就可以达到层层盘剥的效果(-_-!) 在实际使用中,我们只要保证每一层用到的IFS不会在数组内容中出现就行了。 为了能够生成那样一段字符,我们自然需要一些函数做辅助。 具体的代码放到Github上了。目前这个方法虽然有效,但是使用起来仍然不够简洁,看起来如果找不到更好的Bash下的解决方法,就得考虑换用一种20世纪的脚本语言了… Github: Nested-Array-Bash

最近

已经好久没有写东西了,三言两语也是一种存在。前两天把文章投出去,这个学期也快要结束了。 真是充实的一个学期,短短不到三个月的时间里:mm过来,生活状态上带来了不小的变化,体重上来好几斤;第一篇文章被接收,总算有了Publication,感觉挺欣慰;之后是自己的PhD资格考试,严肃地讲了一次自己的工作;接着接着就是做新的文章;最后就是还没有结束的TA,第一次做助教,给小本上复习课感觉压力山大。 之后做什么呢?要做新的东西,要去学开车,暑假要去实习。很是期待暑假的实习,可以见见同学,可以看看另外一种生活状态。埋着头,慢慢走吧。忽然很想听崔健。

rand函数不可重入

写C代码的时候,srand(int seed) 和 rand() 是常用的伪随机数生成函数。 这两个函数的使用方法很简单,但是一个可能被忽略的细节是,rand() 依赖一个内部的、全局的状态变量。所以 rand() 是不可重入,也是不是线程安全的 (thread-safe) 。 如果多个线程同时调用 rand() 函数,那么无论你如何使用 srand(int seed) 都无法保证结果是可以重现的。每次运行程序,各个线程中 rand() 函数生成的伪随机数序列都和上次不同。 在调试的时候,不能重现的结果会是比较棘手的障碍。 幸好,我们可以用C++11 提供的伪随机数生成器 Pseudo-random number generation (这么翻译好机械-_-!)用法很容易在网络上找到,这里有一个最简单的例子。 #include //….. { std::default_random_engine gen(0); int a_random_number = gen(); } default_random_engine维护自己的内部状态,各个线程都用同样的参数初始化default_random_engine,就可以得到一致的伪随机数序列了。