Skip to content

Instantly share code, notes, and snippets.

@mblackstock
Last active December 8, 2017 01:02
Show Gist options
  • Save mblackstock/079cec0121fd9ba769fe43fb9cabf024 to your computer and use it in GitHub Desktop.
Save mblackstock/079cec0121fd9ba769fe43fb9cabf024 to your computer and use it in GitHub Desktop.
Flows on FRED for remote photos and image recognition using AWS
from __future__ import print_function
import boto3
from decimal import Decimal
import json
import urllib
print('Loading function')
rekognition = boto3.client('rekognition')
sqs = boto3.resource('sqs')
queue = sqs.Queue('https://your_queue_url')
#queue = sqs.get_queue_by_name(QueueName='node-red-test-queue')
# --------------- Helper Functions to call Rekognition APIs ------------------
def detect_faces(bucket, key):
response = rekognition.detect_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}})
return response
def detect_labels(bucket, key):
response = rekognition.detect_labels(Image={"S3Object": {"Bucket": bucket, "Name": key}})
# Sample code to write response to DynamoDB table 'MyTable' with 'PK' as Primary Key.
# Note: role used for executing this Lambda function should have write access to the table.
#table = boto3.resource('dynamodb').Table('MyTable')
#labels = [{'Confidence': Decimal(str(label_prediction['Confidence'])), 'Name': label_prediction['Name']} for label_prediction in response['Labels']]
#table.put_item(Item={'PK': key, 'Labels': labels})
return response
def index_faces(bucket, key):
# Note: Collection has to be created upfront. Use CreateCollection API to create a collecion.
#rekognition.create_collection(CollectionId='BLUEPRINT_COLLECTION')
response = rekognition.index_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}}, CollectionId="BLUEPRINT_COLLECTION")
return response
# --------------- Main handler ------------------
def lambda_handler(event, context):
'''Demonstrates S3 trigger that uses
Rekognition APIs to detect faces, labels and index faces in S3 Object.
'''
#print("Received event: " + json.dumps(event, indent=2))
# Get the object from the event
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))
try:
# Calls rekognition DetectFaces API to detect faces in S3 object
#response = detect_faces(bucket, key)
# Calls rekognition DetectLabels API to detect labels in S3 object
response = detect_labels(bucket, key)
# Calls rekognition IndexFaces API to detect faces in S3 object and index faces into specified collection
#response = index_faces(bucket, key)
# Print response to console.
print(response)
# Send result to SQS
queue.send_message(MessageBody=json.dumps(response))
return response
except Exception as e:
print(e)
print("Error processing object {} from bucket {}. ".format(key, bucket) +
"Make sure your object and bucket exist and your bucket is in the same region as this function.")
raise e
[
{
"id": "208c9bc0.f06244",
"type": "mqtt out",
"z": "bfdff962.385948",
"name": "",
"topic": "users/mike/camera-mac",
"qos": "",
"retain": "",
"broker": "f1421e13.e71c9",
"x": 450,
"y": 80,
"wires": []
},
{
"id": "81e9b32f.d61b8",
"type": "http in",
"z": "bfdff962.385948",
"name": "",
"url": "/camera",
"method": "post",
"upload": false,
"swaggerDoc": "",
"x": 150,
"y": 200,
"wires": [
[
"dec9a817.04f4f8"
]
]
},
{
"id": "8b9cb0f5.42487",
"type": "http response",
"z": "bfdff962.385948",
"name": "",
"x": 570,
"y": 240,
"wires": []
},
{
"id": "339f0b0c.af6854",
"type": "ui_template",
"z": "bfdff962.385948",
"group": "d7e5365d.857a68",
"name": "Push Cam",
"order": 2,
"width": "6",
"height": "4",
"format": "Push Cam\n<img src=\"data:image/png;base64,{{msg.payload}}\"\n id='img'\n alt='Getting Image'\n>",
"storeOutMessages": true,
"fwdInMessages": true,
"templateScope": "local",
"x": 590,
"y": 160,
"wires": [
[]
]
},
{
"id": "dec9a817.04f4f8",
"type": "function",
"z": "bfdff962.385948",
"name": "move to payload, stringify",
"func": "msg.payload = msg.req.body.toString();\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 310,
"y": 260,
"wires": [
[
"8b9cb0f5.42487",
"339f0b0c.af6854",
"eb5c43e9.9fd8e",
"657783d0.cd544c"
]
]
},
{
"id": "2a0fedad.960e22",
"type": "ui_button",
"z": "bfdff962.385948",
"name": "",
"group": "d7e5365d.857a68",
"order": 1,
"width": 0,
"height": 0,
"passthru": false,
"label": "Take a picture",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 200,
"y": 80,
"wires": [
[
"208c9bc0.f06244"
]
]
},
{
"id": "59922fd8.dbc36",
"type": "comment",
"z": "bfdff962.385948",
"name": "photo receive and display",
"info": "Assumes we receive the data as a base64 encoded\nJPEG from the camera.\n\nOnce we have base64 installed on FRED, we can do\nthe encoding locally",
"x": 150,
"y": 160,
"wires": []
},
{
"id": "fbbb24fa.3e68c8",
"type": "comment",
"z": "bfdff962.385948",
"name": "signal camera to take photo",
"info": "",
"x": 180,
"y": 40,
"wires": []
},
{
"id": "32cfca7c.8f39b6",
"type": "amazon s3",
"z": "bfdff962.385948",
"aws": "310b2679.e70e1a",
"region": "",
"operation": "put",
"bucketname": "node-red-demo",
"keyname": "",
"name": "",
"x": 550,
"y": 380,
"wires": [
[]
]
},
{
"id": "657783d0.cd544c",
"type": "function",
"z": "bfdff962.385948",
"name": "generate key",
"func": "msg.key = 'snapshot-'+new Date().getTime()+'.png'\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 270,
"y": 380,
"wires": [
[
"ce7ecabc.3d3728"
]
]
},
{
"id": "ce7ecabc.3d3728",
"type": "base64",
"z": "bfdff962.385948",
"name": "",
"x": 420,
"y": 380,
"wires": [
[
"32cfca7c.8f39b6"
]
]
},
{
"id": "eb5c43e9.9fd8e",
"type": "debug",
"z": "bfdff962.385948",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 590,
"y": 300,
"wires": []
},
{
"id": "87e9821d.a99cb",
"type": "comment",
"z": "bfdff962.385948",
"name": "save in S3",
"info": "Bucket is node-red-demo",
"x": 100,
"y": 320,
"wires": []
},
{
"id": "f1421e13.e71c9",
"type": "mqtt-broker",
"z": "",
"broker": "mqtt.sensetecnic.com",
"port": "1883",
"clientid": "mike-fred",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"willTopic": "",
"willQos": "0",
"willPayload": "",
"birthTopic": "",
"birthQos": "0",
"birthPayload": ""
},
{
"id": "d7e5365d.857a68",
"type": "ui_group",
"z": "",
"name": "Camera",
"tab": "f3f47ae8.947888",
"disp": true,
"width": "6"
},
{
"id": "310b2679.e70e1a",
"type": "amazon config",
"z": "",
"name": "AWS",
"region": "us-west-2"
},
{
"id": "f3f47ae8.947888",
"type": "ui_tab",
"z": "",
"name": "Security",
"icon": "dashboard",
"order": 3
}
]
[
{
"id": "7fe49cc0.cae734",
"type": "amazon sqs",
"z": "653c8c20.9f3d04",
"aws": "310b2679.e70e1a",
"region": "",
"operation": "receive",
"queuename": "https://sqs.us-west-2.amazonaws.com/213568653363/node-red-test-queue",
"name": "",
"x": 170,
"y": 120,
"wires": [
[
"20963685.96f80a",
"3a55749a.2f4a9c"
]
]
},
{
"id": "3305d5a9.d198aa",
"type": "debug",
"z": "653c8c20.9f3d04",
"name": "",
"active": true,
"console": "false",
"complete": "true",
"x": 610,
"y": 220,
"wires": []
},
{
"id": "20963685.96f80a",
"type": "change",
"z": "653c8c20.9f3d04",
"name": "set receipt handle",
"rules": [
{
"t": "set",
"p": "key",
"pt": "msg",
"to": "payload.Messages[0]['Body']",
"tot": "msg"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload.Messages[0].ReceiptHandle",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 210,
"y": 180,
"wires": [
[
"44361e03.c5e5c"
]
]
},
{
"id": "44361e03.c5e5c",
"type": "amazon sqs",
"z": "653c8c20.9f3d04",
"aws": "310b2679.e70e1a",
"region": "",
"operation": "delete",
"queuename": "https://sqs.us-west-2.amazonaws.com/213568653363/node-red-test-queue",
"name": "",
"x": 210,
"y": 240,
"wires": [
[]
]
},
{
"id": "d10b304e.95b78",
"type": "ui_template",
"z": "653c8c20.9f3d04",
"group": "d7e5365d.857a68",
"name": "",
"order": 0,
"width": "6",
"height": "6",
"format": "Image Labels\n<ul>\n <li ng-repeat=\"label in msg.payload.Labels\">{{label.Name}}: {{label.Confidence}}%</li>\n</ul>\n",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 620,
"y": 80,
"wires": [
[]
]
},
{
"id": "9e16da41.a9df78",
"type": "json",
"z": "653c8c20.9f3d04",
"name": "",
"pretty": false,
"x": 430,
"y": 140,
"wires": [
[
"d10b304e.95b78",
"3305d5a9.d198aa"
]
]
},
{
"id": "3a55749a.2f4a9c",
"type": "function",
"z": "653c8c20.9f3d04",
"name": "set payload",
"func": "if (msg.payload.Messages && msg.payload.Messages.length > 0) {\n msg.payload = msg.payload.Messages[0].Body;\n return msg;\n}\nreturn null",
"outputs": 1,
"noerr": 0,
"x": 350,
"y": 80,
"wires": [
[
"9e16da41.a9df78"
]
]
},
{
"id": "f31acb40.8ed1e8",
"type": "inject",
"z": "653c8c20.9f3d04",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "5",
"crontab": "",
"once": false,
"x": 130,
"y": 60,
"wires": [
[
"7fe49cc0.cae734"
]
]
},
{
"id": "712af5e6.f4fc3c",
"type": "catch",
"z": "653c8c20.9f3d04",
"name": "",
"scope": [
"44361e03.c5e5c"
],
"x": 420,
"y": 220,
"wires": [
[
"3305d5a9.d198aa"
]
]
},
{
"id": "310b2679.e70e1a",
"type": "amazon config",
"z": "",
"name": "AWS",
"region": "us-west-2"
},
{
"id": "d7e5365d.857a68",
"type": "ui_group",
"z": "",
"name": "Camera",
"tab": "f3f47ae8.947888",
"disp": true,
"width": "6"
},
{
"id": "f3f47ae8.947888",
"type": "ui_tab",
"z": "",
"name": "Security",
"icon": "dashboard",
"order": 3
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment