近期在学校接触到了简单的人脸识别,了解了基础的Haar特征、级联分类器、Adaboost分类器概念。但了解并不深入,如果有想实现相关效果的,可以参考我的级联分类器使用方法。也做了个戴墨镜小的实例,在此分享一下。欢迎大家讨论。
目录
前置知识
Haar特征
Haar特征是一种图像处理中的特征提取方法,用于描述图像中的纹理、边缘和线条等特征。
将图像划分成不同大小、不同形状的小矩形区域,对每个区域内的像素进行加权求和得到一个特定的Haar特征值。这些Haar特征值可以作为分类器的输入,例如在人脸识别中就可以用Haar特征检测人脸的位置、大小和方向等信息。
Haar特征经常用在人脸识别中,它可以通过训练一个分类器来检测人脸的各种属性.计算速度相对较快,并且在处理大量数据时表现稳定,使其成为计算机视觉领域中比较受欢迎的特征提取方法之一。
级联分类器
级联分类器主要用于人脸检测,但也可以用于识别其它物体。级联分类器具有高检测精度和快速检测速度的特点。级联分类器的实现依赖于AdaBoost算法。AdaBoost是一种集成学习方法可以将多个弱分类器组合成一个强分类器。
级联分类器的检测过程分为多个步骤。首先是图像预处理、图像转换为灰度图像、归一化、直方图均衡化。接着,级联分类器将在图像的不同位置和不同大小的窗口中,对每个窗口进行Haar特征的计算。计算得到的Haar特征值会被送入AdaBoost分类器进行分类,如果分类器的输出值大于预设的阈值,则认为当前窗口中有目标物体。
实战
实现人脸识别检测
加载级联分类器,使用分类器识别图像
1.加载分类器
<CascadeCalsssifier object> = cv2.CascadeCkassifile(filename)
Filename:级联分类器的xml文件名
返回值:object:分类器对象
2.使用建好的分类器对图像进行识别
Object=cascade.derectMultiScale(image,scaleFactor.minNEIGHBORS,flags,minSize,maxSize)
Image 待分析的图像
scaleFacator 可选参数 扫描时的缩放比例
MinNeighbors 可选参数 每个候选区域至少保留多少个检测结果才可以判定为人脸,该值越大分析的误差越小
级联分类器文件
在此路径下
x:\xxx\Anaconda\Lib\site-packages\cv2\data
XML文件名 | 检测内容 |
---|---|
haarcascade_eye.xml | 眼睛检测 |
haarcascade_eye_tree_eyeglasses.xml | 眼睛树和眼镜检测 |
haarcascade_frontalcatface.xml | 正面猫脸检测 |
haarcascade_frontalface_default.xml | 正面人脸检测 |
haarcascade_fullbody.xml | 身形检测 |
haarcascade_lefteye_2splits.xml | 左眼检测 |
haarcascade_lowerbody.xml | 下半身检测 |
haarcascade_profileface.xml | 侧面人脸检测 |
haarcascade_righteye_2splits.xml | 右眼检测 |
haarcascade_russian_plate_number.xml | 车牌检测 |
haarcascade_smile.xml | 笑容检测 |
haarcascade_upperbody.xml | 上半身检测 |
人脸识别示例
实现对人戴墨镜效果
import cv2
def overlay_img(img, img_over, img_over_x, img_over_y):
img_h, img_w, img_p = img.shape
img_over_h, img_over_w, img_over_c = img_over.shape
if img_over_c == 3:
img_over = cv2.cvtColor(img_over, cv2.COLOR_BGRA2BGR)
for w in range(0, img_over_w):
for h in range(0, img_over_h):
if img_over[h, w, 3] != 0:
for c in range(0, 3):
x = img_over_x + w
y = img_over_y + h
if x >= img_w or y >= img_h:
break
img[y, x, c] = img_over[h, w, c]
return img
face_img = cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\ren.png")
glass_img = cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\glass.png", cv2.IMREAD_UNCHANGED)
face_cascade = cv2.CascadeClassifier(r"D:\Program Files\Anaconda\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml")
gray_frame = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray_frame, 1.3, 5)
for (x, y, w, h) in faces:
gw = w
gh = int(glass_img.shape[0] * w / glass_img.shape[1])
glass_img_resized = cv2.resize(glass_img, (gw, gh))
overlay_img(face_img, glass_img_resized, x, y + int(h * 1 / 3))
cv2.imshow("screen", face_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
示例
行人检测
import cv2
# 读取图像
img = cv2.imread("e:/image/monitoring.jpg")
# 加载识别人体的级联分类器
bodyCascade = cv2.CascadeClassifier("cascades/haarcascade_fullbody.xml")
# 识别所有的人体
bodies = bodyCascade.detectMultiScale(img, 1.15, 4)
# 遍历所有人体的区域并在图像中绘制方框
for (x, y, w, h) in bodies:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示最终处理效果
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
车牌检测
import cv2
# 读取图像
img = cv2.imread("c:/image/car.jpg")
# 加载识别车牌的级联分类器
plateCascade = cv2.CascadeClassifier("cascadehaarcascade_russian_plate_number.xml") # 注意文件后缀,通常应该是.xml而不是.xm1
# 识别出所有车牌
plates = plateCascade.detectMultiScale(img, 1.15, 4)
# 遍历所有车牌区域
for (x, y, w, h) in plates:
# 在图像中车牌的位置绘制方框
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
# 显示最终处理的效果
cv2.imshow("Image", img)
# 按下任何键盘按键后
cv2.waitKey(0) # 参数为0表示无限等待,也可以传入参数表示等待的毫秒数
# 释放所有窗体
cv2.destroyAllWindows()