LBP(Local Binary Pattern),局部二值模式
一种描述图像局部纹理特征的算子
主要思想:: 通过比较图像区域中每个像素点与其邻域内像素点的灰度值,利用二进制模式表示的比较结果来描述图像的纹理特征。
keywords:邻域,灰度值,比较,直方图。
LBP性质
1.灰度不变性:光照难以改变各个像素块之间的大小关系。
2.旋转不变性
LBP特征向量提取步骤
1.检测窗口划分为16*16的区域cell。
2.对每一个cell进行如上比较,查收内哼8位二进制数,得到窗口中心像素点的LBP值。
3.计算每一个cell的直方图,并归一化。
4.将每个cell的直方图连接成一个特征向量。
5.用机器学习算法分类
人脸检测代码实现
参考: https://blog.csdn.net/hzy459176895/article/details/106984684?utm_medium=distribute.pc_relevant.none-task-blog-utm_term-6&spm=1001.2101.3001.4242
说明:opencv有训练好的人脸检测算法:https://github.com/opencv/opencv/blob/master/data/lbpcascades/lbpcascade_frontalface_improved.xml
#coding:utf-8
"""
LBP特征用于人脸检测...
"""
import cv2 as cv
# 读取原始图像
img = cv.imread('D:\DigitalGaphicsProcessing\hezhao1.jfif')
# 训练好的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("FACE", 0)
# 显示图片
cv.imshow("FACE", img)
# 等待显示 设置任意键退出程序
cv.waitKey(0)
cv.destroyAllWindows()
效果图
用了一张超越妹妹的图像,识别的很好。但是如果图片有闭着眼睛的人或者多个人脸,识别效果就会大打折扣。
输出结果是人脸的坐标
HOG(Histogram Of Oriented Gradient),方向梯度直方图
计算水平和垂直方向的梯度,再计算梯度的直方图。
计算过程太复杂了就不说了。
HOG特征提取方法:
1.对灰度图像进行颜色空间归一化(Gamma校正法)
2.计算每个像素的梯度(大小and方向)
3.将图像分为cell(像上面LBP一样),统计每个cell的梯度直方图,形成每个cell的descriptor。
4.将每几个cell组成一个block,这些cell的descriptor串联起来得到该block的HOG的descriptor。
5.同理,将所有block的descriptor串联起来得到该图像的HOG的descriptor。
人物识别代码
参考:https://blog.csdn.net/weixin_43955530/article/details/91971179?biz_id=102&utm_term=HOG%E5%88%86%E7%B1%BB%E8%AF%86%E5%88%AB%E8%BD%A6%E8%BE%86&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-2-91971179&spm=1018.2118.3001.4449
import cv2
import numpy as np
def is_inside(o,i):#如果o框在i框里面,那么就返回True,否则,返回False
ox,oy,ow,oh = o
ix,iy,iw,ih = i
return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih
def draw_person(image,person):#给检测出来的人画框
x,y,w,h = person
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,255),2)
img = cv2.imread('people1.jfif')
#opencv自带的HOGDescriptor可以检测人,作为检测人的默认检测器
hog = cv2.HOGDescriptor()#定义一个模型
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())#分类是基于人的分类
found,w = hog.detectMultiScale(img)#这里用detectMultiScale来加载图像
#print(found)#found是矩形框的信息,坐标和宽高
#print(w)#w得到的是每一个矩形的置信度
found_filtered = []
for ri,r in enumerate(found):
# print('ri:',ri,'r:',r)
for qi,q in enumerate(found):
# print('qi:',qi,'q:',q)
if ri != qi and is_inside(r,q):#如果是索引不同的两个框,并且r框在q框里面完全包含了,就直接break
print('过')#这里我们发现没有这种不同框相互包含的情况,三个框都不是相互包含的关系
break
else:
found_filtered.append(r)
for person in found_filtered:
# print(person)
draw_person(img,person)
cv2.imshow('PEOPLE DETECTION',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果图
可以看出能够识别人体,但是略有瑕疵。
PS:由于opencv没有可以直接使用的车辆识别的模型,所以两个特征提取方法都用来人脸识别。