{"id":408,"date":"2017-10-13T11:16:54","date_gmt":"2017-10-13T02:16:54","guid":{"rendered":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/blog\/2017\/10\/13\/amazon-ai"},"modified":"2022-10-28T22:39:00","modified_gmt":"2022-10-28T13:39:00","slug":"amazon-ai","status":"publish","type":"post","link":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/blog\/2017\/10\/13\/amazon-ai\/","title":{"rendered":"AWS IoT + Amazon Rekognition\/Polly + Raspberry Pi\u3067\u6620\u50cf\u76e3\u8996&\u97f3\u58f0\u901a\u77e5\u30b7\u30b9\u30c6\u30e0\u3092\u3064\u304f\u308b"},"content":{"rendered":"
[\u682a\u5f0f\u4f1a\u793eMMM\u304c2017\u5e74\u5ea6\u4e0b\u534a\u671f\u306b\u6ce8\u529b\u3057\u3066\u3044\u308b\u6280\u8853\u9818\u57df(\u30b5\u30fc\u30d0\u30fc\u30ec\u30b9\u3001IoT\/AI\u3001\u30af\u30e9\u30a6\u30c9\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3)](https:\/\/blog.mmmcorp.co.jp\/blog\/2017\/10\/10\/Second_half_of_FY2017_MMM\/#2\uff0eAWS<\/a> IoT\u30fbAmazon AI\u3092\u521d\u3081\u3068\u3057\u305f\u5148\u9032\u6280\u8853)\u3068\u3044\u3046\u8a18\u4e8b\u3067\u7d39\u4ecb\u3057\u305f\u304c\u3001AWS IoT + Amazon Rekognition\/Polly + Raspberry Pi\u3092\u4f7f\u3063\u3066\u3001\u6620\u50cf\u76e3\u8996\u304a\u3088\u3073\u3001\u7570\u5e38\u691c\u77e5\u3092\u97f3\u58f0\u3067\u901a\u77e5(\u4e0d\u5be9\u8005\u3092\u5a01\u5687)\u3059\u308b\u30b7\u30b9\u30c6\u30e0\u3092\u3064\u304f\u3063\u3066\u307f\u305f\u3002\u3053\u3053\u3067\u306f\u3001\u305d\u306e\u969b\u306e\u8a2d\u8a08\u3084\u60c5\u5831\u3092\u307e\u3068\u3081\u3066\u307f\u308b\u3002<\/p>\n \u5168\u4f53\u7684\u306a\u30b5\u30fc\u30d3\u30b9\u8a2d\u8a08\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308b\u3002<\/p>\n <\/p>\n \u7c21\u5358\u306a\u30d5\u30ed\u30fc\u3092\u4ee5\u4e0b\u306b\u30c6\u30ad\u30b9\u30c8\u3067\u8a18\u3059\u3002<\/p>\n \u4ee5\u4e0b\u3067\u3001\u3053\u3061\u3089\u306e\u8a2d\u8a08\u8a73\u7d30\u3092\u7d39\u4ecb\u3057\u3066\u3086\u304f\u3002<\/p>\n Apex<\/a>\u3092\u7528\u3044\u3066Golang\u3067\u958b\u767a\u3057\u305f\u3002<\/p>\n Node\u3067\u958b\u767a\u3057\u305f\u3002<\/p>\n \u3053\u3053\u304b\u3089\u306f\u5b9f\u969b\u306e\u5b9f\u88c5\u624b\u9806\u3092\u7c21\u5358\u306b\u7d39\u4ecb\u3057\u3066\u3044\u3053\u3046\u3068\u601d\u3046\u3002<\/p>\n \u307e\u305a\u3001Raspberry Pi\u5074\u3067\u753b\u50cf\u309260\u79d2\u6bce\u306b\u30ad\u30e3\u30d7\u30c1\u30e3&\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u5b9f\u88c5\u3092\u884c\u3046\u3002\u9069\u5f53\u306awebcamera\u3092\u4f7f\u3063\u305f\u306e\u3067\u3001[fswebcam](https:\/\/www.Raspberry<\/a> Pi.org\/documentation\/usage\/webcams\/)\u306eNode\u30e9\u30c3\u30d1\u30fc \u6b21\u306bRekognition\u306b\u3088\u308b\u753b\u50cf\u89e3\u6790\u3092\u884c\u3046\u3002\u4eca\u56de\u306f \u73fe\u72b6\u3060\u3068\u3001 \u6b21\u306b\u3001Lambda\u95a2\u6570\u304b\u3089\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3067\u3042\u308bRaspberry Pi\u5074\u3078\u901a\u77e5\u3092\u884c\u3046\u3002\u3053\u3053\u3067\u521d\u3081\u3066\u6c17\u4ed8\u3044\u305f\u306e\u3060\u304c\u3001AWS Go SDK\u3092\u4f7f\u7528\u3057\u3066\u306eIoT pubsub\u304c\u307e\u3060\u3067\u304d\u306a\u304b\u3063\u305f\u3088\u3046\u3067\u3001Node\u3067\u3064\u304f\u3063\u305fLambda\u95a2\u6570\u3092Go\u304b\u3089\u547c\u3073\u51fa\u3057\u3066\u3044\u308b\u3002(SDK\u3067\u306f\u306a\u304fMQTT\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u5b9f\u88c5\u3059\u308c\u3070Go\u3067\u3082\u5b9f\u73fe\u53ef\u80fd\u3060\u304c\u3001AWS IoT\u306e\u6069\u6075\u3092\u3046\u3051\u308b\u305f\u3081\u306bNode\u3067\u5b9f\u88c5\u3057\u305f)\u3002<\/p>\n \u3053\u3053\u306f\u7279\u5b9a\u306e Lambda\u3067\u306e\u5b9f\u88c5\u304c\u7d42\u308f\u3063\u305f\u306e\u3067\u3001Raspberry Pi\u5074\u3067\u305d\u308c\u3092\u8cfc\u8aad\u3059\u308b(AWS IoT\u3068Raspberry Pi\u306e\u8a2d\u5b9a\u306f\u7701\u7565)\u3002<\/p>\n \u4e0a\u8a18\u306e \u4ee5\u4e0a\u3067\u4e00\u9023\u306e\u5b9f\u88c5\u306f\u5b8c\u4e86\u3057\u3001\u30c7\u30d0\u30a4\u30b9\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308b\u3002<\/p>\n <\/p>\n \u5b9f\u969b\u306b\u4e00\u9023\u306e\u6d41\u308c\u3092\u5b9f\u88c5\u3057\u3066\u307f\u3066\u3001\u6539\u5584\u3067\u304d\u305d\u3046\u306a\u70b9\u3092\u3042\u3052\u3066\u307f\u305f\u3002<\/p>\n Amazon Rekognition\u306b\u306f\u3001 \u3053\u308c\u3092\u8e0f\u307e\u3048\u3066\u3001\u4f8b\u3048\u3070\u3001\u30ab\u30e1\u30e9\u306b\u5199\u308a\u8fbc\u3093\u3060\u9854\u3092\u81ea\u52d5\u7684\u306b\u3059\u3079\u3066 \u3053\u306e\u3088\u3046\u306b\u3001API\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u3001\u672c\u6765\u6642\u9593\u304c\u304b\u304b\u308b\u90e8\u5206\u3092\u7701\u304d\u3064\u3064\u3001\u3088\u308a\u9ad8\u5ea6\u306aAI\u5b9f\u88c5\u3092\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3042\u308b\u3002<\/strong><\/p>\n AI\u5b9f\u88c5\u304cAPI\u3067\u7c21\u5358\u306b\u5b9f\u88c5\u3067\u304d\u308b\u306e\u3067\u3001\u3053\u308c\u3089\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u3001\u3088\u308a\u9762\u767d\u3044\u3053\u3068\u306b\u53d6\u308a\u7d44\u3093\u3067\u3044\u3051\u305d\u3046\u3060\u3068\u601d\u3063\u305f\u3002\u4eca\u5f8c\u3082\u3001\u4ed6\u306e\u6a5f\u68b0\u5b66\u7fd2\u7cfb\u306e\u30b5\u30fc\u30d3\u30b9\u3001\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u30a6\u30a9\u30c3\u30c1\u3057\u3064\u3064\u3001\u5b9f\u969b\u306e\u30d3\u30b8\u30cd\u30b9\u306b\u6d3b\u7528\u3057\u3066\u3086\u304d\u305f\u3044\u3002<\/p>\n\u8a2d\u8a08\u6982\u8981<\/h2>\n
\n
\u8a2d\u8a08\u8a73\u7d30<\/h2>\n
Lambda\u95a2\u6570<\/h3>\n
\n
glide<\/code><\/li>\n
env.json<\/code>\u3092\u4f5c\u6210\u3057\u3001\u30c7\u30d7\u30ed\u30a4\u6642\u306b
apex deploy --env-file env.json<\/code>\u306e\u3088\u3046\u306b\u5b9f\u884c\u3059\u308b\u3002<\/li>\n<\/ul>\n
Raspberry Pi\u30af\u30e9\u30a4\u30a2\u30f3\u30c8<\/h3>\n
\n
npm<\/code>\u3092\u4f7f\u7528\u3057\u305f\u3002<\/li>\n
\u5b9f\u88c5\u624b\u9806<\/h2>\n
1.Raspberry Pi\u306b\u3088\u308b\u753b\u50cf\u30ad\u30e3\u30d7\u30c1\u30e3&S3\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/h3>\n
camelot<\/code>\u3092\u4f7f\u7528\u3057\u305f\u3002<\/p>\n
var path = require('path');\nvar fs = require('fs')\n\nvar Camelot = require('camelot');\nvar moment = require('moment');\nvar AWS = require('aws-sdk');\n\nvar FREQUENCY = 60;\nvar s3 = new AWS.S3({\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n region: 'us-east-1',\n});\n\nvar getPath = function(fileName) {\n return path.join(__dirname, '.\/' + fileName);\n}\n\nvar camelot = new Camelot({\n device : '\/dev\/video0',\n});\n\ncamelot.on('frame', function (image) {\n console.log('camelot: success');\n var params = {\n Body: image,\n Bucket: 'BUCKET',\n Key: moment().format('YYYY-MM-DD-HH-mm-ss') + '.jpg'\n };\n s3.putObject(params, function(err, data) {\n if (err) {\n console.log('s3.putObject: error', err);\n }\n console.log('s3.putObject: success', data);\n });\n});\n\ncamelot.on('error', function (err) {\n console.log('camelot: error', err);\n});\n\ncamelot.grab({\n title: 'TITLE',\n frequency: FREQUENCY,\n});<\/code><\/pre>\n
2.Amazon Rekognition\u306b\u3088\u308b\u753b\u50cf\u89e3\u6790<\/h3>\n
DetectLabels API<\/code>\u3067\u7269\u4f53\u691c\u51fa\u3092\u884c\u3044\u3001\u7279\u5b9a\u306e\u30e9\u30d9\u30eb\u304c\u30d2\u30c3\u30c8\u3057\u305f\u5834\u5408\u306b
\u4eba<\/code>\u3060\u3068\u8a8d\u8b58\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u307f\u305f\u3002<\/p>\n
"Human", "Person", "People", "Face", "Head", "Selfie"<\/code>\u306a\u3069\u306b\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u304c\u3001\u77e5\u898b\u3092\u305f\u3081\u308c\u3070\u3001\u30e9\u30d9\u30eb\u3092\u8ffd\u52a0\/\u524a\u9664\u3057\u305f\u308a\u3001\u305d\u308c\u305e\u308c\u306e\u30e9\u30d9\u30eb\u306b\u5bfe\u3059\u308b\u91cd\u307f\u3092\u8abf\u6574\u3057\u305f\u308a\u3057\u3066\u3088\u308a\u7cbe\u5ea6\u3092\u4e0a\u3052\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3068\u601d\u3046\u3002\u3053\u306e\u3088\u3046\u306b\u3001\u81ea\u524d\u3067\u5b9f\u88c5\u3059\u308b\u3068\u5de5\u6570\u304c\u81a8\u3089\u3080AI\u5b9f\u88c5\u3092\u7d20\u65e9\u304f\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u308b<\/strong>\u3002<\/p>\n
package main\n\nimport (\n "log"\n "encoding\/json"\n "github.com\/apex\/go-apex"\n "github.com\/aws\/aws-sdk-go\/aws\/session"\n "github.com\/aws\/aws-sdk-go\/service\/rekognition"\n "github.com\/aws\/aws-sdk-go\/aws"\n "rekognition-alert\/functions\/detectLabels\/alerts"\n)\n\nfunc isHuman(name string) bool {\n values := []string{"Human", "Person", "People", "Face", "Head", "Selfie"}\n for _, v := range values {\n if name == v {\n return true\n }\n }\n return false\n}\n\nfunc hasConfidence(confidence int) bool {\n min := 70\n return confidence > min\n}\n\nfunc shouldAlert(labels []*rekognition.Label) bool {\n for _, l := range labels {\n if isHuman(*l.Name) && hasConfidence(int(*l.Confidence)) {\n return true\n }\n }\n return false\n}\n\nfunc main() {\n apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {\n type S3Records struct {\n S3 struct {\n Bucket struct {\n Name string\n }\n Object struct {\n Key string\n }\n }\n }\n type LambdaEvent struct {\n EventType string\n Records []S3Records\n }\n source := (*json.RawMessage)(&event)\n var e LambdaEvent\n err := json.Unmarshal(*source, &e)\n if err != nil {\n log.Println("json.Unmarshal: error", err)\n }\n\n bucketName := e.Records[0].S3.Bucket.Name\n objectKey := e.Records[0].S3.Object.Key\n\n sess, err := session.NewSession(&aws.Config{\n Region: aws.String("us-east-1"),\n })\n if err != nil {\n log.Println("session.NewSession()", err)\n }\n\n reko := rekognition.New(sess)\n input := &rekognition.DetectLabelsInput{\n Image: &rekognition.Image{\n S3Object: &rekognition.S3Object{\n Bucket: aws.String(bucketName),\n Name: aws.String(objectKey),\n },\n },\n }\n\n result, err := reko.DetectLabels(input)\n if err != nil {\n log.Println("reko.DetectLabels(input): error", err)\n return nil, err\n }\n\n log.Println("reko.DetectLabels(input): result", result)\n\n if shouldAlert(result.Labels) {\n \/\/ \u4eba\u304c\u6620\u3063\u3066\u3044\u308c\u3070Raspberry Pi\u5074\u306b\u901a\u77e5\u3092\u884c\u3046\u51e6\u7406\n }\n\n return result, nil\n })\n}<\/code><\/pre>\n
3.AWS IoT\u306b\u3088\u308bRaspberry Pi\u3078\u306e\u7570\u5e38\u901a\u77e5<\/h3>\n
topic<\/code>\u306b\u5bfe\u3057\u3066API\u3092\u6295\u3052\u308b\u3060\u3051\u3060\u3063\u305f\u306e\u3067\u3001\u7279\u5225\u306a\u3053\u3068\u306f\u3057\u3066\u3044\u306a\u3044\u3002<\/p>\n
\n
4.Raspberry Pi\u3067\u901a\u77e5\u306e\u8cfc\u8aad\u3001Amazon Polly\u306b\u3088\u308b\u97f3\u58f0\u8aad\u307f\u4e0a\u3052<\/h3>\n
var fs = require('fs');\nvar path = require('path');\nvar iot = require('aws-iot-device-sdk');\nvar AWS = require('aws-sdk');\n\nvar getPath = function(fileName) {\n return path.join(__dirname, '.\/' + fileName);\n}\n\nvar device = iot.device({\n keyPath: getPath('certificate\/private.pem.key'),\n certPath: getPath('certificate\/certificate.pem.crt'),\n caPath: getPath('certificate\/root-ca.crt'),\n clientId: 'Raspberry Pi',\n port: 8883,\n host: process.env.IOT_DATA_ENDPOINT,\n});\n\ndevice.on('connect', function() {\n console.log('connect');\n device.subscribe('\/rekognition\/alert'); \/\/ \u7570\u5e38\u306e\u8cfc\u8aad\u958b\u59cb\n require('.\/camera.js'); \/\/ \u30ab\u30e1\u30e9\u3067\u306e\u6620\u50cf\u76e3\u8996\u3082\u958b\u59cb\u3059\u308b\n});\n\ndevice.on('message', function(topic, payload) {\n \/\/ Amazon Polly\u3067\u97f3\u58f0\u8aad\u307f\u4e0a\u3052\u3092\u3059\u308b\u51e6\u7406\n});\n\nprocess.stdin.resume();\nprocess.on('SIGINT', function() {\n console.log('SIGINT');\n process.exit();\n});<\/code><\/pre>\n
Amazon Polly\u3067\u97f3\u58f0\u8aad\u307f\u4e0a\u3052\u3092\u3059\u308b\u51e6\u7406<\/code>\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002Polly\u3067\u97f3\u58f0\u30c7\u30fc\u30bf\u3092\u8fd4\u3057\u3066\u304f\u308c\u308b\u306e\u3067\u3001\u305d\u308c\u3092\u518d\u751f\u3059\u308b\u3002\u518d\u751f\u306f\u30e9\u30ba\u30d1\u30a4\u3067\u3046\u307e\u304f\u52d5\u304d\u305d\u3046\u306aplay-sound<\/a>\u3092\u4f7f\u7528\u3057\u305f\u3002<\/p>\n
var player = require('play-sound')(opts = {})\n\nvar polly = new AWS.Polly({\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n region: 'us-east-1',\n});\n\nvar getPath = function(fileName) {\n return path.join(__dirname, '.\/' + fileName);\n}\n\ndevice.on('message', function(topic, payload) {\n var spokenText = '\u30ab\u30e1\u30e9\u306b\u4e0d\u5be9\u8005\u3092\u691c\u77e5\u3057\u307e\u3057\u305f\u3002' \/\/ payload\u306b\u3088\u3063\u3066\u30c6\u30ad\u30b9\u30c8\u3092\u5207\u308a\u66ff\u3048\u308b\u3053\u3068\u3082\u3067\u304d\u308b\n\n var params = {\n OutputFormat: 'mp3',\n Text: spokenText,\n VoiceId: 'Mizuki',\n };\n\n polly.synthesizeSpeech(params, function(err, data) {\n if (err) {\n console.log(err);\n return;\n }\n\n console.log('data', data);\n var fileName = 'temp.mp3';\n fs.writeFileSync(getPath(fileName), data.AudioStream);\n\n player.play(getPath(fileName), function(error) {\n if (error) {\n console.log('player.play: error', error);\n }\n console.log('player.play: success');\n });\n });\n});<\/code><\/pre>\n
\u6700\u7d42\u7684\u306a\u30c7\u30d0\u30a4\u30b9<\/h2>\n
npm start<\/code>\u3067\u76e3\u8996\u3092\u958b\u59cb\u3001\u7570\u5e38\u3092\u691c\u77e5\u3057\u305f\u5834\u5408\u3001\u30b9\u30d4\u30fc\u30ab\u30fc\u304b\u3089\u97f3\u58f0\u3092\u767a\u3057\u3001\u4e0d\u5be9\u8005\u3092\u5a01\u5687\u3059\u308b\u4ed5\u69d8\u306b\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n
\u6539\u5584\u3067\u304d\u305d\u3046\u306a\u70b9<\/h2>\n
\u5b66\u7fd2\u3059\u308b\u76e3\u8996\u30ab\u30e1\u30e9\u306e\u5b9f\u73fe<\/h3>\n
\u30b3\u30ec\u30af\u30b7\u30e7\u30f3<\/code>\u3068\u3044\u3046\u4ed5\u7d44\u307f\u304c\u3042\u3063\u3066\u3001\u3072\u3068\u308a\u306e\u4eba\u7269(
\u30b3\u30ec\u30af\u30b7\u30e7\u30f3<\/code>)\u306b\u5bfe\u3057\u3066\u8907\u6570\u306e\u9854\u3092\u7d10\u4ed8\u3051\u308b(
\u9854\u8a8d\u8b58<\/code>\u3059\u308b)\u3053\u3068\u3067\u3001
1:1<\/code>\u306e\u5358\u7d14\u306a\u9854\u6bd4\u8f03\u3067\u306f\u306a\u304f\u3001\u3088\u308a\u7cbe\u5ea6\u304c\u9ad8\u3044
1:\u591a<\/code>\u306e\u6bd4\u8f03\u3092\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n
\u30b3\u30ec\u30af\u30b7\u30e7\u30f3<\/code>\u306b\u8ffd\u52a0\u3057\u3066\u304a\u304d\u3001\u7ba1\u7406\u753b\u9762\u306a\u3069\u3067\u3001
\u77e5\u4eba\/\u5bb6\u65cf\/\u53cb\u4eba<\/code>\u306a\u3069\u306e\u30e9\u30d9\u30eb\u4ed8\u3051\u3092\u884c\u3048\u3070\u3001
\u4e0d\u5be9\u8005<\/code>\u304b\u305d\u3046\u3067\u306a\u3044\u304b\u3092\u30ab\u30e1\u30e9\u306b\u5b66\u7fd2\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002\u3082\u3057\u304f\u306f\u3001\u300c\u9031\u306bX\u56de\u4ee5\u4e0a\u6620\u308a\u8fbc\u3093\u3060\u4eba\u306f
\u77e5\u4eba<\/code>\u3068\u3057\u3066\u8a8d\u8b58\u3059\u308b\u300d\u306a\u3069\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u7d44\u3093\u3067\u3082\u3044\u3044\u304b\u3082\u3057\u308c\u306a\u3044\u3002<\/p>\n
\u305d\u306e\u4ed6\u306e\u6539\u5584\u70b9<\/h3>\n
\n
\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304b\u3089AWS IoT\u306epublish\u3092\u5b9f\u884c\u3001Lambda\u95a2\u6570\u3092\u30c8\u30ea\u30ac\u30fc<\/code>\u3059\u308b\u306a\u3069\u3057\u3066\u3001\u3088\u308a\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\u306e\u30b3\u30fc\u30c9\u3092\u6e1b\u3089\u3059\u3053\u3068\u306f\u53ef\u80fd\u304b\u3082\u3057\u308c\u306a\u3044\u3002<\/li>\n
\u307e\u3068\u3081<\/h2>\n
\u53c2\u8003<\/h2>\n
\n