OpenCV自带的人脸识别方法会识别同一幅图像上所有的人脸,同时也会把并不是人脸的地方识别成人脸,这就对使用者带来不便。那么如何优化这个方法,使其能够正常有效地运行呢?
OpenCV人脸识别的不准问题
上图就是直接使用OpenCV人脸识别方法经常会发生的情况了。对于我目前的使用场景,我只想要图片中识别出唯一正确的人脸。所以我使用了如下两种改进方法:设置ROI和人脸排序。
设置ROI
ROI(region of interest)就是感兴趣区域,在此处具体来讲就是人脸比较容易出现的区域。由于我目前使用的是双目相机,根据双目相机的成像规律,人脸通常会出现在左相机的右侧,以及右相机的左侧,具体可以看下图
从图中可以看出,人脸的图像总是会在左相机的右边,在右相机的左边,因此我把这两个区域设置为ROI,让OpenCV的人脸识别只识别ROI区域,这样非ROI区域就不会被识别了。
具体设置如下:
1 | cv::Rect RectROI1(300, 100, 340, 300); //把ROI画出来,括号内分别是图像的x,y,width,height,注意x轴是从左往右为正,y轴是从上往下为正 |
结果如下图:
可以看到,设置ROI之后,人脸检测的范围就被缩小到大的绿色框内了,识别成功的概率有提升。如果在你的应用场景中,人脸也是会通常出现在特定区域,那么你也可以利用这个方法试一试。
等等,右边图像的背景墙上有一部分还是被当做人脸,如何解决这个问题?
人脸排序
通过大量测试发现,OpenCV误把非人脸区域识别成人脸的情况下,错误人脸bounding-box是明显小于真正人脸bounding-box的,因此可以把识别到的所有“人脸”降序排列,第一个就是真正的人脸啦。
1 | //降序排列 |
结果如图,这样就能确保得到真正的人脸了。这些框框只是为了讲明白是怎么一回事画的,实际上我的工程里面没有画这些红的绿的框,只标出了人脸特征点,需不需要画自己决定。
经过设置ROI和人脸排序两个步骤,OpenCV的人脸识别方法已经有很大的改良了,能够投入正常使用中。除此之外有没有其他比较方便的实现人脸识别的办法呢?你好,有的。那就是Dlib,下一篇文章就介绍如何在OpenCV里面使用Dlib进行人脸识别吧。