基于树莓派的监控摄像头拍摄到人像后,将照片传入阿里云对象存储(OSS);同时,物联网服务通过监听设备上报的属性信息,获取图片,并调用人脸识别API进行人脸识别, 然后将结果推送到钉钉群。

流程图



物料准备

需准备以下硬件:

  • 树莓派开发板
  • 适用于树莓派的摄像头
  • 红外线传感器

并且,需将摄像头、红外线传感器连接树莓派开发板。

  • 将摄像头连接线头插入树莓派卡槽中。
  • 将红外线传感器(PIR)连接线头插入树莓派GPIO引脚。

创建对象存储Bucket

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

  1. 登录对象存储控制台

    若您还未开通对象存储服务,请单击立即开通,进入购买页开通服务。对象存储计费,请参见对象存储计费方式

  2. 单击存储空间对应的新建Bucket+按钮,新建一个Bucket。
    参数 说明
    Bucket名称 自定义Bucket名称。

    Bucket名称仅支持:小写英文字母、数字和连接号(-),且不能以连接号开头或结尾。

    区域 选择您要创建的Bucket所在地域。创建成功后,地域不可更改。
    存储类型 选择为标准存储
    读写权限 本示例中,选择为公共读写。实际使用中,请根据您的实际需要选择。
    同城区域冗余存储 本示例中,选择为关闭。实际使用中,请根据您的实际需要选择。
    实时日志查询 本示例中,选择为不开通。实际使用中,请根据您的实际需要选择。


    Bucket创建后,其概览页会显示Endpoint和域名。Endpoint信息需配置到设备端SDK中。



  3. 测试Bucket。
    1. 在Bucket页,单击文件管理 > 上传文件,上传一张测试图片。

    2. 图片上传后,单击详情按钮,再将文件URL粘贴到浏览器中。浏览器中显示该图片,证明Bucket使用正常。

创建产品和设备

  1. 登录物联网平台控制台
  2. 在左侧导航栏,单击设备管理 > 产品,创建摄像头产品。

  3. 在产品的产品详情功能定义页签下,添加两个属性。
    标识符 数据类型 数据定义
    people bool 0:没人;1:有人。
    picURL text 数据长度限制:2048字节。


  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-cn-beijing.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-cn-shanghai.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':1883,
        '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()

完整的示例代码,请见本文末附录章节。

创建服务

  1. 登录物联网平台控制台
  2. 在左侧导航栏,单击开发服务 > IoT Studio
  3. IoT Studio页的项目列表中,单击已有项目对应的进入按钮进入项目,或单击新建项目,创建一个项目。
  4. 在项目的产品管理页,单击关联物联网平台产品,将之前创建的摄像头产品与该项目关联。关联产品后,产品下的所有设备随之与项目关联。
  5. 单击服务开发 > 新建服务,新建一个服务。
  6. 服务开发页,单击左侧的节点按钮,服务开发的功能节点将展示在列表中。
  7. 设备页签下,拖拽一个设备触发节点到画布上,触发数据源配置为摄像头产品下设备的属性上报。

  8. 配置一个云市场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"


  9. 配置一个钉钉机器人。
    参数 说明
    节点名称 输入节点名称
    Webhook 钉钉群机器人的Webhook地址。

    需在钉钉群对话窗口,单击群设置...按钮,然后选择群机器人,创建一个钉钉机器人,并复制其Webhook地址。

    配置方法 选择为自定义
    消息类型 选择为FeedCard类型
    内容配置
    • 修改消息标题title
    • 修改picURL值为{{query.props.picURL.value}}


  10. 单击页面右上角保存,保存配置。
  11. 单击部署,部署服务。
  12. 部署完成后,单击启动
  13. 调试服务。
    1. 单击调试 > 前往,前往产品的在线调试页。
    2. 启动虚拟设备。
    3. 输入模拟属性值,单击推送

      数据推送成功,钉钉群将收到图片。



  14. 发布服务。

    需待该服务所在项目中的所有服务都部署、调试完成后,才能单击服务页面右上角发布按钮,发布该服务。

附录:设备端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-cn-beijing.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-cn-shanghai.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':1883,
    '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()