本文介绍在物联网应用开发(IoT Studio)平台使用树莓派摄像头实现人脸识别功能。即将树莓派摄像头采集的人像,存储到阿里云对象存储(OSS)中,同时,通过设备属性上报获取图片,并调用人脸识别API进行人脸识别后,在钉钉群中推送验证结果。

流程图

流程

物料准备

硬件 说明
树莓派主板 将摄像头和红外线传感器连接到树莓派主板。
  • 将摄像头连接线头插入到树莓派卡槽中。
  • 将红外线传感器(PIR)连接线头插入到树莓派GPIO引脚。
适用于树莓派的摄像头
红外线传感器

创建存储空间

本示例中,摄像头拍摄的图像将存储在阿里云对象存储中,因此需为图像存储创建一个存储空间Bucket。开发设备端SDK时,需要配置该Bucket信息。

  1. 登录对象存储控制台

    若您还未开通对象存储服务,请单击立即开通,进入购买页开通服务。具体操作,请参见开通OSS服务

  2. 单击Bucket列表,然后单击创建Bucket
    您也可以单击概览,然后单击右上角的创建Bucket
  3. 创建Bucket面板,按如下说明配置必要参数。其他参数保持默认配置,也可以在Bucket创建完成后单独配置。
    参数 说明
    Bucket名称 Bucket的名称。Bucket一旦创建,则无法更改其名称。

    命名规则如下:

    • Bucket名称必须全局唯一。
    • 只能包括小写字母、数字和短划线(-)。
    • 必须以小写字母或者数字开头和结尾。
    • 长度必须在3~63字节之间。
    地域 选择您要创建的Bucket所在地域。Bucket一旦创建,则无法更改其所在地域。
    存储类型 本示例中,选择标准存储。实际使用中,请根据您的实际需要选择。
    同城冗余存储 本示例中,选择关闭。实际使用中,请根据您的实际需要选择。
    读写权限 本示例中,选择公共读写。实际使用中,请根据您的实际需要选择。
    实时日志查询 本示例中,选择不开通。实际使用中,请根据您的实际需要选择。
    Bucket创建后,其概览页会显示Endpoint和域名。Endpoint信息需配置到设备端SDK中。endport信息
  4. 测试Bucket。
    1. 在概览页,单击左侧导航栏的文件管理,然后单击上传文件。
    2. 上传文件面板,参数保持默认配置,上传一张测试图片。
    3. 图片上传完成后,关闭上传任务面板,然后单击操作列的详情按钮,将图片URL复制到浏览器中。若浏览器中显示该图片,证明Bucket使用正常。

创建产品和设备

  1. 登录物联网平台控制台
  2. 实例概览页面,找到对应的实例,单击实例进入实例详情页面。
    实例概览
  3. 在左侧导航栏,选择设备管理 > 产品,单击创建产品
  4. 新建产品页面,配置参数后,单击确认
    本文示例的产品名称摄像头所属品类自定义品类,其他参数使用默认值。创建产品
  5. 单击查看产品详情,在产品详情页,单击设备数后的前往管理
  6. 在设备页,单击添加设备。输入设备名称(DeviceName),设置设备备注名,单击确认

为产品定义物模型

  1. 在左侧导航栏,选择设备管理 > 产品。在产品列表中,单击产品对应的查看
  2. 产品详情功能定义页签下,定义物模型。
    说明 已发布的产品不能添加和更新功能。

    本示例在物模型的默认模块中,添加以下属性。具体操作,请参见单个添加物模型

    标识符 数据类型 数据定义
    people bool 0:没人;1:有人。
    picURL text 数据长度限制:2048字节。
  3. 发布物模型。
    1. 单击页面左下方的发布上线按钮,弹出发布物模型上线对话框。
    2. (可选)单击添加发布备注,输入版本号和版本描述。
      参数 说明
      版本号 设置当前物模型版本号。后期可根据版本号管理物模型。

      版本号支持英文字母、数字和英文句号(.),长度限制1~16个字符。

      版本描述 描述当前版本物模型。支持中文汉字、英文字母、数字和特殊符号。长度限制为100个字符。一个中文汉字算一个字符。
    3. 如存在已上线的版本,则需要进行比对,确认新版本的修改点。
      单击比对结果,在比对结果对话框中查看修改点。确认无误后,单击确认查阅,回到发布物模型上线对话框,自动勾选“确认已查看当前版本与线上版本的比对结果”。
    4. 单击确定,发布物模型。
    说明 物模型发布后,才会正式生效。
    自定义功能属性配置完成,可在功能定义页签下查看。

    有关物模型的更多信息,请参见物模型(功能定义)

设备端SDK开发

因为树莓派基于Python语言,需要配置两个Python SDK: IoT设备端接入SDKOSS文件上传SDK

设备端SDK开发代码示例如下:

  • 引入相关库。
    import aliyunsdkiotclient.AliyunIotMqttClient as iot ##导入阿里云的设备MQTT库,如果import失败需要先pip3 install
    import json
    import multiprocessing
    import time
    import random
    import oss2 ##导入阿里云的OSS库,如果import失败需要先pip3 install oss2
    from picamera import PiCamera ##树莓派的摄像头,系统自带
    import RPi.GPIO as GPIO ##GPIO口,接红外PIR使用
  • OSS Bucket访问授权 。
    auth = oss2.Auth('**YourAccessKeyId**','**YourAccessKeySecret**') ##OSS的授权,需要您的阿里云账号AccessKey ID和AccessKey Secret,具体查看https://usercenter.console.aliyun.com/#/manage/ak
    bucket = oss2.Bucket(auth,'http://oss-******.aliyuncs.com','**YourBucketName**') ##请在OSS控制台,Bucket的概览页查看具体信息
    global picURLtoIoT
    camera = PiCamera()
    camera.resolution = (800,600)  ##拍照分辨率,越高越容易分析,但是上传速度越慢
  • 初始化树莓派。
    def init():
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(3, GPIO.IN)
        pass
  • 定义图像上传OSS Bucket。
    def take_photo():
        ticks = int(time.time())
        fileName = 'test%s.jpg' % ticks  ##在文件名加入时间戳作为简易加密手段
        filePath = '/home/pi/Pictures/%s' % fileName
        camera.capture(filePath)
        bucket.put_object_from_file('bucket_file_name/%s', fileName) ##在这里改bucket名称
        global picURLtoIoT
        picURLtoIoT = 'http://**您的bucket名称**.oss-******.aliyuncs.com/bucket_file_name/%s' % fileName ##图片存储URL,需替换为您的bucket名称和bucket内文件名称
        print(str(picURLtoIoT))
  • 定义红外线感应器检测到有人时,摄像头拍照,否则休眠5秒。
    def detectPeople():
        if GPIO.input(3) == True:
    take_photo()
        else:
        time.sleep(5)
    
    options = {
        'productKey':'**设备的ProductKey**',
        'deviceName':'**设备的deviceName**',
        'deviceSecret':'**设备的deviceSecret**',
        'port':****,
        'host':'iot-as-mqtt.******.aliyuncs.com' ##物联网平台域名
    }
    host = options['productKey'] + '.' + options['host']
    
    def on_message(client, userdata, msg):
        topic = '/' + productKey + '/' + deviceName + '/update'
        print(msg.payload)
    
    def on_connect(client, userdata, flags_dict, rc):
        print("Connected with result code " + str(rc))
    
    def on_disconnect(client, userdata, flags_dict, rc):
        print("Disconnected.")
  • 定义设备上报数据到物联网平台。
    def upload_device(client):
        topic = '/sys/'+options['productKey']+'/'+options['deviceName']+'/thing/event/property/post'
        while True:
            payload_json = {
                'id': int(time.time()),
                'params': {
    'people':1 ##物模型里布尔值以0和1的形式上报
                    'picURL': picURLtoIoT,
                },
               'method': "thing.event.property.post"
                }
            print('send data to iot server: ' + str(payload_json))
            client.publish(topic, payload=str(payload_json))
    
    if __name__ == '__main__':
        client = iot.getAliyunIotMqttClient(options['productKey'], options['deviceName'], options['deviceSecret'], secure_mode=3)
        client.on_connect = on_connect
        client.connect(host=host, port=options['port'], keepalive=60)
        p = multiprocessing.Process(target=upload_device, args=(client,))
        p.start()
        detectPeople()
        GPIO.cleanup()
        client.loop_forever()

完整的示例代码,请参见本文结尾附录:设备端SDK代码示例

创建业务服务

  1. 登录物联网应用开发控制台,在页面左上角选择对应实例后,在左侧导航栏单击项目管理
  2. 创建普通项目。具体操作,请参见普通项目
  3. 将已创建的摄像头产品和设备与项目关联。具体操作,请参见关联产品至普通项目
  4. 在项目详情主页,单击业务服务页签,单击应用列表上方的新建 > 新建,创建一个业务服务。
  5. 在业务逻辑编辑页,单击左侧的节点按钮,服务开发的功能节点将展示在列表中。
  6. 输入页签下,拖拽一个设备触发节点到画布上,触发数据源配置为摄像头产品下设备的属性上报。
    设备触发
  7. 配置一个云市场API节点,并与设备触发节点相连。
    业务配置

    需在阿里云云市场购买人脸识别API。本示例购买的API是艾科瑞特(iCREDIT)_智能人脸识别

    参数 说明
    节点名称 输入节点名称。
    请求方式 在云市场该API购买页,查看请求方式。本示例中,购买的API的请求方式为POST。
    调用地址 在云市场该API购买页,查看该API的调用地址。
    APPCODE 云市场控制台已购买的服务页列表中,查看已购买API的AppCode。
    编码 选择编码方式。
    参数填写 根据云市场该API购买页的请求参数说明,填入请求参数。本示例中,需填入两个参数:
    • IMAGE:图像数据存储的URL。可输入:
      • 静态值:即输入图像在OSS中的存储地址URL。
      • 动态值:配置为动态获取值,本示例动态取值设置为:"IMAGE":"{{query.props.picURL.value}}",即从属性picURL的数据中获取。
    • IMAGE_TYPE0:图像内容为图像数据BASE64编码;1:图像内容为图像文件的URL。本示例采用URL,配置为"IMAGE_TYPE":"1"
  8. 配置钉钉机器人节点。
    钉钉机器人
    参数 说明
    节点名称 输入节点名称
    Webhook 钉钉群机器人的Webhook地址。具体操作,请参见创建钉钉机器人
    配置方法 选择为自定义
    消息类型 选择为FeedCard类型
    内容配置
    • 修改消息标题title
    • 修改picURL值为{{query.props.picURL.value}}
  9. 单击页面右上方保存按钮保存,保存设置。

调试与发布

  1. 在业务服务编辑页面,单击右上方的部署调试按钮部署,部署并启动服务。
  2. 部署完成后,再次单击右上方的部署调试按钮部署,调试服务。
    1. 单击调试 > 前往,前往产品的设备模拟器页面。
    2. 单击启动模拟设备
    3. 选择上行指令调试 > 属性上报
    4. 在默认模块中推送调试指令。
      调试服务
      数据推送成功,钉钉群将收到图片。钉钉群收到图片
  3. 单击发布按钮,发布服务。

附录:设备端SDK代码示例

import aliyunsdkiotclient.AliyunIotMqttClient as iot ##导入阿里云的设备MQTT库,如果import失败需要先pip3 install
import json
import multiprocessing
import time
import random
import oss2 ##导入阿里云的OSS库,如果import失败需要先pip3 install oss2
from picamera import PiCamera ##树莓派的摄像头,系统自带
import RPi.GPIO as GPIO ##GPIO口,接红外PIR使用

auth = oss2.Auth('**YourAccessKeyId**','**YourAccessKeySecret**') ##OSS的授权,需要您的阿里云账号AccessKey ID和AccessKey Secret,具体查看https://usercenter.console.aliyun.com/#/manage/ak
bucket = oss2.Bucket(auth,'http://oss-******.aliyuncs.com','**YourBucketName**') ##请在OSS控制台,Bucket的概览页查看具体信息
global picURLtoIoT
camera = PiCamera()
camera.resolution = (800,600)  ##拍照分辨率,越高越容易分析,但是上传速度越慢

##初始化树莓派
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(3, GPIO.IN)
    pass

def take_photo():
    ticks = int(time.time())
    fileName = 'test%s.jpg' % ticks  ##在文件名加入时间戳作为简易加密手段
    filePath = '/home/pi/Pictures/%s' % fileName
    camera.capture(filePath)
    bucket.put_object_from_file('bucket_file_name/%s', fileName) ##在这里改bucket名称
    global picURLtoIoT
    picURLtoIoT = 'http://**您的bucket名称**.oss-******.aliyuncs.com/bucket_file_name/%s' % fileName ##图片存储URL,需替换为您的bucket名称和bucket内文件名称
    print(str(picURLtoIoT))

##如果检测到有人则拍照,否则休眠5秒
def detectPeople():
    if GPIO.input(3) == True:
take_photo()
    else:
    time.sleep(5)

options = {
    'productKey':'**设备的ProductKey**',
    'deviceName':'**设备的deviceName**',
    'deviceSecret':'**设备的deviceSecret**',
    'port':****,
    'host':'iot-as-mqtt.cn-shanghai.aliyuncs.com' ##物联网平台域名
}
host = options['productKey'] + '.' + options['host']

def on_message(client, userdata, msg):
    topic = '/' + productKey + '/' + deviceName + '/update'
    print(msg.payload)

def on_connect(client, userdata, flags_dict, rc):
    print("Connected with result code " + str(rc))

def on_disconnect(client, userdata, flags_dict, rc):
    print("Disconnected.")

##设备上报属性
def upload_device(client):
    topic = '/sys/'+options['productKey']+'/'+options['deviceName']+'/thing/event/property/post'
    while True:
        payload_json = {
            'id': int(time.time()),
            'params': {
'people':1 ##物模型里布尔值以0和1的形式上报
                'picURL': picURLtoIoT,
            },
           'method': "thing.event.property.post"
            }
        print('send data to iot server: ' + str(payload_json))
        client.publish(topic, payload=str(payload_json))

if __name__ == '__main__':
    client = iot.getAliyunIotMqttClient(options['productKey'], options['deviceName'], options['deviceSecret'], secure_mode=3)
    client.on_connect = on_connect
    client.connect(host=host, port=options['port'], keepalive=60)
    p = multiprocessing.Process(target=upload_device, args=(client,))
    p.start()
    detectPeople()
    GPIO.cleanup()
    client.loop_forever()
            
参数 说明
productKey 您添加设备后,保存的设备证书信息,请参见设备证书信息

您可在物联网平台控制台中设备的设备详情页面查看。

deviceName
deviceSecret
port 设置为1883
host 接入域名。获取方法,请参见查看实例终端节点

本示例(iot-as-mqtt.cn-shanghai.aliyuncs.com)为公共实例接入。

cn-shanghai为本示例所在地域。