Cet article est un article pratique pour passer en revue et corriger les connaissances acquises en développant Serverless Web App Mosaic. C'est l'un des w2or3w / items / 87b57dfdbcf218de91e2).
Ce serait bien de lire cet article après avoir regardé ce qui suit.
S3 est bon si vous enregistrez simplement le fichier, mais il ne convient pas que les gens se réfèrent à ce fichier. Même s'il s'agit d'une image, elle ne peut pas être visualisée telle quelle sur un navigateur Web, et il est nécessaire de la télécharger une fois, puis de la visualiser. C'est un peu compliqué. À cet égard, Google Drive est agréable car vous pouvez parcourir les images bien avec un navigateur ou une application, que ce soit un PC ou un smartphone.
Accédez à la Developers Console de Google. https://console.developers.google.com
Si vous n'avez pas de projet, créez-en un.
Cliquez sur "+ Activer les API et les services" en haut de l'écran "API et services" de la console pour activer Google Drive.
Après avoir activé l'API Google Drive, créez les informations d'identification à partir de "Informations d'identification" dans le volet gauche de l'écran "API et services" de la console. Sélectionnez «Compte de service» dans le menu déroulant qui apparaît lorsque vous appuyez sur «+ Créer des informations d'identification» en haut de la page Informations d'identification.
Veuillez saisir le nom du compte de service pour le créer. L'identifiant du compte de service sous le nom du compte de service est une information importante, veuillez donc le gérer afin qu'il ne soit pas divulgué.
Après avoir créé le compte de service, parcourez les détails du compte de service créé à partir de «Compte de service» dans le volet gauche de l'écran «IAM et administration» de la console.
Dans les détails du compte de service, cliquez sur les boutons "Modifier" et "Créer + Clé" pour créer la clé privée au format JSON et télécharger le fichier JSON.
Créez un dossier pour télécharger des fichiers sur Google Drive. Ici, le nom du dossier est «sample-drive». Partagez ensuite ce dossier avec le compte de service (adresse e-mail) que vous avez créé précédemment.
La chaîne après l'URL de ce dossier sera utilisée plus tard dans le programme. (Partie cachée de la capture ci-dessous)
Eh bien, cela complète les paramètres du côté Google. Ensuite, importons le fichier par programmation avec l'API Google.
Tout d'abord, renommez le fichier JSON de clé privée du compte de service que vous avez téléchargé précédemment sous un nom approprié et placez-le au même emplacement que lambda_function.py. Je l'ai nommé "service-account-key.json" ici.
Ensuite, installez les bibliothèques requises.
$ pip install google-api-python-client -t .
$ pip install oauth2client -t .
Importez ensuite ce dont vous avez besoin.
lambda_function.py
:
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from oauth2client.service_account import ServiceAccountCredentials
:
Ensuite, téléchargez le fichier avec l'implémentation suivante.
lambda_function.py
:
def uploadFileToGoogleDrive(fileName, localFilePath):
try:
ext = os.path.splitext(localFilePath.lower())[1][1:]
if ext == "jpg":
ext = "jpeg"
mimeType = "image/" + ext
service = getGoogleService()
file_metadata = {"name": fileName, "mimeType": mimeType, "parents": ["*********************************"] }
media = MediaFileUpload(localFilePath, mimetype=mimeType, resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
except Exception as e:
logger.exception(e)
def getGoogleService():
scope = ['https://www.googleapis.com/auth/drive.file']
keyFile = 'service-account-key.json'
credentials = ServiceAccountCredentials.from_json_keyfile_name(keyFile, scopes=scope)
return build("drive", "v3", credentials=credentials, cache_discovery=False)
"parents": ["*********************************"] Cette partie est un dossier créé dans Google Drive Remplacez-le par la chaîne après l'URL dans.
Enfin, juste au cas où, je posterai l'intégralité du programme.
lambda_function.py
# coding: UTF-8
import boto3
import os
import json
from urllib.parse import unquote_plus
import numpy as np
import cv2
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.client("s3")
rekognition = boto3.client('rekognition')
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
ENDPOINT = "https://**************************.appsync-api.ap-northeast-1.amazonaws.com/graphql"
API_KEY = "da2-**************************"
_headers = {
"Content-Type": "application/graphql",
"x-api-key": API_KEY,
}
_transport = RequestsHTTPTransport(
headers = _headers,
url = ENDPOINT,
use_json = True,
)
_client = Client(
transport = _transport,
fetch_schema_from_transport = True,
)
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from oauth2client.service_account import ServiceAccountCredentials
def lambda_handler(event, context):
bucket = event["Records"][0]["s3"]["bucket"]["name"]
key = unquote_plus(event["Records"][0]["s3"]["object"]["key"], encoding="utf-8")
logger.info("Function Start (deploy from S3) : Bucket={0}, Key={1}" .format(bucket, key))
fileName = os.path.basename(key)
dirPath = os.path.dirname(key)
dirName = os.path.basename(dirPath)
orgFilePath = "/tmp/" + fileName
if (not key.startswith("public") or key.startswith("public/processed/")):
logger.info("don't process.")
return
apiCreateTable(dirName, key)
keyOut = key.replace("public", "public/processed", 1)
dirPathOut = os.path.dirname(keyOut)
try:
s3.download_file(Bucket=bucket, Key=key, Filename=orgFilePath)
orgImage = cv2.imread(orgFilePath)
grayImage = cv2.cvtColor(orgImage, cv2.COLOR_RGB2GRAY)
processedFileName = "gray-" + fileName
processedFilePath = "/tmp/" + processedFileName
uploadImage(grayImage, processedFilePath, bucket, os.path.join(dirPathOut, processedFileName), dirName, False)
uploadFileToGoogleDrive(key, orgFilePath)
detectFaces(bucket, key, fileName, orgImage, dirName, dirPathOut)
except Exception as e:
logger.exception(e)
raise e
finally:
if os.path.exists(orgFilePath):
os.remove(orgFilePath)
def uploadImage(image, localFilePath, bucket, s3Key, group, isUploadGoogleDrive):
logger.info("start uploadImage({0}, {1}, {2}, {3})".format(localFilePath, bucket, s3Key, group))
try:
cv2.imwrite(localFilePath, image)
s3.upload_file(Filename=localFilePath, Bucket=bucket, Key=s3Key)
apiCreateTable(group, s3Key)
if isUploadGoogleDrive:
uploadFileToGoogleDrive(s3Key, localFilePath)
except Exception as e:
logger.exception(e)
raise e
finally:
if os.path.exists(localFilePath):
os.remove(localFilePath)
def apiCreateTable(group, path):
logger.info("start apiCreateTable({0}, {1})".format(group, path))
try:
query = gql("""
mutation create {{
createSampleAppsyncTable(input:{{
group: \"{0}\"
path: \"{1}\"
}}){{
group path
}}
}}
""".format(group, path))
_client.execute(query)
except Exception as e:
logger.exception(e)
raise e
def detectFaces(bucket, key, fileName, image, group, dirPathOut):
logger.info("start detectFaces ({0}, {1}, {2}, {3}, {4})".format(bucket, key, fileName, group, dirPathOut))
try:
response = rekognition.detect_faces(
Image={
"S3Object": {
"Bucket": bucket,
"Name": key,
}
},
Attributes=[
"ALL",
]
)
name, ext = os.path.splitext(fileName)
jsonFileName = name + ".json"
localPathJSON = "/tmp/" + jsonFileName
with open(localPathJSON, 'w') as f:
json.dump(response, f, ensure_ascii=False)
s3.upload_file(Filename=localPathJSON, Bucket=bucket, Key=os.path.join(dirPathOut, jsonFileName))
if os.path.exists(localPathJSON):
os.remove(localPathJSON)
imgHeight = image.shape[0]
imgWidth = image.shape[1]
index = 0
for faceDetail in response["FaceDetails"]:
index += 1
faceFileName = "face_{0:03d}".format(index) + ext
box = faceDetail["BoundingBox"]
x = max(int(imgWidth * box["Left"]), 0)
y = max(int(imgHeight * box["Top"]), 0)
w = int(imgWidth * box["Width"])
h = int(imgHeight * box["Height"])
logger.info("BoundingBox({0},{1},{2},{3})".format(x, y, w, h))
faceImage = image[y:min(y+h, imgHeight-1), x:min(x+w, imgWidth)]
localFaceFilePath = os.path.join("/tmp/", faceFileName)
uploadImage(faceImage, localFaceFilePath, bucket, os.path.join(dirPathOut, faceFileName), group, False)
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 3)
processedFileName = "faces-" + fileName
processedFilePath = "/tmp/" + processedFileName
uploadImage(image, processedFilePath, bucket, os.path.join(dirPathOut, processedFileName), group, True)
except Exception as e:
logger.exception(e)
raise e
def uploadFileToGoogleDrive(fileName, localFilePath):
try:
ext = os.path.splitext(localFilePath.lower())[1][1:]
if ext == "jpg":
ext = "jpeg"
mimeType = "image/" + ext
service = getGoogleService()
file_metadata = {"name": fileName, "mimeType": mimeType, "parents": ["*********************************"] }
media = MediaFileUpload(localFilePath, mimetype=mimeType, resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
except Exception as e:
logger.exception(e)
def getGoogleService():
scope = ['https://www.googleapis.com/auth/drive.file']
keyFile = 'service-account-key.json'
credentials = ServiceAccountCredentials.from_json_keyfile_name(keyFile, scopes=scope)
return build("drive", "v3", credentials=credentials, cache_discovery=False)
Lorsque vous téléchargez une image à partir d'une application Web, Python de Lambda s'exécute pour traiter l'image, puis vous téléchargez également l'image d'origine et l'image avec le retour sur investissement marqué sur le visage vers Google Drive. Contrairement à S3, je suis heureux de le voir comme une image.
Je voudrais également parler du service cloud de Google. J'aime Google. C'est l'un des objectifs pour 2020.
En passant, il y a de nombreux produits Google autour de moi, tels que le Pixel 3a, le Chromebook, le Google Home Mini, le Chromecast et le Google Wifi. En ce qui concerne le service, j'utilise quotidiennement Google Fit avec Mi Band ainsi que Gmail, Agenda, Drive, Photo, etc., et j'aime publier Google Map dans un style de guide local. Google One a également été mis à niveau à 2 To (13 000 ¥ par an).
OK Google, je t'aime!
Recommended Posts