目录
5 基于LBP特征检测的人脸检测实现(opencv+python)
1 LBP简介
LBP指局部二值模式(Local Binary Pattern),是一种用来描述图像局部特征的算子,具有灰度不变性和旋转不变性等显著优点,LBP常应用于人脸识别和目标检测中。
补充知识:
1. 灰度不变性:所谓的灰度不变性,指的是光照变化是否会对描述产生影响以上面的8邻域为例,
光照变化是很难改变灰度值83与其周围8个像素的大小关系的。因为光照是一种区域性质的变化,
而不是单像素性质的变化。所以比如有一个强光照在这9个像素上面,
这9个值应该是都会增大,但是相对的大小关系仍然是会编码成右边这样的一个二值图。
2. 旋转不变性:就是一个体系转动了之后,和转动之前一样,看不出差别。
3. 纹理特征:纹理是一种反映图像中同质现象的视觉特征,
它体现了物体表面的具有缓慢变化或者周期性变化的表面结构组织排列属性。
纹理具有三大标志:某种局部序列性不断重复、非随机排列、纹理区域内大致为均匀的统一体。
2 LBP原理简介
!!! 上边是公式推导,下面进行通俗解释:
这里这个19就是上边公式中T的值,公式中t表示将二进制转换为十进制。
!!! 再通俗的解释一下:对LBP特征向量进行提取的步骤 (举例步骤) ------------------>
(1)首先将检测窗口划分为16×16的小区域(cell);
(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;
(3)然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理。
(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;
然后便可利用SVM或者其他机器学习算法进行分类了。
3 圆形LBP算子
基本的 LBP算子的最大缺陷在于它只覆盖了一个固定半径范围内的小区域,这显然不能满足不同尺寸和频率纹理的需要。为了适应不同尺度的纹理特征,并达到灰度级和旋转不变性的要求,Ojala等对 LBP算子进行了改进,将 3×3邻域扩展到任意邻域,并用圆形邻域代替了正方形邻域,改进后的 LBP算子允许在半径为 R的圆形邻域内有任意多个像素点。
具体可以参考:https://blog.youkuaiyun.com/zfjBIT/article/details/90637779
4 LBP旋转不变性及等价模式
具体等价模式详细解释,可以参考如下链接说的比较好:https://blog.youkuaiyun.com/heli200482128/article/details/79204008
5 基于LBP特征检测的人脸检测实现(opencv+python)
- (1)需要使用OpenCV的LBP于预训练模型
- (2)可以直接调用opencv的基于lbp巡检好的人脸检测算法调用。将haarcascade_frontalface_default.xml下载至本地以方便调用,下载链接:https://github.com/opencv/opencv/blob/master/data/lbpcascades/lbpcascade_frontalface_improved.xml
- (3)具体python实现代码如下:
#coding:utf-8
"""
LBP特征用于人脸检测...
"""
import cv2 as cv
# 读取原始图像
img = cv.imread('data/dahuaxiyou.jpg')
# 训练好的LBP,人脸检测模型
face_detect = cv.CascadeClassifier("lbpcascade_frontalface_improved.xml")
# 灰度处理
gray = cv.cvtColor(img, code=cv.COLOR_BGR2GRAY)
# 检查人脸: scaleFactor表示每次图像尺寸减小的比例, minNeighbors表示每一个目标至少要被检测到3次才算是真的目标
face_zone = face_detect.detectMultiScale(gray, scaleFactor=2, minNeighbors=3) # maxSize = (55,55)
print('识别人脸的信息:\n', face_zone)
# 绘制矩形和圆形检测人脸
for x, y, w, h in face_zone:
# 绘制矩形人脸区域
cv.rectangle(img, pt1=(x, y), pt2=(x+w, y+h), color=[0, 0, 255], thickness=2)
# 绘制圆形人脸区域 radius表示半径
cv.circle(img, center=(x + w//2, y + h//2), radius=w//2, color=[0, 255, 0], thickness=2)
# 设置图片可以手动调节大小
cv.namedWindow("Easmount-优快云", 0)
# 显示图片
cv.imshow("Easmount-优快云", img)
# 等待显示 设置任意键退出程序
cv.waitKey(0)
cv.destroyAllWindows()
(a)运行输出结果 (即人脸信息的坐标) ---------------------->
(b)原图效果 --------------------------------------------------------->
(c)检测效果 ------------------------------------------>