Python图像处理之目标识别:人脸识别+车辆识别

文章目录

python图像处理教程:初步📷插值变换📷形态学处理📷滤波

在Python中实现目标识别任务,最常用的方法是调用dlib模块。dlib由C++编写,基于boost,在Python中有很多依赖,推荐用conda来安装,一行代码轻松搞定

conda install -c conda-forge dlib

 
 

人脸识别

人脸识别是应用最广泛的目标识别任务之一,dlib对此提供了非常成熟的方案,包括基于HOG和CNN的两种算法,可以实现下面的效果。

在这里插入图片描述

其中,绿色框线即为检测到的人脸区域。

HOG算法的基本思想是计算图像的梯度和方向,然后用直方图对梯度值进行统计得到特征,并将这些特征送入SVM,从而实现分类,并检测出人脸。其实现代码如下

import numpy as np
import matplotlib.pyplot as plt
import dlib

path = ‘lena.jpg’
img = plt.imread(path)

detector = dlib.get_frontal_face_detector()
rect = detector(img, 1)[0]
def drawDetector(img, rect):
cnrs = [rect.bl_corner(), rect.br_corner(),
rect.tr_corner(), rect.tl_corner(),
rect.bl_corner()]
xs = [c.x for c in cnrs]
ys = [c.y for c in cnrs]
plt.imshow(img)
plt.plot(xs, ys, c=‘g’)
plt.axis(‘off’)
plt.show()

drawDetector(img, rect)

【get_frontal_face_detector】便用于生成HOG人脸检测器,detector为其返回值。作为一个人脸检测器,detector输入一个图像后,其返回值是一个矩形,通过提取矩形的四个点,并连成线之后,就可以把检测到的人脸框选出来。

CNN算法,即卷积神经网络,若想让其顺利工作,需要使用已经训练好的模型,可在这里下载mmod_human_face_detector.dat.bz2文件。

下载完成后,解压并调用

p = r"mmod_human_face_detector.dat"     # 模型路径
cnnDetector = dlib.cnn_face_detection_model_v1(p)

 
 

在检测器创建后,其调用方法与内置检测器是完全相同的,但返回值对Rectangle类型进行了二次封装,代码如下。

cnnRect = cnnDetector(img, 1)[0]
drawDetector(img, cnnRect.rect)

 
 

特征点识别

如果想鉴别某两张脸是同一个人,那么首先要得到人脸上的某些特殊的点,比如眼角、嘴角,然后根据这些点的位置关系,得到一些不随着人脸移动和表情变化而变化的不变量,并以此作为鉴别人物的依据。

为此需要从dlib.net下载68点的人脸模型 shape_predictor_68_face_landmarks.dat.bz2,下载后注意解压。

# 加载68点人脸模型
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

# 此为人脸的特征点列表,img和rect是HOG算法检测到的结果。
face = predictor(img, rect)
keyPts = face.parts()

其中,shape_predictor关键点检测器,face可以理解为检测到关键点的脸,keyPts为其检测后的关键点列表。效果如下

在这里插入图片描述

从这个图可以看到人脸特征点总共有68个,分布在脸的轮廓和五官的边缘,每个点有 x , y x,y x,y两个坐标,则总共有136个值,可以组成一个新的向量。绘图代码为

for i, pt in enumerate(keyPts):
    plt.text(pt.x,pt.y, str(i))
    plt.scatter([pt.x], [pt.y], marker='*')

plt.imshow(img)
plt.axis(‘off’)
plt.show()

人脸比对

对比两张脸是否相同,本质就是对比这136个值是否相近,只不过这种方案误差很大就是了。

【face_recognition_model_v1】提供了人脸对比模型,当然需要调用的模型还是需要到dlib中下载。考虑到在寻找脸部的68个特征点时,并未保证特征点之间是线性无关的,所以通过这个模型后,得到的是一个128维的向量,代码如下

pReg = "dlib_face_recognition_resnet_model_v1.dat"
faceRec = dlib.face_recognition_model_v1(pReg)
vec1 = faceRec.compute_face_descriptor(img, face)

 
 

接下来再打开两张图片,并求得对应的特征向量

def getReg(im):
    rect = detector(im, 1)[0]      # 此为人脸区域
    face = predictor(im, rect)
    vec = faceRec.compute_face_descriptor(im, face)
    return np.array(vec)

img2 = plt.imread(‘test2.jpg’)
vec2 = getReg(img2)
img3 = plt.imread(‘test3.jpg’)
vec3 = getReg(img3)

接下来查看一下这三张图片的距离

np.linalg.norm(vec1-vec2)
0.40060397645976
np.linalg.norm(vec1-vec3)
0.8248735552156338

 
 

可见,vec1和vec2很有可能是一个人,和vec3则是两个人。

车辆识别

除了人脸识别模型之外,dlib还提供了车辆模型

  • mmod_front_and_rear_end_vehicle_detector.dat
  • mmod_rear_end_vehicle_detector.dat

接下来测试一下这两个模型的识别效果

p1 = r"mmod_front_and_rear_end_vehicle_detector.dat"
p2 = r"mmod_rear_end_vehicle_detector.dat"
fD = dlib.cnn_face_detection_model_v1(p1)
rD = dlib.cnn_face_detection_model_v1(p2)

 
 

然后打开一张车辆的图像进行识别

img = plt.imread("test.jpg")
fRects = fD(img)
rRects = rD(img)

 
 

由于图像中有多个车辆,所以重做一个展示函数

def getXY(rect):
    cnrs = [rect.bl_corner(), rect.br_corner(),
        rect.tr_corner(), rect.tl_corner(),
        rect.bl_corner()]
    xs = [c.x for c in cnrs]
    ys = [c.y for c in cnrs]
    return xs, ys

def drawDetector(img, rects, ax):
for r in rects:
xs, ys = getXY(r.rect)
ax.plot(xs, ys)
ax.imshow(img)
plt.axis(‘off’)

运行
运行

然后绘图

fig = plt.figure()
ax = fig.add_subplot(1,2,1)
drawDetector(img, fRects, ax)
ax = fig.add_subplot(1,2,2)
drawDetector(img, rRects, ax)
plt.show()

 
 

效果如下

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值