เกี่ยวกับ Codelab นี้
1 ภาพรวม
ใน Code Lab ครั้งแรก คุณจะต้องอัปโหลดภาพในที่เก็บข้อมูล การดำเนินการนี้จะสร้างเหตุการณ์การสร้างไฟล์ที่ฟังก์ชันจะจัดการ ฟังก์ชันดังกล่าวจะเรียกใช้ Vision API เพื่อทำการวิเคราะห์รูปภาพและบันทึกผลลัพธ์ลงในพื้นที่เก็บข้อมูล
สิ่งที่คุณจะได้เรียนรู้
- Cloud Storage
- Cloud Functions
- Cloud Vision API
- Cloud Firestore
2 การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก
- ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ปกติแล้วคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น
PROJECT_ID
) หากคุณไม่ชอบรหัสที่สร้างขึ้น คุณสามารถสร้างรหัสแบบสุ่มอื่นได้ หรือคุณจะลองดำเนินการเองแล้วดูว่าพร้อมให้บริการหรือไม่ และไม่สามารถเปลี่ยนแปลงได้หลังจากขั้นตอนนี้และจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - สำหรับข้อมูลของคุณ ค่าที่ 3 คือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าเหล่านี้ในเอกสารประกอบ
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่คุณสร้างหรือลบทั้งโปรเจ็กต์ได้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD
เริ่มต้น Cloud Shell
แม้ว่าคุณจะดำเนินการ Google Cloud จากระยะไกลได้จากแล็ปท็อป แต่คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์ใน Codelab นี้
จากคอนโซล Google Cloud ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน ดังนี้
การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมนี้ควรใช้เวลาเพียงครู่เดียว เมื่อเสร็จแล้ว คุณจะเห็นข้อมูลต่อไปนี้
เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ใช้งานได้ต่อเนื่องและทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานทั้งหมดใน Codelab นี้ทำได้ในเบราว์เซอร์ คุณไม่จำเป็นต้องติดตั้งอะไร
3 เปิดใช้ API
สำหรับห้องทดลองนี้ คุณจะใช้ Cloud Functions และ Vision API แต่ต้องเปิดใช้ใน Cloud Console หรือด้วย gcloud
ก่อน
หากต้องการเปิดใช้ Vision API ใน Cloud Console ให้ค้นหา Cloud Vision API
ในแถบค้นหา
คุณจะเข้าสู่หน้า Cloud Vision API:
คลิกปุ่ม ENABLE
หรือคุณจะเปิดใช้ Cloud Shell โดยใช้เครื่องมือบรรทัดคำสั่ง gcloud ก็ได้
เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud services enable vision.googleapis.com
คุณควรเห็นการดำเนินการที่เสร็จสิ้นเรียบร้อยแล้ว
Operation "operations/acf.12dba18b-106f-4fd2-942d-fea80ecc5c1c" finished successfully.
เปิดใช้ Cloud Functions ด้วยโดยทำดังนี้
gcloud services enable cloudfunctions.googleapis.com
4 สร้างที่เก็บข้อมูล (คอนโซล)
สร้างที่เก็บข้อมูลของพื้นที่เก็บข้อมูลสำหรับรูปภาพ โดยทำได้จากคอนโซล Google Cloud Platform ( console.cloud.google.com) หรือด้วยเครื่องมือบรรทัดคำสั่ง gsutil จาก Cloud Shell หรือสภาพแวดล้อมการพัฒนาในเครื่อง
ไปที่พื้นที่เก็บข้อมูล
จาก "แฮมเบอร์เกอร์" (⋮) ให้ไปที่หน้าStorage
ตั้งชื่อที่เก็บข้อมูล
คลิกปุ่ม CREATE BUCKET
คลิก CONTINUE
เลือกตำแหน่ง
สร้างที่เก็บข้อมูลหลายภูมิภาคในภูมิภาคที่คุณเลือก (ที่นี่ Europe
)
คลิก CONTINUE
เลือกคลาสพื้นที่เก็บข้อมูลเริ่มต้น
เลือกคลาสพื้นที่เก็บข้อมูล Standard
สำหรับข้อมูลของคุณ
คลิก CONTINUE
ตั้งค่าการควบคุมการเข้าถึง
เนื่องจากคุณจะต้องใช้งานรูปภาพที่เข้าถึงได้แบบสาธารณะ คุณต้องการให้รูปภาพทั้งหมดที่จัดเก็บในที่เก็บข้อมูลนี้มีการควบคุมการเข้าถึงแบบเดียวกัน
เลือกตัวเลือกการควบคุมการเข้าถึง Uniform
คลิก CONTINUE
ตั้งค่าการป้องกัน/การเข้ารหัส
เก็บค่าเริ่มต้นไว้ (Google-managed key)
เนื่องจากคุณจะไม่ใช้คีย์การเข้ารหัสของคุณเอง
คลิก CREATE
เพื่อสร้างที่เก็บข้อมูลขั้นสุดท้าย
เพิ่ม allUsers เป็นผู้ดูพื้นที่เก็บข้อมูล
ไปที่แท็บ Permissions
:
เพิ่มสมาชิก allUsers
ไปยังที่เก็บข้อมูล โดยมีบทบาทเป็น Storage > Storage Object Viewer
ดังนี้
คลิก SAVE
5 สร้างที่เก็บข้อมูล (gsutil)
คุณยังใช้เครื่องมือบรรทัดคำสั่ง gsutil
ใน Cloud Shell เพื่อสร้างที่เก็บข้อมูลได้ด้วย
ใน Cloud Shell ให้ตั้งตัวแปรสำหรับชื่อที่เก็บข้อมูลที่ไม่ซ้ำกัน Cloud Shell มี GOOGLE_CLOUD_PROJECT
ที่ตั้งค่าเป็นรหัสโปรเจ็กต์ที่ไม่ซ้ำกันอยู่แล้ว คุณจะเพิ่มค่านั้นต่อท้ายชื่อที่เก็บข้อมูลได้
เช่น
export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
สร้างโซนหลายภูมิภาคตามมาตรฐานในยุโรป
gsutil mb -l EU gs://${BUCKET_PICTURES}
ตรวจสอบว่าสิทธิ์เข้าถึงระดับที่เก็บข้อมูลแบบเดียวกัน
gsutil uniformbucketlevelaccess set on gs://${BUCKET_PICTURES}
ทำให้ที่เก็บข้อมูลเป็นแบบสาธารณะ โดยทำดังนี้
gsutil iam ch allUsers:objectViewer gs://${BUCKET_PICTURES}
หากไปที่ส่วน Cloud Storage
ของคอนโซล คุณควรมีที่เก็บข้อมูล uploaded-pictures
สาธารณะ
ทดสอบว่าคุณสามารถอัปโหลดรูปภาพไปยังที่เก็บข้อมูล และภาพที่อัปโหลดจะปรากฏต่อสาธารณะ ตามที่อธิบายไว้ในขั้นตอนก่อนหน้า
6 ทดสอบสิทธิ์เข้าถึงที่เก็บข้อมูลแบบสาธารณะ
การกลับไปยังเบราว์เซอร์พื้นที่เก็บข้อมูล คุณจะเห็นที่เก็บข้อมูลในรายการ โดยมี "สาธารณะ" (รวมถึงป้ายเตือนที่บอกว่าทุกคนมีสิทธิ์เข้าถึงเนื้อหาของที่เก็บข้อมูลนั้น)
ตอนนี้ที่เก็บข้อมูลของคุณพร้อมรับรูปภาพแล้ว
หากคลิกชื่อที่เก็บข้อมูล คุณจะเห็นรายละเอียดที่เก็บข้อมูล
จากจุดนี้ คุณสามารถลองใช้ปุ่ม Upload files
เพื่อทดสอบว่าคุณเพิ่มรูปภาพลงในที่เก็บข้อมูลได้ ป๊อปอัปตัวเลือกไฟล์จะขอให้คุณเลือกไฟล์ เมื่อเลือกแล้ว ระบบจะอัปโหลดไฟล์ดังกล่าวไปยังที่เก็บข้อมูลของคุณ และคุณจะเห็นสิทธิ์เข้าถึง public
ที่ระบบระบุแหล่งที่มาไปยังไฟล์ใหม่นี้โดยอัตโนมัติอีกครั้ง
คุณจะเห็นไอคอนลิงก์ขนาดเล็กที่ป้ายกำกับการเข้าถึง Public
ด้วย เมื่อคลิกที่รูปภาพ เบราว์เซอร์ของคุณจะนำทางไปยัง URL สาธารณะของรูปภาพนั้น ซึ่งจะอยู่ในรูปแบบ:
https://storage.googleapis.com/BUCKET_NAME/PICTURE_FILE.png
โดย BUCKET_NAME
เป็นชื่อที่ไม่ซ้ำกันทั่วโลกซึ่งคุณได้เลือกไว้สำหรับที่เก็บข้อมูล และตามด้วยชื่อไฟล์ของรูปภาพ
เมื่อคลิกช่องทำเครื่องหมายข้างชื่อภาพ ปุ่ม DELETE
จะเปิดการใช้งาน และคุณจะสามารถลบรูปภาพแรกนี้ได้
7 สร้างฟังก์ชัน
ในขั้นตอนนี้ คุณจะได้สร้างฟังก์ชันที่ตอบสนองต่อเหตุการณ์การอัปโหลดรูปภาพ
ไปที่ส่วนCloud Functions
ของคอนโซล Google Cloud การเข้าชมนี้จะเปิดใช้บริการ Cloud Functions โดยอัตโนมัติ
คลิกที่ Create function
เลือกชื่อ (เช่น picture-uploaded
) และภูมิภาค (โปรดทราบว่าต้องสอดคล้องกับตัวเลือกภูมิภาคสำหรับที่เก็บข้อมูล):
ฟังก์ชันมี 2 ประเภท ได้แก่
- ฟังก์ชัน HTTP ที่สามารถเรียกใช้ผ่าน URL (เช่น API ของเว็บ)
- ฟังก์ชันเบื้องหลังที่เหตุการณ์บางอย่างทริกเกอร์ได้
คุณต้องการสร้างฟังก์ชันพื้นหลังที่ทริกเกอร์เมื่อมีการอัปโหลดไฟล์ใหม่ไปยังที่เก็บข้อมูล Cloud Storage
ของเรา ดังนี้
คุณสนใจประเภทเหตุการณ์ Finalize/Create
ซึ่งเป็นเหตุการณ์ที่จะทริกเกอร์เมื่อมีการสร้างหรืออัปเดตไฟล์ในที่เก็บข้อมูล
เลือกที่เก็บข้อมูลที่สร้างขึ้นก่อนหน้านี้เพื่อแจ้งให้ Cloud Functions รับการแจ้งเตือนเมื่อมีการสร้าง / อัปเดตไฟล์ในที่เก็บข้อมูลเฉพาะนี้
คลิก Select
เพื่อเลือกที่เก็บข้อมูลที่คุณสร้างไว้ก่อนหน้านี้ จากนั้นคลิก Save
ก่อนคลิก "ถัดไป" คุณจะขยายและแก้ไขค่าเริ่มต้น (หน่วยความจำ 256 MB) ได้ในส่วนการตั้งค่ารันไทม์ บิลด์ การเชื่อมต่อ และความปลอดภัย แล้วอัปเดตเป็น 1 GB
หลังจากคลิก Next
คุณจะปรับแต่งรันไทม์ ซอร์สโค้ด และจุดเริ่มต้นได้
เก็บ Inline editor
ไว้สำหรับฟังก์ชันนี้:
เลือกรันไทม์ของ Node.js รายการใดรายการหนึ่งต่อไปนี้
ซอร์สโค้ดประกอบด้วยไฟล์ JavaScript index.js
และไฟล์ package.json
ที่มีข้อมูลเมตาและการอ้างอิงที่หลากหลาย
เก็บข้อมูลโค้ดเริ่มต้นไว้ซึ่งจะบันทึกชื่อไฟล์ของรูปภาพที่อัปโหลด
ในตอนนี้ โปรดเก็บชื่อของฟังก์ชันที่จะเรียกใช้ helloGCS
ไว้สำหรับการทดสอบ
คลิกที่ Deploy
เพื่อสร้างและทำให้ฟังก์ชันใช้งานได้ เมื่อการติดตั้งใช้งานเสร็จสมบูรณ์ คุณจะเห็นเครื่องหมายถูกวงกลมสีเขียวในรายการฟังก์ชัน
8 ทดสอบฟังก์ชัน
ในขั้นตอนนี้ ให้ทดสอบว่าฟังก์ชันตอบสนองต่อเหตุการณ์พื้นที่เก็บข้อมูลหรือไม่
จาก "แฮมเบอร์เกอร์" (⋮) ให้กลับไปที่หน้า Storage
คลิกที่ที่เก็บข้อมูลรูปภาพ จากนั้นคลิก Upload files
เพื่ออัปโหลดรูปภาพ
โปรดนำทางอีกครั้งภายใน Cloud Console เพื่อไปที่หน้า Logging > Logs Explorer
ในตัวเลือก Log Fields
ให้เลือก Cloud Function
เพื่อดูบันทึกสำหรับฟังก์ชันของคุณโดยเฉพาะ เลื่อนลงตามฟิลด์บันทึกและคุณสามารถเลือกฟังก์ชันที่ต้องการเพื่อดูบันทึกที่เกี่ยวข้องกับฟังก์ชันอย่างละเอียด เลือกฟังก์ชัน picture-uploaded
คุณจะเห็นรายการในบันทึกที่กล่าวถึงการสร้างฟังก์ชัน เวลาเริ่มต้นและสิ้นสุดของฟังก์ชัน และข้อความบันทึกจริงของเรา:
ข้อความบันทึกของเราคือ Processing file: pic-a-daily-architecture-events.png
ซึ่งหมายความว่ามีการทริกเกอร์เหตุการณ์ที่เกี่ยวข้องกับการสร้างและจัดเก็บรูปภาพนี้ตามที่คาดไว้แล้ว
9 เตรียมฐานข้อมูล
คุณจะจัดเก็บข้อมูลเกี่ยวกับรูปภาพที่ได้รับจาก Vision API ไว้ในฐานข้อมูล Cloud Firestore ซึ่งเป็นฐานข้อมูลเอกสาร NoSQL ที่ดำเนินการบนระบบคลาวด์และทำงานได้อย่างรวดเร็ว มีการจัดการครบวงจร เตรียมฐานข้อมูลด้วยการไปที่ส่วน Firestore
ของ Cloud Console:
โดยมี 2 ตัวเลือก ได้แก่ Native mode
หรือ Datastore mode
ใช้โหมดเนทีฟซึ่งมีฟีเจอร์เพิ่มเติม เช่น การรองรับการใช้งานออฟไลน์และการซิงค์ข้อมูลแบบเรียลไทม์
คลิก SELECT NATIVE MODE
เลือกหลายภูมิภาค (ที่นี่ในยุโรป แต่อย่างน้อยควรเป็นภูมิภาคเดียวกับฟังก์ชันและที่เก็บข้อมูลของพื้นที่เก็บข้อมูล)
คลิกปุ่ม CREATE DATABASE
เมื่อสร้างฐานข้อมูลแล้ว คุณจะเห็นสิ่งต่อไปนี้
สร้างคอลเล็กชันใหม่โดยคลิกปุ่ม + START COLLECTION
ชื่อคอลเล็กชัน pictures
คุณไม่ต้องสร้างเอกสาร คุณจะเพิ่มรูปภาพเหล่านั้นโดยใช้โปรแกรมเมื่อมีการจัดเก็บรูปภาพใหม่ใน Cloud Storage และวิเคราะห์โดย Vision API
คลิก Save
Firestore สร้างเอกสารเริ่มต้นรายการแรกในคอลเล็กชันที่สร้างขึ้นใหม่ คุณลบเอกสารดังกล่าวได้อย่างปลอดภัยเนื่องจากไม่มีข้อมูลที่เป็นประโยชน์ใดๆ ดังต่อไปนี้
เอกสารที่จะสร้างขึ้นแบบเป็นโปรแกรมในคอลเล็กชันของเราประกอบด้วย 4 ฟิลด์ ดังนี้
- name (สตริง): ชื่อไฟล์ของรูปภาพที่อัปโหลด ซึ่งเป็นคีย์ของเอกสาร
- labels (อาร์เรย์ของสตริง): ป้ายกำกับของรายการที่รู้จักโดย Vision API
- color (สตริง): รหัสสีเลขฐาน 16 ของสีหลัก (เช่น #ab12ef)
- สร้าง (วันที่): การประทับเวลาที่เก็บข้อมูลเมตาของรูปภาพนี้
- ภาพขนาดย่อ (บูลีน): ช่องที่ไม่บังคับซึ่งจะแสดงและเป็น "จริง" หากมีการสร้างภาพขนาดย่อสำหรับรูปภาพนี้
เนื่องจากเราจะค้นหาใน Firestore เพื่อค้นหารูปภาพที่มีภาพขนาดย่อ และจัดเรียงตามวันที่สร้าง เราจะต้องสร้างดัชนีการค้นหา
คุณสร้างดัชนีด้วยคำสั่งต่อไปนี้ใน Cloud Shell ได้
gcloud firestore indexes composite create \
--collection-group=pictures \
--field-config field-path=thumbnail,order=descending \
--field-config field-path=created,order=descending
หรือดำเนินการจาก Cloud Console โดยคลิก Indexes
ในคอลัมน์การนำทางด้านซ้าย แล้วสร้างดัชนีผสมดังที่แสดงด้านล่างก็ได้
คลิก Create
การสร้างดัชนีอาจใช้เวลาสักครู่
10 อัปเดตฟังก์ชัน
กลับไปที่หน้า Functions
เพื่ออัปเดตฟังก์ชันเพื่อเรียกใช้ Vision API เพื่อวิเคราะห์รูปภาพและจัดเก็บข้อมูลเมตาใน Firestore
จาก "แฮมเบอร์เกอร์" (⋮) ไปยังส่วน Cloud Functions
จากนั้นคลิกชื่อฟังก์ชัน จากนั้นเลือกแท็บ Source
แล้วคลิกปุ่ม EDIT
ก่อนอื่นให้แก้ไขไฟล์ package.json
ซึ่งแสดงรายการทรัพยากร Dependency ของฟังก์ชัน Node.JS อัปเดตโค้ดเพื่อเพิ่มทรัพยากร Dependency ของ NPM สำหรับ Cloud Vision API ดังนี้
{
"name": "picture-analysis-function",
"version": "0.0.1",
"dependencies": {
"@google-cloud/storage": "^1.6.0",
"@google-cloud/vision": "^1.8.0",
"@google-cloud/firestore": "^3.4.1"
}
}
ตอนนี้ทรัพยากร Dependency เป็นปัจจุบันแล้ว คุณจะทำงานกับโค้ดของฟังก์ชันได้โดยอัปเดตไฟล์ index.js
แทนที่รหัสใน index.js
ด้วยรหัสด้านล่าง ซึ่งจะอธิบายในขั้นตอนถัดไป
const vision = require('@google-cloud/vision');
const Storage = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const client = new vision.ImageAnnotatorClient();
exports.vision_analysis = async (event, context) => {
console.log(`Event: ${JSON.stringify(event)}`);
const filename = event.name;
const filebucket = event.bucket;
console.log(`New picture uploaded ${filename} in ${filebucket}`);
const request = {
image: { source: { imageUri: `gs://${filebucket}/${filename}` } },
features: [
{ type: 'LABEL_DETECTION' },
{ type: 'IMAGE_PROPERTIES' },
{ type: 'SAFE_SEARCH_DETECTION' }
]
};
// invoking the Vision API
const [response] = await client.annotateImage(request);
console.log(`Raw vision output for: ${filename}: ${JSON.stringify(response)}`);
if (response.error === null) {
// listing the labels found in the picture
const labels = response.labelAnnotations
.sort((ann1, ann2) => ann2.score - ann1.score)
.map(ann => ann.description)
console.log(`Labels: ${labels.join(', ')}`);
// retrieving the dominant color of the picture
const color = response.imagePropertiesAnnotation.dominantColors.colors
.sort((c1, c2) => c2.score - c1.score)[0].color;
const colorHex = decColorToHex(color.red, color.green, color.blue);
console.log(`Colors: ${colorHex}`);
// determining if the picture is safe to show
const safeSearch = response.safeSearchAnnotation;
const isSafe = ["adult", "spoof", "medical", "violence", "racy"].every(k =>
!['LIKELY', 'VERY_LIKELY'].includes(safeSearch[k]));
console.log(`Safe? ${isSafe}`);
// if the picture is safe to display, store it in Firestore
if (isSafe) {
const pictureStore = new Firestore().collection('pictures');
const doc = pictureStore.doc(filename);
await doc.set({
labels: labels,
color: colorHex,
created: Firestore.Timestamp.now()
}, {merge: true});
console.log("Stored metadata in Firestore");
}
} else {
throw new Error(`Vision API error: code ${response.error.code}, message: "${response.error.message}"`);
}
};
function decColorToHex(r, g, b) {
return '#' + Number(r).toString(16).padStart(2, '0') +
Number(g).toString(16).padStart(2, '0') +
Number(b).toString(16).padStart(2, '0');
}
11 สำรวจฟังก์ชัน
มาดูรายละเอียดเกี่ยวกับส่วนต่างๆ ที่น่าสนใจกัน
โดยก่อนอื่น เราจะต้องการโมดูลที่จำเป็นสำหรับ Vision, พื้นที่เก็บข้อมูล และ Firestore
const vision = require('@google-cloud/vision');
const Storage = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
จากนั้นเราจะเตรียมไคลเอ็นต์สำหรับ Vision API ดังนี้
const client = new vision.ImageAnnotatorClient();
ตอนนี้มาถึงโครงสร้างของฟังก์ชัน เราทำให้เป็นฟังก์ชันอะซิงโครนัส เนื่องจากเราใช้ความสามารถอะซิงโครนัส / รอคอย สิ่งที่เปิดตัวใน Node.js 8:
exports.vision_analysis = async (event, context) => {
...
const filename = event.name;
const filebucket = event.bucket;
...
}
โปรดสังเกตลายเซ็น รวมถึงวิธีที่เราเรียกชื่อไฟล์และที่เก็บข้อมูลซึ่งเรียกใช้ Cloud Function
สำหรับการอ้างอิง เปย์โหลดเหตุการณ์มีลักษณะดังนี้
{
"bucket":"uploaded-pictures",
"contentType":"image/png",
"crc32c":"efhgyA==",
"etag":"CKqB956MmucCEAE=",
"generation":"1579795336773802",
"id":"uploaded-pictures/Screenshot.png/1579795336773802",
"kind":"storage#object",
"md5Hash":"PN8Hukfrt6C7IyhZ8d3gfQ==",
"mediaLink":"https://www.googleapis.com/download/storage/v1/b/uploaded-pictures/o/Screenshot.png?generation=1579795336773802&alt=media",
"metageneration":"1",
"name":"Screenshot.png",
"selfLink":"https://www.googleapis.com/storage/v1/b/uploaded-pictures/o/Screenshot.png",
"size":"173557",
"storageClass":"STANDARD",
"timeCreated":"2020-01-23T16:02:16.773Z",
"timeStorageClassUpdated":"2020-01-23T16:02:16.773Z",
"updated":"2020-01-23T16:02:16.773Z"
}
เราเตรียมคำขอที่จะส่งผ่านไคลเอ็นต์ Vision ดังนี้
const request = {
image: { source: { imageUri: `gs://${filebucket}/${filename}` } },
features: [
{ type: 'LABEL_DETECTION' },
{ type: 'IMAGE_PROPERTIES' },
{ type: 'SAFE_SEARCH_DETECTION' }
]
};
เราขอแนะนำความสามารถหลัก 3 อย่างของ Vision API ดังนี้
- การตรวจจับป้ายกำกับ: เพื่อให้ทราบสิ่งที่อยู่ในรูปภาพเหล่านั้น
- คุณสมบัติของรูปภาพ: เพื่อแสดงแอตทริบิวต์ที่น่าสนใจของรูปภาพ (เราสนใจสีที่โดดเด่นของรูปภาพ)
- ค้นหาปลอดภัย: เพื่อดูว่ารูปภาพนั้นปลอดภัยหรือไม่ (ไม่ควรมีเนื้อหาสำหรับผู้ใหญ่ / การแพทย์ / สำหรับผู้ใหญ่ / ความรุนแรง)
ในตอนนี้ เราสามารถเรียกใช้ Vision API ได้โดยทำดังนี้
const [response] = await client.annotateImage(request);
สำหรับการอ้างอิง การตอบสนองจาก Vision API จะมีลักษณะดังนี้
{
"faceAnnotations": [],
"landmarkAnnotations": [],
"logoAnnotations": [],
"labelAnnotations": [
{
"locations": [],
"properties": [],
"mid": "/m/01yrx",
"locale": "",
"description": "Cat",
"score": 0.9959855675697327,
"confidence": 0,
"topicality": 0.9959855675697327,
"boundingPoly": null
},
✄ - - - ✄
],
"textAnnotations": [],
"localizedObjectAnnotations": [],
"safeSearchAnnotation": {
"adult": "VERY_UNLIKELY",
"spoof": "UNLIKELY",
"medical": "VERY_UNLIKELY",
"violence": "VERY_UNLIKELY",
"racy": "VERY_UNLIKELY",
"adultConfidence": 0,
"spoofConfidence": 0,
"medicalConfidence": 0,
"violenceConfidence": 0,
"racyConfidence": 0,
"nsfwConfidence": 0
},
"imagePropertiesAnnotation": {
"dominantColors": {
"colors": [
{
"color": {
"red": 203,
"green": 201,
"blue": 201,
"alpha": null
},
"score": 0.4175916016101837,
"pixelFraction": 0.44456374645233154
},
✄ - - - ✄
]
}
},
"error": null,
"cropHintsAnnotation": {
"cropHints": [
{
"boundingPoly": {
"vertices": [
{ "x": 0, "y": 118 },
{ "x": 1177, "y": 118 },
{ "x": 1177, "y": 783 },
{ "x": 0, "y": 783 }
],
"normalizedVertices": []
},
"confidence": 0.41695669293403625,
"importanceFraction": 1
}
]
},
"fullTextAnnotation": null,
"webDetection": null,
"productSearchResults": null,
"context": null
}
ถ้าไม่มีการส่งคืนข้อผิดพลาด เราสามารถดำเนินการต่อได้ ด้วยเหตุนี้เราจึงมีข้อผิดพลาดนี้หากบล็อก:
if (response.error === null) {
...
} else {
throw new Error(`Vision API error: code ${response.error.code},
message: "${response.error.message}"`);
}
เราจะทำป้ายกำกับของสิ่งต่างๆ หมวดหมู่ หรือธีมที่จำได้ในภาพ
const labels = response.labelAnnotations
.sort((ann1, ann2) => ann2.score - ann1.score)
.map(ann => ann.description)
เราจะจัดเรียงป้ายกำกับตามคะแนนสูงสุดก่อน
เราอยากทราบสีที่โดดเด่นของรูปภาพ
const color = response.imagePropertiesAnnotation.dominantColors.colors
.sort((c1, c2) => c2.score - c1.score)[0].color;
const colorHex = decColorToHex(color.red, color.green, color.blue);
เราจะมาจัดเรียงสีตามคะแนนอีกครั้ง และเป็นอันแรก
นอกจากนี้เรายังใช้ฟังก์ชันยูทิลิตีเพื่อแปลงค่าสีแดง / เขียว / น้ำเงินเป็นรหัสสีเลขฐาน 16 ที่เราใช้ในสไตล์ชีต CSS ได้
ลองดูว่าภาพนั้นปลอดภัยไหม:
const safeSearch = response.safeSearchAnnotation;
const isSafe = ["adult", "spoof", "medical", "violence", "racy"]
.every(k => !['LIKELY', 'VERY_LIKELY'].includes(safeSearch[k]));
เรากำลังตรวจสอบแอตทริบิวต์สำหรับผู้ใหญ่ / การปลอมแปลง / การแพทย์ / ความรุนแรง / สำหรับผู้ใหญ่เพื่อดูว่ามีลักษณะมีแนวโน้มหรือมีแนวโน้มมากหรือไม่
หากผลของฟีเจอร์ค้นหาปลอดภัยถูกต้อง เราสามารถจัดเก็บข้อมูลเมตาใน Firestore ได้ ดังนี้
if (isSafe) {
const pictureStore = new Firestore().collection('pictures');
const doc = pictureStore.doc(filename);
await doc.set({
labels: labels,
color: colorHex,
created: Firestore.Timestamp.now()
}, {merge: true});
}
12 ทำให้ฟังก์ชันใช้งานได้
ได้เวลาทำให้ฟังก์ชันใช้งานได้แล้ว
กด DEPLOY
และเวอร์ชันใหม่จะถูกทำให้ใช้งานได้ โดยคุณจะเห็นความคืบหน้า:
13 ทดสอบฟังก์ชันอีกครั้ง
เมื่อทำให้ฟังก์ชันใช้งานได้เรียบร้อยแล้ว คุณจะโพสต์รูปภาพไปยัง Cloud Storage ดูว่าฟังก์ชันของเราเรียกใช้หรือไม่ Vision API แสดงผลหรือไม่ และข้อมูลที่เก็บข้อมูลเมตาอยู่ใน Firestore หรือไม่
กลับไปที่ Cloud Storage
แล้วคลิกที่เก็บข้อมูลที่เราสร้างไว้เมื่อเริ่มต้นห้องทดลอง
เมื่ออยู่ในหน้ารายละเอียดที่เก็บข้อมูล ให้คลิกปุ่ม Upload files
เพื่ออัปโหลดรูปภาพ
จาก "แฮมเบอร์เกอร์" (⋮) เพื่อไปที่การสำรวจ Logging > Logs
ในตัวเลือก Log Fields
ให้เลือก Cloud Function
เพื่อดูบันทึกสำหรับฟังก์ชันของคุณโดยเฉพาะ เลื่อนลงตามฟิลด์บันทึกและคุณสามารถเลือกฟังก์ชันที่ต้องการเพื่อดูบันทึกที่เกี่ยวข้องกับฟังก์ชันอย่างละเอียด เลือกฟังก์ชัน picture-uploaded
อันที่จริง ในรายการบันทึก เราจะเห็นว่ามีการเรียกใช้ฟังก์ชันของเรา ดังนี้
บันทึกจะระบุจุดเริ่มต้นและสิ้นสุดของการดำเนินการของฟังก์ชัน และระหว่างนั้น เราจะเห็นบันทึกที่เราใส่ไว้ในฟังก์ชันโดยใช้คำสั่งconsole.log() เราพบว่า
- รายละเอียดของเหตุการณ์ที่ทริกเกอร์ฟังก์ชันของเรา
- ผลลัพธ์ดิบจากการเรียก Vision API
- ป้ายกำกับที่พบในภาพที่เราอัปโหลด
- ข้อมูลสีที่โดดเด่น
- รูปภาพปลอดภัยที่จะแสดงหรือไม่
- และท้ายที่สุดแล้วระบบได้จัดเก็บข้อมูลเมตาเกี่ยวกับรูปภาพไว้ใน Firestore
อีกครั้งจาก "แฮมเบอร์เกอร์" (src) ไปที่ส่วน Firestore
ในส่วนย่อย Data
(แสดงโดยค่าเริ่มต้น) คุณจะเห็นคอลเล็กชัน pictures
ที่มีเอกสารใหม่เพิ่มเข้ามา ซึ่งจะสอดคล้องกับภาพที่คุณเพิ่งอัปโหลด
14 ล้างข้อมูล (ไม่บังคับ)
หากไม่ต้องการใช้ห้องทดลองอื่นๆ ในชุดนี้ต่อ คุณสามารถล้างทรัพยากรเพื่อประหยัดต้นทุนและเป็นพลเมืองระบบคลาวด์ที่ดีโดยรวม คุณสามารถล้างทรัพยากรแต่ละรายการได้ดังนี้
ลบที่เก็บข้อมูล
gsutil rb gs://${BUCKET_PICTURES}
ลบฟังก์ชัน
gcloud functions delete picture-uploaded --region europe-west1 -q
ลบคอลเล็กชัน Firestore โดยเลือก "ลบคอลเล็กชัน" ออกจากคอลเล็กชัน ดังนี้
หรือจะลบทั้งโปรเจ็กต์ก็ได้ โดยทำดังนี้
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
15 ยินดีด้วย
ยินดีด้วย คุณใช้งานบริการจัดการคีย์แรกของโปรเจ็กต์เรียบร้อยแล้ว
หัวข้อที่ครอบคลุม
- Cloud Storage
- Cloud Functions
- Cloud Vision API
- Cloud Firestore