智能快递机器人—— 人脸识别算法设计

**计算机系统的介绍

一 概要

  智能快递机器人是一种以自动导航轮式小车为载体,搭载人脸识别检测模块以及储存箱体的智能运输机器人。其可以实现GPS自动导航,箱门自动开合,识别取件人面部等功能,主要运用于写字楼,小区,高校宿舍楼等物流运输的终端场所,研究目的在于为传统快递业注入一个新的生命力,以及作为智能生活应用方面的一个代表。
  而人脸识别技术基于生物特征安全识别技术,作为机器视觉方面的应用,是智能识别的一个重要体现,已经广泛应用于安防,门禁,交通图像处理等领域,具有很高的安全性和可靠性,将其运用在智能快递机器人上无疑能提高产品的智能化程度。而两者结合在一起的智能快递机器人不仅能具备快捷的配送功能,也具备了安全防盗的功能。
  本次研究中,人脸识别模块核心采用k210芯片,编程语言使用python,基于人脸识别特征库来实现。主要使用到python中的opencv,numpy,pillow等pip。在经过人脸检测,人脸特征采集,模型训练,人脸识别四个步骤后,达到所需的检测效果。主要以实体模块来展示人脸识别功能,并且详细对关键环节:人脸检测,人脸特征,人脸识别这三大环节来进行讲解。这款快递机器人结合先进的人脸识别技术,以一种智能生活的理念给消费者带来全新的体验,也大大减轻了快递员的负担,使派件变得更加便捷。
  智能快递机器人的研究想法来源于生活,对于我们平常的取快递时种种的不便产生的疑惑和烦恼,这款机器人都能很大程度上解决这些问题,智能机器人最重要的一点就是能够为人类提供最大的帮助,这也是我们想法的初衷。

关键词:智能快递机器人,人脸识别,生物特征识别技术,python

二、绪论

1.1.研究背景与意义

众所周知,现在中国的快递业正在面临巨大的挑战,尤其是在最后的环节——终端配送的难题逐渐成为各快递公司的关注点和急需解决的地方。而且这样的难题不仅仅存在于快递行业,也紧紧关系着城市和农村的信息化建设和网络化服务的铺设。而在分析国内外的智能机器人的发展情况以及物流行业的运作方式之间的差异之后,我们自主进行了智能快递机器人课题的调查研究以及机器人实物的研发工作,对于传统快递业提出了几点新的理念和建议。
首先智能快递机器人是一种基本可以完全实现无人控制的一种物流配送终端的智能型机器人。它以强大的智能芯片为控制中枢,搭载了四个直流驱动电机为动力部件,采用先进的人脸识别模块,人脸识别速率可达到一秒以内,然后在人脸识别成功后给箱门继电器输出一个高电平信号,使连接箱门的机械手臂电机运作,完成打开箱门动作,在收件人取出快递后可自动闭合箱门。智能快递机器人的主要特点在于轻巧的身躯,强大的GPS自动导航技术,以及安全可靠的人脸识别技术。
而人脸识别技术是基于计算机视觉应用的一个重要研究领域,在图像检索,身份识别等都有广泛应用。而光线补偿技术,高斯平滑技术以及二值化技术均是提高人脸识别准确率的重要技术之一。在许多国家,人脸识别在军事领域,智能家居,移动式电子产品上都已经相当普及。
这两者的结合产物——智能快递机器人的主要作用是能解决物流的终端配送问题,可以在任意指定的时间内前往收件人指定的相对固定场所,由GPS自动导航到达目的地后,经过人脸识别读取到收件人的信息,确认无误后打开箱门送出快递,完成配送过程。这是在物流领域中一次创新性的尝试,突破了传统人力配送的固定方式,可给传统快递业注入新的生命力。

二、人脸识别算法设计

在智能快递机器人课题研究中,本人主要负责人脸识别模块的算法设计及调试,辅助队友完成机械结构的设计和控制系统的开发。
在充分了解其控制系统原理的前提下,采用了SPIEED MF1人脸识别模块为主控模
块,使用Python语言在Opencv平台的基础上对安全识别取件功能进行程序设计及优化,并且尝试与快递车的箱门机械手臂进行联动,使得人脸识别成功后可自动打开箱门,取出快递。
1)该人脸识别模块的特性如下:
通过双光谱摄像头判断识别活体人脸
适用于无光线直射的室内和室外环境,遇到黑暗环境可自动切换至红外线识别
默认的有效识别距离为40~80cm
开机启动时间大约为0.3秒,识别速度最快可在0.5秒左右,识别准确率为98%@0.001FA
内置16M储存数据空间,可存储人脸特征值数量大约为2200张
在这里插入图片描述

图2.1 MF1模块
2)采用Opencv来进行人脸识别程序的开发及调试。Opencv是一个开源的计算视
觉库,可以运行在Linux,Window,Mac OS等计算机系统上,可支持提供Python,Ruby,MATLAB等语言接口,实现机器视觉方面的多元化算法。其应用非常广泛,且可靠程度高,检测成功率高,是实现人脸识别功能的优秀平台。

3)Python于20世纪90年代初诞生,到现在经过不断的发展,已经成为一门最
受欢迎的编程语言之一。Python与C语言,Java等属于编程语言的一种,偏向于解释型脚本语言。主要用于计算机程序设计,具有强大的功能和广阔的拓展性,并且优势在于简单易学,上手速度快。Python在开始运行的时候,首先会将py文件中的代码翻译成字节码,然后再由Virtual Machine将其执行。此外,Python还有良好的交互模式,在开源系统Linux,Mac系统上都可以直接运行。
此外Python的具体应用还有:图形处理,文本处理,数字处理以及简单的网络爬虫。
Python还具有强大的标准库和大量的第三方模块,涵盖了系统开发,数据库连接,图形系统等多个领域,是实现人脸识别功能的最优选择。

2.1设计原理

首先,我们来初步了解一下人脸识别技术的概念:人脸识别技术是近年来非常火热的一项计算机与机器视觉相结合的研究领域。它与眼球识别技术,静脉识别技术等都属于生物特征识别技术,是以人本身的特有的生物特征来达到区分个体的目的。
人脸识别技术基于人的面部特征,能对录入的人脸图像或者视频进行分析处理。首先是判断是否存在空白信息,也就是是否存在人脸。然后如果存在人脸,再进一步根据每个脸部器官的位置信息,大小差异来提取每个人脸部代表的个人身份信息。最后与云端已存储的人脸信息进行对比,达到识别目的。

2.1.1各部分技术原理

人脸检测:
参考模板法:这是最基本的人脸检测方法,首先准备好一个人脸的标准模板,然后计算测试中采样的信息与模板之间的匹配程度,并通过阈值计算来判断人脸是否存在。
肤色模型法:不同的人肤色会有所差异,这种方法主要是根据肤色在色彩范围内分布的值的不同来进行检测。
可视特征法:这种方法是根据特征之间反射的信息之间的差异来进行。将所有的面集合成一个整体,基于检测物在投影上的距离来判断是否存在
另外一个检测步骤是人脸跟踪:
人脸跟踪是指在检测到目标为有效面部后,对目标进行动态追踪。具体采用三维模型与运动仿真相结合的方法,此外也有利用肤色模型的方法来进行跟踪。
在这里插入图片描述

图2.2 人脸特征分布关系图

人脸特征采集
人脸特征采集步骤就是提取人脸上的细微特征。主要流程在于输入图像后,与
识别库中的一张已存人脸图片进行联系,形成一个识别系统。具体方法如下:
几何特征法:总的来说就是把人脸看似成一个几何特征总量,并根据这些特征去设计分类器。在选取几何特征矢量是要尽可能采用差异较大的部分,同时要考虑光线变化产生的问题。
代数特征法:主要是把图像上的一个个像素点替换成空间上的投影点,从而对各个像素用基本图像来编码。常采用PCA采集法,仅采用一种少量特征描述方法来达到降维特征空间的目的。其基本公式是采用K-L展开公式,可以使所有图像都被投影到同一空间上,能很好地达到降维目的。
基于人工神经网络:机器视觉近几年发展迅速,在人脸识别上的应用也开始研究。神经网络是一个庞大的可自我计算的一个系统,能处理复杂的算法。主要特点在于具备学习和分类的能力,也可以通过大量训练来达到自我适应的能力。

人脸识别对比
人脸识别对比就是对检测成功的完整的人脸进行识别,也就是最后一步。而人脸
识别又主要分为以下两种算法原理:1.基于几何特征,2.以特征脸为基础。
首先基于几何特征方法的原理在于:将重要特征的位置信息及形状参数作为一个分类,因为人五官的轮廓,角度,之间的距离是有很大差异的。通过设计一个参数可自行调整的五官函数模型,就可以作为这个人脸的几何特征的对比向量。
特征脸方法也是基于PCA算法的一种方法,只不过这种算法相对简单且速度比较快。主要就是利用一个二维矩阵,将检测好的人脸图像投影到空间当中,通过对特征的加权运算和描述,将其与已存的图像权值进行对比即可。
在这里插入图片描述

图2.3 人脸识别原理流程图

2.1.2人脸识别模块参数
SIPEED MF1人脸识别模块是基于M1W模块,以K210为核心的AI模块。它搭载了一
对在黑暗环境中也能清楚识别人脸的双红外摄像头,一块用于显示人脸画面的1.3寸TFT屏,一个RGB LED指示灯。这个模块主要结合Opencv平台来实现人脸识别功能,用途相当广泛。其具体参数如下表:

表2.1 MF1具体参数表

在这里插入图片描述

三、设计过程

2.3.1人脸检测

  这是比较重要且困难的一步,因为要利用Python中许多不同类型的库,如果缺少
任何一个程序都进行不下去。以下结合几个重要步骤的程序来讲解我的思路。
  1.先调用Python里含有的识别分类器,主要运用一般常用的人脸的识别分类器—
haarcascade_frontalface_default以及识别双眼的haarcascade_eye分类器。而haar特征也是人脸检测中常用且有效的一种方法。代码如下:
#人脸识别分类器

faceCascade=cv2.CascadeClassifier(r'C:\Users\leo12\AppData\Local\Programs\Python\Python38\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')

识别眼睛的分类器

eyeCascade=cv2.CascadeClassifier(r'C:\Users\leo12\AppData\Local\Programs\Python\Python38\Lib\site-packages\cv2\data\haarcascade_eye.xml')

  而我在调用分类器时也出现过一点问题,就是分类器的路径一定要是完整路径,不然它自己寻找不到,我当时只是填了python的安装路径,导致程序出错。

  2.接下来就是人脸框架的检测,这部分就是识别出脸和眼睛的大致方位,并用矩
形框标出来,主要就是把检测到的各个坐标换成绝对位置的过程,部分代码如下:

人脸检测

    faces = faceCascade.detectMultiScale(
gray,     
scaleFactor=1.2,
minNeighbors=5,     
minSize=(32, 32)

在检测人脸的基础上检测眼睛

for (x, y, w, h) in faces:
fac_gray = gray[y: (y+h), x: (x+w)]
result = []
eyes = eyeCascade.detectMultiScale(fac_gray, 1.3, 2)

眼睛坐标的换算,将相对位置换成绝对位置

for (ex, ey, ew, eh) in eyes:
result.append((x+ex, y+ey, ew, eh))

附上检测效果图:
在这里插入图片描述

图2.4 人脸检测图

2.3.2人脸特征数据采集

  这一部分其实只是为接下来的模型训练作素材准备。主要是先从摄像头中读取图片,然后经过灰度转换,然后和上面同样的检测人脸,但这个时候只需要简单的整脸采集,不必做单独的眼睛定位,在持续拍摄500张图片样本后就完成采集工作了。
首先新建存放样本的文件夹,我这里选择把分类器也一起存放,以免出错。
在这里插入图片描述

图2.5 创建文件夹

  然后运行采集程序,这里设定采集数量为500,也就是采集0-500号数据图
片,存放到shujudata文件夹中。经过大量的数据采集之后能提高人脸识别精度,所以结合家庭电脑工作速度我选择采集500张。部分代码如下:

sucess, img = cap.read()#摄像头工作照相
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#转为灰度
faces = face_detector.detectMultiScale(gray, 1.3, 5)#人脸检测
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
count += 1
cv2.imwrite("shujudata/User." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])#设定存储路径,放入shujudata文件夹
cv2.imshow('image', img)
k = cv2.waitKey(1)
if k == 27:   
break
elif count >= 500:  # 设定为取500张样本
break

附上过程图:
在这里插入图片描述

图2.6 人脸采集过程图
在这里插入图片描述

图2.7 不同角度的采集图

程序

源程序代码:
import numpy as np
import cv2

# 人脸识别分类器
faceCascade=cv2.CascadeClassifierr'C:\Users\leo12\AppData\Local\Programs\Python\Python38\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')

# 识别眼睛的分类器
eyeCascade=cv2.CascadeClassifierr'C:\Users\leo12\AppData\Local\Programs\Python\Python38\Lib\site-packages\cv2\data\haarcascade_eye.xml')
# 开启摄像头
cap = cv2.VideoCapture(0)
ok = True

while ok:
    # 读取摄像头中的图像,ok为是否读取成功的判断参数
    ok, img = cap.read()
    # 转换成灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 人脸检测
    faces = faceCascade.detectMultiScale(
        gray,     
        scaleFactor=1.2,
        minNeighbors=5,     
        minSize=(32, 32)
    )

    # 在检测人脸的基础上检测眼睛
    for (x, y, w, h) in faces:
        fac_gray = gray[y: (y+h), x: (x+w)]
        result = []
        eyes = eyeCascade.detectMultiScale(fac_gray, 1.3, 2)

        # 眼睛坐标的换算,将相对位置换成绝对位置
        for (ex, ey, ew, eh) in eyes:
            result.append((x+ex, y+ey, ew, eh))

    # 画矩形
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

    for (ex, ey, ew, eh) in result:
        cv2.rectangle(img, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
 
    cv2.imshow('video', img)

    k = cv2.waitKey(1)
    if k == 27:    # press 'ESC' to quit
        break
 
cap.release()
cv2.destroyAllWindows()
import cv2
import os
# 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2

cap = cv2.VideoCapture(0)

face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

face_id = input('\n enter user id:')

print('\n Initializing face capture. Look at the camera and wait ...')

count = 0

while True:

    # 从摄像头读取图片

    sucess, img = cap.read()

    # 转为灰度图片

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 检测人脸

    faces = face_detector.detectMultiScale(gray, 1.3, 5)

    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
        count += 1

        # 保存图像
        cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])

        cv2.imshow('image', img)

    # 保持画面的持续。

    k = cv2.waitKey(1)

    if k == 27:   # 通过esc键退出摄像
        break

    elif count >= 1000:  # 得到1000个样本后退出摄像
        break

# 关闭摄像头
cap.release()
cv2.destroyAllWindows()
import numpy as np
from PIL import Image
import os
import cv2
# 人脸数据路径
path = 'Facedata'

recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

def getImagesAndLabels(path):
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]  # join函数的作用?
    faceSamples = []
    ids = []
    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L')   # convert it to grayscale
        img_numpy = np.array(PIL_img, 'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x, y, w, h) in faces:
            faceSamples.append(img_numpy[y:y + h, x: x + w])
            ids.append(id)
    return faceSamples, ids


print('Training faces. It will take a few seconds. Wait ...')
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))

recognizer.write(r'face_trainer\trainer.yml')
print("{0} faces trained. Exiting Program".format(len(np.unique(ids))))
import cv2

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('face_trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath)
font = cv2.FONT_HERSHEY_SIMPLEX

idnum = 0

names = ['jie']

cam = cv2.VideoCapture(0)
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)

while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(int(minW), int(minH))
    )

    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
        idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w])

        if confidence < 100:
            idnum = names[idnum]
            confidence = "{0}%".format(round(100 - confidence))
        else:
            idnum = "unknown"
            confidence = "{0}%".format(round(100 - confidence))

        cv2.putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1)
        cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (0, 0, 0), 1)

    cv2.imshow('camera', img)
    k = cv2.waitKey(10)
    if k == 27:
        break

cam.release()
cv2.destroyAllWindows()

总结

   经过这次智能快递机器人以及其中的人脸识别算法研究,我整理了各项资料,结合如今国内人脸识别技术和快递行业的发展,得出以下两点结论:
   1)传统人脸识别技术一直都是以光照图像为识别依据,是最基本也是最普遍的识别方式,已经过了数十年的历史考验。但任何事物都难以达到完美的情况,在周围环境光线和气温发生变化的情况下,识别效果会受到抑制,在实际应用中存在不稳定因素,无法充分满足用户的需求。目前比较先进的可解决替代方案为三维动态面部识别和热成像识别,但技术成本昂贵,且不够成熟。而最近兴起的一种基于主动近红外图像的多光源人脸识别技术在一定程度上可克服光线问题,识别性能也比较出色,在精确度,识别速率和稳定性上也超过其他人脸识别方法,但同样问题也是因为属于新技术,所以造价昂贵和实际应用案例较少。
   我觉得基于神经网络的人脸识别算法可很大程度上解决这个问题。人工神经拥有优越自我组织力和自我适应能力,具体方法可以是先提取50个人脸主元,然后用相关神经网络投射到五维空间中,再经过多层感知器来识别。也可以是将人脸的特点用六个标准来概括,然后根据标准来进行五官定位,将五官之间的三维几何距离代入到神经网络中进行计算。还可以是采用卷积神经网络进行识别,因为其集成了相近像素的近似度知识,在一定程度上可避免人脸特征在三维空间中的平移,旋转和局部变形,可以达到良好的识别效果。
   神经网络方法作为近几年来人脸识别上应用上的新尝试,具有一定的优势,因为普遍的人脸识别方法中是很难寻找到明显的规律,而神经网络方法类似于机器深度学习,可在学习过程中获得隐性规律,能有很强的适应性。

   2)快递配送经过数十年的发展,虽然进化出多种不同的配送模式,如送货上门,快递代取,智能柜投放等,也都存在各自的擅长的范围,但都有各自的缺陷。例如送货上门时间长,人力成本大;快递代取局限点在于空间成本大,服务质量因工作人员没有接受统一培训标准而有所差异;智能快递柜则受限于存放空间,相对固定的储存格大小决定着快递不能过大,而且形状也必须符合标准方体。
   经过走访一些社区以及对于上班族的调研得知,中老年人对于社区快递服务质量是日渐感到不满,大部分因素在于高年龄带来的身体机能的不便。而上班族则苦于工作时间和快递员配送时间经常发生冲突,无法按时取得快递。这些问题看似不大,但任其长期发展必定会对快递行业产生不利。
   而智能快递机器人与人脸识别技术的结合,是一次重要的尝试,事实证明这也是正确的决定。普通的搬运机器人早已在货物运输,包装中得到应用,而且技术相当成熟,这些机器人虽然具备自动化能力,但没有类似人一样的“感官”,并不具备智能化,并不能进行灵活的配送服务。随着社会经济发展,这一类的机械产品也出现了智能定制化要求。在英国泰晤士港,荷兰的鹿特丹港都已经批准建设一批集自动化和智能化为一体的机器人运作码头。这些都只是简单的搬运机器人,如果在此基础上加上GPS自动驾驶,人脸识别技术,网络化服务等智能化产品,其在物流业的应用前景将会更加广阔。
   在快递业务与日俱增的情况下,智能设备的投入必定能成为快递运输的主力军。纵观世界各国,无论是美国的亚马逊,还是我国的京东,都在大力发展着智能快递机器人这一项目。可以设想这样一个未来,无数的智能快递小车在马路上行驶,代替着千千万万快递员的身影,这景象背后代表着全人类智能机械化时代的到来,代表着智能机器人的美好未来。

五、 文章目录

目 录

1 前言 1
1.1 智能快递机器人及人脸识别技术的目的、意义 1
1.2 智能快递机器人应达到的技术要求 4
1.3 智能快递机器人在国内外的发展概况及存在的问题 5
1.4 智能快递机器人应解决的主要问题 7
2人脸识别算法设计 9
2.1设计原理 10
2.1.1各部分技术原理 10
2.1.2人脸识别模块参数 12
2.2方案选择 13
2.2.1存在的影响因素 15
2.2设计过程 15
2.2.1人脸检测 16
2.2.1人脸特征数据采集 17
2.2.1人脸训练 19
2.2.1人脸识别 20
2.2.1模块的准备工作及调试 22
3结论 23
参考文献 25
谢辞 26
附录 27

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值