JavaScript 智能监控详解

第 8 章树莓 Pi 图像流中,我们学习了如何将树莓 Pi 相机模块连接到树莓 Pi 3,抓取图片或视频,然后实时上传/流。在这一章中,我们将把这个逻辑带到下一个层次。我们将在检测到入侵时拍摄一张照片,然后将该图像发送到亚马逊 Rekognition 平台,并将该图像与一组图像进行比较。

在本章中,我们将讨论以下几点:

以下引用自亚马逊 Rekognition(https://aws.amazon.com/rekognition/):

"Amazon Rekognition is a service that makes it easy to add image analysis to your applications. With Rekognition, you can detect objects, scenes, faces; recognize celebrities; and identify inappropriate content in images. You can also search and compare faces. Rekognition's API enables you to quickly add sophisticated deep learning-based visual search and image classification to your applications."

在本章中,我们将利用 AWS Rekognition 功能来帮助我们设置基于人脸识别的条件监控,而不是人脸检测。

假设你用树莓派在你家门口设置了一个摄像头,并对它进行编程,让它不断拍摄入侵者的照片并发送给你。在这个设置中,你会收到每个上门的人的图像,例如,你的家人、邻居等等。但是如果只有当入侵者是一个未知的人时才通知你呢?这就是我所说的智能监控。

第 8 章树莓 Pi 图像流中,我们构建了一个设置,当检测到入侵时,它会捕获图像,然后发送电子邮件并实时更新应用。

在这一章中,我们将使用一组可信的人脸来播种 AWS Rekognition。然后,当有一个图像被摄像机捕获时,在入侵检测时,我们将其发送到 AWS Rekognition 以执行面部识别。如果图像与可信图像之一匹配,则不会发生任何事情;否则,将发送电子邮件通知。

要了解更多关于 AWS Rekogniton 及其工作原理,请看宣布亚马逊 Rekognition -基于深度学习的图像分析(https://www.youtube.com/watch?v=b6gN9jCmq3w)。

现在我们已经了解了我们要做的事情,我们将开始设置树莓派。

我们将设置摄像机和运动检测器,就像我们在第 8 章树莓派图像流中所做的那样。接下来,我们将添加在检测到运动时捕获图像所需的逻辑,然后将其发送进行处理。

在此之前,我们需要为 Rekognition 集合植入授权人脸。

这个脚本可以是作为 API 引擎一部分的 API,使用 web 仪表板我们可以上传和播种图像。但是为了简单起见,我们将从机器上运行这个独立的脚本。

在开始开发之前,我们需要用 AWS 命令行界面和 AWS 凭据设置我们的本地机器。

首先,我们需要安装 AWS 命令行界面。前往https://aws.amazon.com/cli并按照页面上的说明进行操作。要从命令提示符测试安装,请运行:

aws --version

你应该看到类似这样的东西:

aws-cli/1.7.38 Python/2.7.9 Darwin/16.1.0

一旦设置完成,我们需要配置 AWS 凭据,这样只要我们使用这台机器,我们就不需要在代码中输入任何凭据。

运行以下命令:

aws configure

应该给你四个问题;用适当的信息填充它们:

如果您在配置 AWS 凭据时遇到问题,请参考http://docs . AWS . Amazon . com/CLI/latest/user guide/CLI-chap-入门. html # CLI-quick-configuration

另一种选择是在代码本身中添加accessKeyIdsecretAccessKey。但是我们仍然需要accessKeyIdsecretAccessKey继续。

一旦配置完成,我们将开始与 AWS Rekognition 接口。

创建一个名为chapter9的文件夹,在这个文件夹里面,创建一个名为rekogniton_seed的文件夹。在这个文件夹中,创建一个名为seed.js的文件。

更新seed.js如下:

var config = { 
    collectionName: 'AIOWJS-FACES', 
    region: 'eu-west-1', 
// If the credentials are set using `aws configure`, below two properties are not needed.    
    accessKeyId: 'YOUR-ACCESSKEYID',  
    secretAccessKey: YOUR-SECRETACCESSKEY' 
}; 

var AWS = require('aws-sdk'); 
var fs = require('fs-extra'); 
var path = require('path'); 
var klawSync = require('klaw-sync') 

AWS.config.region = config.region; 

var rekognition = new AWS.Rekognition({ 
    region: config.region, 
 // accessKeyId: config.accessKeyId, // uncomment as applicable 
 // secretAccessKey: config.secretAccessKey // uncomment as applicable 
}); 

function createCollection() { 
    rekognition.createCollection({ 
        'CollectionId': config.collectionName 
    }, (err, data) => { 
        if (err) { 
            console.log(err, err.stack); // an error occurred 
        } else { 
            console.log(data); // successful response 
        } 
    }); 
} 

function indexFaces() { 
    var paths = klawSync('./faces', { 
        nodir: true, 
        ignore: ['*.json'] 
    }); 

    paths.forEach((file) => { 
        var p = path.parse(file.path); 
        var name = p.name.replace(/\W/g, ''); 
        var bitmap = fs.readFileSync(file.path); 

        rekognition.indexFaces({ 
            'CollectionId': config.collectionName, 
            'DetectionAttributes': ['ALL'], 
            'ExternalImageId': name, 
            'Image': { 
                'Bytes': bitmap 
            } 
        }, (err, data) => { 
            if (err) { 
                console.log(err, err.stack); // an error occurred 
            } else { 
                console.log(data.FaceRecords); // successful response 
                fs.writeJson(file.path + '.json', data, (err) => { 
                    if (err) return console.error(err) 
                }); 
            } 
        }); 
    }); 
} 

createCollection(); 
indexFaces(); 

Please refer to the source code for the additional comments: https://github.com/PacktPublishing/Practical-Internet-of-Things-with-JavaScript.

正如我们从前面的代码片段中看到的,我们正在eu-west-1区域创建一个名为AIOWJS-FACES的新集合。您可以在代码中使用accessKeyIdsecretAccessKey,也可以使用 AWS 命令行界面中的配置。如果您正在使用 AWS CLI 配置中的密钥和密码,您可以在初始化rekognition的新实例时注释掉这两行。

我们调用createCollection()来创建一个新的集合,这个只需要运行一次。

You can seed data as many times as you want, but collection creation should happen only once.

一旦创建了集合,我们将从名为faces的文件夹中索引一些图像,我们现在将创建该文件夹。在rekogniton_seed文件夹的根目录下创建一个名为faces的文件夹。在这个文件夹中,上传清晰的人脸图像。图像的质量和清晰度越好,被识别的机会就越大。

我在faces文件夹里放了几张我的照片。在开始播种之前,我们需要安装所需的依赖项:

  1. 打开rekogniton_seed文件夹内的命令提示符/终端,运行:
npm init --yes
  1. 接下来,运行:
npm install aws-sdk fs-extra klaw-sync --save
  1. 安装完成后,通过运行以下命令创建集合并播种面:
node seed.js
  1. 对于每个上传的图像,我们应该会看到如下输出:
[ { Face:  
     { FaceId: '2d7ac2b3-fa84-5a16-ad8c-7fa670b8ec8c', 
       BoundingBox: [Object], 
       ImageId: '61a299b6-3004-576d-b966-31fb6780f1c7', 
       ExternalImageId: 'photo', 
       Confidence: 99.96211242675781 }, 
    FaceDetail:  
     { BoundingBox: [Object], 
       AgeRange: [Object], 
       Smile: [Object], 
       Eyeglasses: [Object], 
       Sunglasses: [Object], 
       Gender: [Object], 
       Beard: [Object], 
       Mustache: [Object], 
       EyesOpen: [Object], 
       MouthOpen: [Object], 
       Emotions: [Object], 
       Landmarks: [Object], 
       Pose: [Object], 
       Quality: [Object], 
       Confidence: 99.96211242675781 } } ] 

该对象将由关于由 Rekognition 分析的图像的信息组成。

播种完成后,您可以在faces文件夹中查找*.json文件。这些 JSON 文件将包含更多关于图像的信息。

现在种子已经完成,让我们验证种子。这一步完全是可选的;如果你愿意,你可以跳过这一步。

chapter9文件夹的根目录下新建一个名为rekogniton_seed_test的文件夹。然后在rekogniton_seed_test的根目录下创建一个名为faces的文件夹,并将您想要测试的图像转储到这个文件夹中。就我而言,这张照片是我在不同地点的照片。

接下来,创建一个名为seed_test.js的文件并进行更新,如下图所示:

var config = { 
    collectionName: 'AIOWJS-FACES', 
    region: 'eu-west-1', 
    accessKeyId: 'ACCESSKEYID',  
    secretAccessKey: SECRETACCESSKEY' 
}; 

var AWS = require('aws-sdk'); 
var fs = require('fs-extra'); 
var path = require('path'); 
var klawSync = require('klaw-sync') 

AWS.config.region = config.region; 

var rekognition = new AWS.Rekognition({ 
    region: config.region, 
    // accessKeyId: config.accessKeyId, // uncomment as applicable 
    // secretAccessKey: config.secretAccessKey // uncomment as applicable 
}); 

// Once you've created your collection you can run this to test it out. 
function FaceSearchTest(imagePath) { 
    var bitmap = fs.readFileSync(imagePath); 

    rekognition.searchFacesByImage({ 
        "CollectionId": config.collectionName, 
        "FaceMatchThreshold": 80, 
        "Image": { 
            "Bytes": bitmap, 
        }, 
        "MaxFaces": 1 
    }, (err, data) => { 
        if (err) { 
            console.error(err, err.stack); // an error occurred 
        } else { 
            // console.log(data); // successful response 
            console.log(data.FaceMatches.length > 0 ? data.FaceMatches[0].Face : data); 
        } 
    }); 
} 

FaceSearchTest(__dirname + '/faces/arvind_2.jpg'); 

在前面的代码中,我们从faces文件夹中拾取图像并提交进行识别,然后打印适当的响应。

完成后,我们将安装所需的依赖项:

  1. 打开rekogniton_seed_test文件夹内的命令提示符/终端,运行:
npm init --yes
  1. 然后运行:
npm install aws-sdk fs-extra path --save
  1. 现在,我们都准备运行这个示例。从rekogniton_seed_test文件夹中,运行:
node seed_test.js
  1. 我们应该看到如下内容:
{ FaceId: '2d7ac2b3-fa84-5a16-ad8c-7fa670b8ec8c', 
  BoundingBox:  
   { Width: 0.4594019949436188, 
     Height: 0.4594019949436188, 
     Left: 0.3076919913291931, 
     Top: 0.2820509970188141 }, 
  ImageId: '61a299b6-3004-576d-b966-31fb6780f1c7', 
  ExternalImageId: 'photo', 
  Confidence: 99.96209716796875 } 

从前面的回答中有几件事需要注意:

  • FaceId:这是当前人脸匹配的 ID
  • ImageId:这是当前人脸匹配的图像

这样,我们甚至可以从我们已经索引/播种的图像中标记用户。

您可以通过放置一个与我们的种子数据不匹配的图像并更新前面代码中的最后一行来进行否定测试,如下所示:

FaceSearchTest(__dirname + '/faces/no_arvind.jpg');

We should see something like the following:

{ SearchedFaceBoundingBox:

{ Width: 0.5322222113609314,

Height: 0.5333333611488342,

Left: 0.2777777910232544,

Top: 0.12444444745779037 },

SearchedFaceConfidence: 99.76634979248047,

FaceMatches: [] }

如你所见,没有找到匹配的。

一旦我们捕捉到图像,我们将在树莓派中使用前面的方法。

现在我们已经播种了一个 Rekognition 集合,并对其进行了测试(可选步骤),现在我们将开始设置树莓 Pi 代码。

我们将按原样使用chapter8文件夹中的所有其他代码片段,并且只修改chapter9文件夹中的树莓派客户端。

将整个代码从chapter8文件夹复制到chapter9文件夹。然后,打开桌面或树莓派上的pi-client文件夹,并按如下方式更新:

var config = require('./config.js'); 
var mqtt = require('mqtt'); 
var GetMac = require('getmac'); 
var Raspistill = require('node-raspistill').Raspistill; 
var crypto = require("crypto"); 
var Gpio = require('onoff').Gpio; 
var exec = require('child_process').exec; 

var AWS = require('aws-sdk'); 

var pir = new Gpio(17, 'in', 'both'); 
var raspistill = new Raspistill({ 
    noFileSave: true, 
    encoding: 'bmp', 
    width: 640, 
    height: 480 
}); 

// Rekognition config 
var config = { 
    collectionName: 'AIOWJS-FACES', 
    region: 'eu-west-1', 
    accessKeyId: 'ACCESSKEYID',  
    secretAccessKey: 'SECRETACCESSKEY' 
}; 

AWS.config.region = config.region; 

var rekognition = new AWS.Rekognition({ 
    region: config.region, 
    accessKeyId: config.accessKeyId, 
    secretAccessKey: config.secretAccessKey 
}); 

var client = mqtt.connect({ 
    port: config.mqtt.port, 
    protocol: 'mqtts', 
    host: config.mqtt.host, 
    clientId: config.mqtt.clientId, 
    reconnectPeriod: 1000, 
    username: config.mqtt.clientId, 
    password: config.mqtt.clientId, 
    keepalive: 300, 
    rejectUnauthorized: false 
}); 

client.on('connect', function() { 
    client.subscribe('rpi'); 
    GetMac.getMac(function(err, mac) { 
        if (err) throw err; 
        macAddress = mac; 
        client.publish('api-engine', mac); 
        // startStreaming(); 
    }); 

}); 

client.on('message', function(topic, message) { 
    message = message.toString(); 
    if (topic === 'rpi') { 
        console.log('API Engine Response >> ', message); 
    } else { 
        console.log('Unknown topic', topic); 
    } 
}); 

var processing = false; 

// keep watching for motion 
pir.watch(function(err, value) { 
    if (err) exit(); 
    if (value == 1 && !processing) { 
        raspistill.takePhoto() 
            .then((photo) => { 
                console.log('took photo'); 
                checkForMatch(photo, function(err, authorizedFace) { 
                    if (err) { 
                        console.error(err); 
                    } else { 
                        if (authorizedFace) { 
                            console.log('User Authorized'); 
                        } else { 
                            // unauthorized user,  
                            // send an email! 
                            require('./mailer').sendEmail(photo, function(err, info) { 
                                if (err) { 
                                    console.error(err); 
                                } else { 
                                    console.log('Email Send Success', info); 
                                } 
                            }); 
                        } 
                    } 
                }); 
            }) 
            .catch((error) => { 
                console.error('something bad happened', error); 
            }); 
    } 
}); 

function checkForMatch(image, cb) { 
    rekognition.searchFacesByImage({ 
        'CollectionId': config.collectionName, 
        'FaceMatchThreshold': 80, 
        'Image': { 
            'Bytes': image, 
        }, 
        'MaxFaces': 1 
    }, (err, data) => { 
        if (err) { 
            console.error(err, err.stack); // an error occurred 
            cb(err, null); 
        } else { 
            // console.log(data); // successful response 
            console.log(data.FaceMatches.length > 0 ? data.FaceMatches[0].Face : data); 
            cb(null, data.FaceMatches.length >= 1); 
        } 
    }); 
} 

function exit() { 
    pir.unexport(); 
    process.exit(); 
} 

在前面的代码中,我们有向 AWS Rekognition 发出请求所需的配置,然后我们运行checkForMatch(),它将拍摄原始照片并检查匹配情况。如果找到任何匹配项,我们将不会收到电子邮件,如果没有找到匹配项,我们将会收到电子邮件。

接下来,我们将安装所需的依赖项。

运行以下命令:

npm install getmac mqtt node-raspistill aws-sdk --save

安装完成后,启动代理、api-engine和 web 仪表板。然后运行以下命令:

node index.js

触发一个动作来捕捉图像。如果捕获的图像与我们索引的人脸之一匹配,我们将不会收到电子邮件;如果是的话,我们会收到一封邮件。

很简单,不是吗?这是一个非常强大的设置,我们已经建立了在我们的家庭或办公室提供监控,简单的错误警报可以很容易地识别。

这个例子可以进一步扩展到使用基于云的呼叫服务(如 Twilio)发送推送通知或呼叫邻居。

在本章中,我们已经看到了如何使用树莓 Pi 和 AWS Rekognition 平台建立智能监控系统。

我们从了解 AWS Rekognition 平台开始,然后用我们的图像索引/播种一个集合。接下来,我们更新了树莓 Pi 代码,在检测到运动时拍摄一张照片,然后将该图像发送到 AWS Rekognition,以识别当前照片中的人脸是否与任何索引图像匹配。如果有,我们忽略图像;如果没有,我们会发送一封带有该图片的电子邮件。

有了这个,我们用 JavaScript 完成了,实用物联网。我希望您已经学习了一些利用 JavaScript 和树莓 Pi 构建简单而强大的物联网解决方案的方法。

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

Linux内核技术实战课 -〔邵亚方〕

动态规划面试宝典 -〔卢誉声〕

etcd实战课 -〔唐聪〕

打造爆款短视频 -〔周维〕

MySQL 必知必会 -〔朱晓峰〕

数据分析思维课 -〔郭炜〕

陈天 · Rust 编程第一课 -〔陈天〕

全链路压测实战30讲 -〔高楼〕

LangChain 实战课 -〔黄佳〕