Dieser Artikel ist ein praktischer Artikel zum Überprüfen und Korrigieren der durch die Entwicklung von Serverless Web App Mosaic gewonnenen Erkenntnisse. Es ist eines von w2or3w / items / 87b57dfdbcf218de91e2).
Es wäre schön, diesen Artikel zu lesen, nachdem man sich Folgendes angesehen hat.
S3 ist gut, wenn Sie nur die Datei speichern, aber es ist nicht geeignet, dass Personen auf diese Datei verweisen. Selbst wenn es sich um ein Bild handelt, kann es nicht wie in einem Webbrowser angezeigt werden. Es muss einmal heruntergeladen und anschließend angezeigt werden. Es ist ein bisschen mühsam. In dieser Hinsicht ist Google Drive nett, da Sie Bilder mit einem Browser oder einer Anwendung gut durchsuchen können, egal ob es sich um einen PC oder ein Smartphone handelt.
Gehen Sie zur Entwicklerkonsole von Google. https://console.developers.google.com
Wenn Sie kein Projekt haben, erstellen Sie eines.
Klicken Sie oben im Bildschirm "APIs und Dienste" in der Konsole auf "+ APIs und Dienste aktivieren", um Google Drive zu aktivieren.
Erstellen Sie nach dem Aktivieren der Google Drive-API die Anmeldeinformationen unter "Anmeldeinformationen" im linken Bereich des Bildschirms "APIs und Dienste" der Konsole. Wählen Sie "Dienstkonto" aus dem Dropdown-Menü, das angezeigt wird, wenn Sie oben auf der Seite "Anmeldeinformationen" auf "+ Anmeldeinformationen erstellen" klicken.
Bitte geben Sie den Namen des Dienstkontos ein, um ihn zu erstellen. Die Dienstkonto-ID unter dem Namen des Dienstkontos ist eine wichtige Information. Verwalten Sie sie daher so, dass sie nicht durchgesickert ist.
Durchsuchen Sie nach dem Erstellen des Dienstkontos die Details des erstellten Dienstkontos unter "Dienstkonto" im linken Bereich des Bildschirms "IAM und Administration" der Konsole.
Klicken Sie in den Dienstkontodetails auf die Schaltflächen "Bearbeiten" und "Erstellen + Schlüssel", um den privaten Schlüssel im JSON-Format zu erstellen und die JSON-Datei herunterzuladen.
Erstellen Sie einen Ordner zum Hochladen von Dateien auf Google Drive. Hier lautet der Ordnername "sample-drive". Geben Sie dann diesen Ordner für das zuvor erstellte Dienstkonto (E-Mail-Adresse) frei.
Die Zeichenfolge nach der URL dieses Ordners wird später im Programm verwendet. (Versteckter Teil der Aufnahme unten)
Damit sind die Einstellungen auf der Google-Seite abgeschlossen. Laden Sie als Nächstes die Datei programmgesteuert mit der Google-API hoch.
Benennen Sie zunächst die JSON-Datei mit privatem Schlüssel des zuvor heruntergeladenen Dienstkontos in einen geeigneten Namen um und platzieren Sie sie am selben Speicherort wie lambda_function.py. Ich habe es hier "service-account-key.json" genannt.
Installieren Sie dann die erforderlichen Bibliotheken.
$ pip install google-api-python-client -t .
$ pip install oauth2client -t .
Importieren Sie dann das, was Sie benötigen.
lambda_function.py
:
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from oauth2client.service_account import ServiceAccountCredentials
:
Laden Sie dann die Datei mit der folgenden Implementierung hoch.
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)
"Eltern": ["*************************************"] Dieser Teil ist ein Ordner, der in Google Drive erstellt wurde Ersetzen Sie es durch die Zeichenfolge nach der URL in.
Zum Schluss werde ich für alle Fälle das gesamte Programm veröffentlichen.
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)
Wenn Sie ein Bild von einer Web-App hochladen, wird Lambdas Python ausgeführt, um das Bild zu verarbeiten. Anschließend laden Sie das Originalbild und das Bild mit dem auf der Vorderseite markierten ROI auf Google Drive hoch. Im Gegensatz zu S3 sehe ich es gerne als Bild.
Ich möchte auch den Cloud-Service von Google berühren. Ich mag Google. Dies ist eines der Ziele für 2020.
Übrigens gibt es viele Google-Produkte um mich herum, wie Pixel 3a, Chromebook, Google Home Mini, Chromecast und Google Wifi. Für den Dienst verwende ich täglich Google Fit mit Mi Band sowie Google Mail, Kalender, Laufwerk, Foto usw. und poste Google Map gerne in einem lokalen Leitfaden. Google One wurde ebenfalls auf 2 TB (13.000 Yen pro Jahr) aktualisiert.
OK Google, ich liebe dich!
Recommended Posts