Analyze Images with the Cloud Vision API

๋ชฉ๋ก
- APIs Explorer: Qwik Start
- Extract, Analyze, and Translate Text from Images with the Cloud ML APIs โฌ ๏ธ ์ค๋ ํ์ตํ Lab!
- Detect Labels, Faces, and Landmarks in images with the Cloud Vision API
- Analyze Images with the Cloud Vision API: Challenge Lab
- Claim credential (๋ชจ๋ ๊ฐ์๋ฅผ ์๋ฃํด์ผ Skill badge ์ทจ๋ ๊ฐ๋ฅ!โจ)
Cloud Vision API์ ํ
์คํธ ๊ฐ์ง ๋ฉ์๋๋ก ๊ดํ ๋ฌธ์ ์ธ์(OCR)์ ํ์ฉํด ์ด๋ฏธ์ง์์ ํ
์คํธ๋ฅผ ์ถ์ถํ๋ ๊ฒ์์ ์ถ๋ฐํ์ฌ ์ด ํ
์คํธ๋ฅผ Translation API๋ก ๋ฒ์ญํ๊ณ Natural Language API๋ก ๋ถ์ํ๊ธฐ
Shell ๋ฒํผ ํด๋ฆญ ํ ํ์ฑํ ์งํ

Your Cloud Platform project in the session is set to "PROJECT_ID"๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ๋ณด์ด๋ฉด ์ฑ๊ณต!
โก๏ธ PROJECT_ID: ์๋์ผ๋ก ์ค์ ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ง๋ค ์์ด

+ Create credenntials > API key
Cloud Translation API, Cloud Vision API, Natural Language API) ์ ํ ํ API key ๋ณต์ฌ

export API_KEY=<YOUR_API_KEY>
โก๏ธ echo API_KEY ๋ฅผ ํตํด์ ์ ๋๋ก ์ธํ
๋์๋์ง ํ์ธ ๊ฐ๋ฅ
โก๏ธ ๋ค๋น๊ฒ์ด์
๋ฐ > Cloud Storage > Create Bucket > Bucket ์์ฑ ํ ์ด๋ฏธ์ง ์
๋ก๋ (์์ธ ๋ฐฉ๋ฒ์ ์ด์ ํฌ์คํธ ์ฐธ๊ณ )

์ฐธ๊ณ ์ด๋ฏธ์ง

โก๏ธ ์ด๋ฏธ์ง ์ค์ > Add Entry > Public / allUsers / Reader ๊ถํ ๋ถ์ฌ
(์์ธ ๋ฐฉ๋ฒ์ ์ด์ ํฌ์คํธ ์ฐธ๊ณ )
โก๏ธ ocr-request.json ํ์ผ ์์ฑ

{
"requests": [
{
"image": {
"source": {
"gcsImageUri": "gs://my-bucket-name/sign.jpg"
}
},
"features": [
{
"type": "TEXT_DETECTION",
"maxResults": 10
}
]
}
]
}
์ฐธ๊ณ
ํ์ผ ์์ฑ ๋ฐฉ๋ฒ์
nano,vim,emacs๋ฑ ์ ํธํ๋ Command line editor๋ฅผ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ๋ค.
curl์ ์ฌ์ฉํ์ฌ Cloud Vision API๋ฅผ ํธ์ถํ๋ค.curl -s -X POST -H "Content-Type: application/json" --data-binary @ocr-request.json https://vision.googleapis.com/v1/images:annotate?key=${API_KEY}

Response ๊ฐ ๋ถ์
textAnnotations์์ ๋ฐํ๋๋ ์ฒซ ๋ฒ์งธ ๋ฐ์ดํฐ๋ API๊ฐ ์ด๋ฏธ์ง์์ ์ฐพ์ ์ ์ฒด ํ ์คํธ ๋ธ๋ก์ด๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋ค์ด ํฌํจ๋๋ค.
- ์ธ์ด์ฝ๋(the language code)
- ํ ์คํธ ๋ฌธ์์ด(a string of the text)
- ์ด๋ฏธ์ง์์ ํ ์คํธ๊ฐ ๋ฐ๊ฒฌ๋ ์์น๋ฅผ ๋ํ๋ด๋ ๊ฒฝ๊ณ ์์(a bounding box indicating where the text was found in the image)
โก๏ธ ocr-request.json ํ์ผ์ ์ ์ฅ๋๋ค.
curl -s -X POST -H "Content-Type: application/json" --data-binary @ocr-request.json https://vision.googleapis.com/v1/images:annotate?key=${API_KEY} -o ocr-response.json
translation-request.json ํ์ผ ์์ฑ
{
"q": "your_text_here", //์ถํ ๋ฒ์ญํ ๋ฌธ์์ด์ด ์ ์ฅ๋จ
"target": "en" //๋ฒ์ญํ ์ธ์ด ์ฝ๋
}
์ฐธ๊ณ
์ธ์ด ์ง์์ ํตํด Translation API๋ก ๋ฒ์ญ ๊ฐ๋ฅํ ์ธ์ด๋ค๊ณผ ํด๋นํ๋ ์ฝ๋๋ฅผ ์ ์ ์๋ค.
ocr-response.json ํ์ผ์์ ํ
์คํธ๋ฅผ ์ถ์ถํด ๊ฐ๊ณตํ ๋ค, ๊ทธ ๋ด์ฉ์ translation-request.json ํ์ผ์ ํน์ ์์น(=q์ value)์ ์๋์ผ๋ก ์ฝ์
ํ๋ค.STR=$(jq .responses[0].textAnnotations[0].description ocr-response.json) && STR="${STR//\"}" && sed -i "s|your_text_here|$STR|g" translation-request.json
์ฃผ์๐ฅ
์์ฒ๋ผ error๊ฐ ๋ฐ์ํ๋ค๋ฉด, ์ฒ์์ ์์ฑํ API๊ฐCloud Vision API๋Cloud Translation API,Natural Language API์ ๋ํ ๊ถํ์ด ์๋ ๊ฒ์ด๋ฏ๋ก ๋ค๋น๊ฒ์ด์ ๋ฉ๋ด > APIs & Servies ์์ ๋ด๊ฐ ์ฒ์์ ์์ฑํ API Key๋ฅผ ์ ํ ํ, API ๊ถํ์ ์ถ๊ฐํด์ผ ํ๋ค.
translation-response.json ํ์ผ์ ์ ์ฅํ๋ค.
curl -s -X POST -H "Content-Type: application/json" --data-binary @translation-request.json https://translation.googleapis.com/language/translate/v2?key=${API_KEY} -o translation-response.json
์ฐธ๊ณ
Google Cloud Natural Language API๋ ์ปดํจํฐ๊ฐ ์ธ๊ฐ์ ์ธ์ด(์์ฐ์ด)๋ฅผ ์ดํดํ๊ณ ๋ถ์ํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ์ด๋ค. ๋จ์ํ ํ ์คํธ๋ฅผ ์ฝ๋ ๊ฒ์ ๋์ด, ๊ทธ ์์ ๋ด๊ธด ์๋, ๊ฐ์ , ๊ตฌ์กฐ๋ฅผ ํ์ ํ๋ ๋ฐ ํนํ๋์ด ์๋ค.
nl-request.json ํ์ผ ์์ฑ{
"document":{
"type":"PLAIN_TEXT",
"content":"your_text_here"
},
"encodingType":"UTF8"
}
ํญ๋ชฉ ๋ถ์
- type: ์ง์๋๋ ์ ํ(
PLAIN_TEXT,HTML)- content: Natural Language API์ ์ ์กํ์ฌ ๋ถ์ํ๋ ค๋ ํ ์คํธ๋ฅผ ์ ๋ฌ
- Cloud Storage์์ ํ์ผ์ ์ ์กํ๋ ค๋ฉด,
content๋ฅผgcsContentUri๋ก ๋์ฒดํ๊ณ Cloud Storage์ ํ ์คํธ ํ์ผ์ URI ๊ฐ์ ์ฌ์ฉํด์ผ ํจ- encodingType: API์ ํ ์คํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ ํ ์คํธ ์ธ์ฝ๋ฉ ์ ํ
nl-request.json์ content ๋ถ๋ถ์ ๋ณต์ฌํด ๋ฃ๊ธฐSTR=$(jq .data.translations[0].translatedText translation-response.json) && STR="${STR//\"}" && sed -i "s|your_text_here|$STR|g" nl-request.json
Natural Language API์ analyzeEntities ์๋ํฌ์ธํธ๋ฅผ ํธ์ถโก๏ธ ์ด์ nl-request.json ํ์ผ์ ์๋ณธ ์ด๋ฏธ์ง์์ ์ถ์ถํ์ฌ ์์ด๋ก ๋ฒ์ญ๋ ํ ์คํธ๊ฐ ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ถ์ ๊ฐ๋ฅ!
curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \
-s -X POST -H "Content-Type: application/json" --data-binary @nl-request.json

Response ๋ถ์
student_02_bd8583cb7b9e@cloudshell:~ (qwiklabs-gcp-02-6bd633451e8b)$ curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \ -s -X POST -H "Content-Type: application/json" --data-binary @nl-request.json { "entities": [ { "name": "news reports", "type": "WORK_OF_ART", "metadata": {}, "salience": 0.34937522, "mentions": [ { "text": { "content": "news reports", "beginOffset": 16 }, "type": "COMMON" } ] }, { "name": "PUBLIC GOOD", "type": "ORGANIZATION", "metadata": { "wikipedia_url": "https://en.wikipedia.org/wiki/Public_good", "mid": "/m/017bkk" }, "salience": 0.26161328, "mentions": [ { "text": { "content": "PUBLIC GOOD", "beginOffset": 4 }, "type": "PROPER" } ] }, { "name": "Obama", "type": "PERSON", "metadata": { "wikipedia_url": "https://en.wikipedia.org/wiki/Barack_Obama", "mid": "/m/02mjmr" }, "salience": 0.18295486, "mentions": [ { "text": { "content": "Obama", "beginOffset": 33 }, "type": "PROPER" } ] }, { "name": "mustard", "type": "OTHER", "metadata": {}, "salience": 0.115125984, "mentions": [ { "text": { "content": "mustard", "beginOffset": 44 }, "type": "COMMON" } ] }, { "name": "Dijon", "type": "LOCATION", "metadata": { "wikipedia_url": "https://en.wikipedia.org/wiki/Dijon", "mid": "/m/0pbhz" }, "salience": 0.09093063, "mentions": [ { "text": { "content": "Dijon", "beginOffset": 60 }, "type": "PROPER" } ] } ], "language": "en" }
์ํฐํฐ(์ด๋ฆ) ์ ํ ์ค์๋ ์ค๋ช new reports WORK_OF_ART 0.349 ์ด ๋ฌธ์ฅ์์ ๊ฐ์ฅ ํต์ฌ์ ์ธ ์์ฌ(์์ /์ ์๋ฌผ)๋ก ์ธ์ PUBLIC GOOD ORGANIZATION 0.261 ๊ณต๊ณต์ฌ๋ฅผ '๋จ์ฒด/์กฐ์ง'์ผ๋ก ๋ถ๋ฅ Obama PERSON 0.182 '๋ฒ๋ฝ ์ค๋ฐ๋ง'๋ผ๋ ์ธ๋ฌผ๋ก ์ ํํ ์ธ์ mustard OTHER 0.115 ์ผ๋ฐ์ ์ธ ์ฌ๋ฌผ(๋จธ์คํฐ๋ ์์ค ๋ฑ)๋ก ๋ถ๋ฅ Dijon LOCATION 0.091 ํ๋์ค์ ๋์ '๋์ข '์ด๋ผ๋ ์ฅ์๋ก ์ธ์
type: ํด๋น ๋จ์ด๊ฐ ์ธ๋ฌผ(PERSON), ์ฅ์(LOCATION), ์กฐ์ง(ORGANIZATION) ์ค ์ด๋์ ์ํ๋์ง๋ฅผ ๋ํ๋metadata: ์ง์ ๊ทธ๋ํ์ ์ฐ๊ฒฐ๋ ์ ๋ณด -> ํนํwikipedia_url์ด ์๋ค๋ ๊ฒ์ API๊ฐ ์ด ๋จ์ด๊ฐ ๊ตฌ์ฒด์ ์ผ๋ก ๋ฌด์์ธ์ง(์: ์๋ง์ ์ค๋ฐ๋ง ์ค ์ ๋ฏธ๊ตญ ๋ํต๋ น ์ค๋ฐ๋ง) ํ์คํ ์๊ณ ์๋ค๋ ๋ป!salience(์ค์๋): 0์์ 1 ์ฌ์ด์ ์ซ์๋ก, ๋ฌธ์ฅ์์ ์ด ๋จ์ด๊ฐ ์ผ๋ง๋ ์ค์ฌ์ ์ธ ์ญํ ์ ํ๋์ง ๋ณด์ฌ์คmentions: ๋ฌธ์ฅ ๋ด์์ ์ด ๋จ์ด๊ฐ ๋ํ๋ ์์น์ ๊ณ ์ ๋ช ์ฌ์ธ์ง ์ผ๋ฐ ๋ช ์ฌ์ธ์ง ๋ฑ์ ๋ํ๋
์ค์ต ๊ฐ์์๋ ์์ด๋ก ๋ฒ์ญ์ ํ๋๋ก ๋์ด ์์ง๋ง, ๋๋ ํ๊ตญ์ด๋ก ๋ฒ์ญ์ ์๋ํด๋ณด์๋ค. -> translation-request.json ํ์ผ์ target์ ko๋ก ๋ณ๊ฒฝ ํ ๋๋จธ์ง๋ ๋์ผํ ์์์ curl์ ์ฌ์ฉํ์ฌ ์งํํ์๋ค.
