效果图闲扯:公司鼓励创新,做了个皮肤检测器,本来的想法是用手机外接wifi摄像头,用摄像头来拍摄皮肤图像的,后来找了几个wifi摄像头的厂家,因价格没谈拢,就不用wifi摄像头了,只用手机自带的相机来获取图像。 下面我写了个 demo 测试,如下图 me
目前实现了皱纹,油份,水份的检测算法,以后还想实现更多功能,比如痘痘数量,色斑检测,年龄预测等等。 人脸检测原理人脸检测就是要判断一张图像是不是人脸,以及人脸的位置。 判断一张图像是不是人脸,先提取图像的 haar-like 特征值,交给 adaboost 算法,它能判断是不是人脸。 提取图片的 haar 特征
假设积分图是 F(x, y),求 Rect(x, y, w, h) 区域和。 // F(x, y) 表示 Rect(0, 0, x, y) 的区域和,f(x, y) 表示 (x, y) 灰度级 AdaBoost 算法先来一个感性的认识。 每来一张图片,提取其特征值 X,用 AdaBoost 算法能判断出 X 是不是人脸。 假设 1 类是人脸类,-1 类是非人脸类,就能分出一张图是不是人脸了。 分类器可以理解为一个函数 G(x),输入特征值 x,返回数值 G(x) AdaBoost 里面有多个弱分类器 (假设3个),组合成一个强分类器,像这样 每个弱分类器有权重 再来个sign(n)函数,sign 返回 n 前面的正负号,0和正数返回 1,负数返回 -1 拓展到 n,最终的判断公式为 输入一个图像的特征值 x,看看返回是 1 还是 -1,就可以判断出是人脸还是非人脸。 其他:w1, w2, w3 一开始不知道是多少,需要训练数据进行多轮的迭代后算出,训练过程就是调整权值的过程。训练完了后,就用这些权值组成的模型,对未知的图像进行分类。 具体的例子有8组包含各种情况的特征值,作为训练数据。
1.初始化 n 组训练数据的权值为 D(i) = 1 / n 2.多轮迭代 2 到 3 的时候,由 1 变为 -1,是一个变化的地方,设定 x = 2.5,意思是在 2.5 的地方切一刀。 下面对 2.5,5.5 进行迭代
误差率写成公式有点晦涩了,用文字描述比较直观,就是把被分类器分错的元素的和权值全部加起来,就是误差率了。
x = 2.5 时,先认为 x <= 2.5 为 1 类,x > 2.5 的为 -1 类 x = 5.5 时,先认为 x <= 5.5 为 1,x > 5.5 为 -1 选个误差小的 0.25,得出第一个分类器 G1 计算 G1 权重公式:(e 是误差率) 该函数图像: 由图像可知误差率 e 越小,w 权值越大。 G1 的误差率 e1 = 2 / 8 = 0.25 w1 就描述了 G1 的重要程度,或者说对一个特征值被分成哪一类的话语权的大小。 接下来要更新以下元素权重: 权重更新公式: 其中常数 Z 是 ki 本轮要计算的元素的权重 按照上面方式,算出新的权重为 D = (0.174721, 0.174721, 0.108426, 0.108426, 0.108426, 0.108426, 0.108426, 0.108426) 可以看出 1, 2 被分错后,它的权值增大了,那么如果后面的分类器再把 1, 2 分错,产生的误差率会更大,因为误差率根据权值和算出的,所以权值大的,会被重点考虑。
x = 2.5 时,误差率为 6, 7, 8 权值和:0.325278 选个误差率小的,即 0.325278,x = 2.5 的,得出第二个分类器 G2 G2 的误差率 e2 = 0.325278 此时,已经得到两个弱分类器,代入 adaboost 算法的公式中 得到模型:
分析 G(x) 得出的结果,发现 1,2 被分错了,还是有误差,说明本例子迭代两次是不够的,还需要更多轮的迭代,减小误差,直到模型 G(x) 在训练数据上的误差为0,再继续迭代下去误差会收敛于一个常数。(详见最后的参考文献) 训练好了一个误差很小的模型 G(x),就可以用该模型去对未知的图像进行分类,分为人脸类和非人脸类,即可检测出一张图像是不是人脸。 |
|