2017年6月12日 星期一

Google Video Intelligence 學習筆記

Google Video Intelligence 學習筆記

除了前面所述 Google Cloud vision,透過靜態照片來由Google Cloud Vision AI 來辨識之外,Google另一項影像辨識功能,即透過影片(video) 來進行影像辨識。

這篇有介紹如何進行Google Video Intelligence 的 快速入門。

在這篇的範例,需要先安裝Google Cloud SDK,再請先安裝

開啟一個專案

  1. 在Google Cloud Platform 內,先建立一個新的專案。
  2. 到 API 管理介面,啟用 Google Video Intelligence API
  3. 然後在 API 管理介面內,點選「憑證」,建立API 金鑰,它會跳出一個視窗,告訴你在使用此API 時,用 key=API_KEY 來傳送金鑰,所以記得要先把你的API 金鑰剪下來,貼在你的文字檔裡。如下圖:

設定授權

在你安裝好 Google Cloud SDK 後,在其目錄下就會有 cloud 這支程式:
  1. 建立一個服務帳號,叫 quickstart:
  1. gcloud iam service-accounts create quickstart

  2. 建立 service account key file,其中your-project-123 是你剛才建立的專案名稱全名(即加上 - 後面的數字串):
  3. gcloud iam service-accounts keys create key.json \
    --iam-account quickstart@your-project-123.iam.gserviceaccount.com
  4. 授權給你的service account,並把你的service account key file 位置傳送過去
  5. gcloud auth activate-service-account --key-file key.json
  6. 取得授權,並將它顯示在螢幕上:
  7. gcloud auth print-access-token
你會看到程式大概五秒之後會顯示一長串亂碼,那其實就是你的key,也就是上面圖示顯示的那塊。

進行 Video 辨識請求

  1. 用文字編輯器,將下列文字copy 到你的文字檔裡,用來產生一個 JSON 要求檔,就叫 request.json但要記得,將你的檔案copy 到你的 google cloud storage 內。目前google video intelligence 只支援將影片上傳到其google cloud storage 內做辨識,並不支援其他任何方式(如 streaming)。像下面的範例就是在cloud storage 建立一個 video 目錄,再把 chicago.mp4 上傳到這個video 目錄下。
  2. {
       "inputUri":"gs://cloud-ml-sandbox/video/chicago.mp4",
       "features": [
           "LABEL_DETECTION"
       ]
    }
    
  3. 利用 curl 指令來產生影像辨識要求 (videos:annotate),將下方的 ACCESS_TOKEN h利用剛才印出的那一長串亂碼(即access token) 取代,其餘照抄(下面這指令全在同一行內, \表連續行):
  4. curl -s -k -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer ACCESS_TOKEN' \
        'https://videointelligence.googleapis.com/v1beta1/videos:annotate' \
        -d @request.json
    Video intelligence API 會產生一個 operation 以處理你的辨識要求。上述指令下完會,會顯示它產生的 operation name:
      {
        "name": "us-west-18358601230245040268"
      }
      
    1. 這時Google 已經開始在分析你的影片,你可以傳遞operation name 並透過 v1.operations  來取得分析結果:
    2. curl -s -k -H 'Content-Type: application/json' \
          -H 'Authorization: Bearer ACCESS_TOKEN' \
          'https://videointelligence.googleapis.com/v1/operations/OPERATION_NAME'
      你會看到Google 回應你分析的結果,如果分析尚未完成,那在 done 這個值會是 false:
      {
        "name": "OPERATION_NAME",
        "metadata": {
          "@type": "type.googleapis.com/google.cloud.videointelligence.v1beta1.Annota
      tionProgressMetadata",
          "progressMetadata": [
            {
              "inputUri": "gs://cloud-ml-sandbox/video/chicago.mp4",
              "progressPercent": 0,
              "startTime": "2016-09-22T21:41:56.766091Z",
              "lastUpdateTime": "2016-09-22T21:42:03.889743Z"
            }
          ]
        },
        "done": false,
        ...
      }
      
    在分析完所有資料後,你再下一次上述指令,就可以看到Google Video intelligence 對你的影片做的完整分析內容。其中 description 欄表示它判斷可能的物件名稱,confidence 表信心值,或簡單說,它猜此物件的正確率大約是多少。

    結論


    基本上Google Video intelligence 可以辨識出的物件仍然有限,尤其影片不清楚時,所以它的信心值都不高。它目前可以做物件分析,臉部分析,標題分析和場景變換的辨認。它可以用來判斷你的影片內出現了那些東西,但無法很精確地辨識出人臉或(誰)出現在影片裡。但Apple 的 照片 程式可以將類似的人臉整合成一個群組,再給人類進行更正確的判斷是否為同一個人。我想,應該要做到這樣的程度才夠吧。而且,影片還要上傳到google storage才能辨識,還不夠方便。不過,Google 也強調,這是beta,還沒算正試的服務,就玩玩看囉。



    2017年6月8日 星期四

    Google Cloud Vision 學習筆記 2

    安裝 Client library

    這裡有介紹如何安裝你的語言版本的library

    我用的是python,所以在command line 下:
    pip install --upgrade google-cloud-vision

    就會自動安裝了。

    (2017/6/6) 等等,這個架構可以玩玩,但我是想要裝在RPi 上的,可是這個架構並沒有RPi 的 Google Cloud SDK. 只有for X86 linux, macOS 和 windows ⋯⋯ 
    (2017/6/7) 找到一個 demo了,原來不一定要用Google Cloud SDK. 用API 就可以了。快來參考這篇

    安裝後,你會發現下面的範例是需要安裝 Google Cloud SDK,依照你的系統(我是用Mac),下載合適的SDK,再執行它的 install 檔。 然後 執行 gcloud init 來設定你的帳號和預設專案(project),若需要,可以再開一個 Google compute Engine API。依其範例,應該是用Google Compute Engine 來執行,因為後來我看 API 管理員的主頁,只有 Google Compute Engine API 有流量,Google Cloud Vision API 完全沒流量。
    而且,請記得將SDK 安裝在~ 下,我之前放在 virtualenv 或其它目錄,執行gcloud 都會出現問題,搞了我好久。

    安裝好 SDK 後,回到 Cloud Vision API Client Libraries 的說明,要再執行認證:
    gcloud auth application-default login
    這樣就差不多了。
    然後 copy 以下檔案到你電腦裡的目錄:

    C#

    GO

    JAVA

    NODE.JS

    PHP

    PYTHON

    RUBY

    import ioimport os # Imports the Google Cloud client library from google.cloud import vision # Instantiates a client vision_client = vision.Client() # The name of the image file to annotate file_name = os.path.join(     os.path.dirname(__file__),     'resources/wakeupcat.jpg') # Loads the image into memory with io.open(file_name, 'rb') as image_file:     content = image_file.read()     image = vision_client.image(         content=content) # Performs label detection on the image file labels = image.detect_labels() print('Labels:') for label in labels:     print(label.description)
    Read more in the Python API Reference Documentation for the Google Cloud Vision API Client Library.

    其中 __file__ 會帶出你目前的檔案路徑,所以你的圖檔要放在你目前路徑下的 resources 目錄裡,至於圖檔名,就隨便你取。

    再 執行此python 檔,就可以看到輸出的Json 結果。
    基本上就是Google Vision 會判斷你的圖檔內容大概是什麼,可能性的機率有多高等等的。




    2017年6月5日 星期一

    Google Cloud Vision 學習筆記 1

    與其自己重新學習影像辨識和AI,不如直接站在巨人的肩膀上⋯⋯

    先從 Google 提供的 5 分鐘 quickstart 來學。

    以Quickstart 的介紹,要透過Vision API 來使用 Google cloud vision,要透過下列三步驟:


    • 建立 Cloud Storage 空間。Creating a Cloud Storage bucket.
    • 將你的照片上傳至建立的Cloud Storage 並設定為公開。Uploading your image to Cloud Storage and making it public.
    • 以照片來向Vision API 要求辨識。Making a request to the Vision API with that image.

    照Google 的說法,上述步驟約要5分鐘的時間,可以建立一個 5GB 的免費儲存空間,並且每個月可丟 1000次以內的免費辨識服務要求。

    在開始建立Google Storage 之前,要先在Google Platform Console 建立一個專案。
    1. 到專案頁面,建立一個新的專案。我先建立一個叫 Cloud-Vision-test 的專案名稱,但Google 的回應有點慢,它跳到所有專案的頁面,卻沒看到剛建立的 Colud-Vision-test 專案名稱。我馬上再建一個新的,當它refresh 完頁面後,才發現重覆建立了。所以專案建立的按鈕按下後,要稍等一下。
    2. 啟動計費功能。可能我之前已啟動,所以畫面直接跳到專案內容畫面。
    3. 啟動Cloud Vision API. 中間欄有API 的選項,點選後會出現Google Cloud Platform 的所有 API,利用Filter 的方式,輸入 vision ,就可以看到Cloud Vision API。點選後會出現下列圖片。

    然後點選啟用,就會出現目前此 API 的使用情形。但因為我們還沒有任何使用,所以畫面呈現出的都是空值。

    接下來建立 Cloud Storage bucket。
    1. 在 Cloud Platform Console 裡,連到 Cloud Storage 畫面。
    2. 點選「建立bucket」。

    3. 在建立 bucket 的對話畫面中,設定以下屬性:

    • 名稱:可以任意指定,但因為bucket 的資料是公開的,如果你的名稱內含機密資訊,那可能會被其他人看到。所以我用內建的名稱就好,內建的不會選一個和別人一樣的吧。
    • 儲存級別:文件是建議選用 Milti-Regional。但我看了級別的說明,Multi-Regional 是適合需要經常跨國存取的資料,又說可用來串流播放影片及代管熱門網路內容。但我只是要用自己上傳的影片,可是Regional 又只提到可用來儲存資料及執行資料分析,不知能否上傳圖片。我先試試Regional 了好。
    • Regional 位置:如果選用 Multi-Regional , 那 Regional位置只有 亞洲、歐盟和美國可以選,可能它會直接放在這幾個地區的不同storage site 吧。但如果是選 Regional, 則可以選 上述三洲的不同地區。亞洲有asia-east1, asia-northeast1 和 asia-sourtheast1 可選。台灣的位置有點尷尬,所以我直接選 asia-northeast1
    4. 點選建立。

    建立對 Cloud Vision API 服務的要求

    1. 下載 他建議的 demo-image.jpg
    2. 開啟 Cloud Platform Console Storage Brower, 選定 bucket, 然後點選上傳檔案,並選擇剛剛下載的 demo-image.jpg 來上傳。
    3. 上傳檔案後,畫面會出現已上傳的通知,並且在畫面上呈現出已上傳的檔案列表。在我們剛上傳的 demo-image.jpg 後䤏有個「公開共用」的選項,將其點選。
    4. 透過以下的程式範例,來執行 Vision API 請求。 將其中的 image.source.imageUri 的 bucket 字眼改成你剛才在bucket 內建立的名稱和圖片檔名,再按下EXECUTE後,不出一秒的時間,就會得到 AI 辨識後的 JSON 結果檔。
    5. 執行結果如下:


    搞定!!!

    清除

    為了避免無謂的被Google Cloud Platform 扣款(可能你自己不自覺地測試超過1000次),所以 Google 也很貼心的建議你,如果測試完後,就把用不到的 bucket 砍了。夠貼心吧。

    後記
    上傳了幾個自己的圖檔去辨識,好像都沒能辨識出來⋯⋯


    2017年5月9日 星期二

    Docker 學習筆記 - Part 2

    事前準備:

    • 安裝 Docker 1.13 以上版本
    • 讀過 Part 1
    • 確定你的環境,並執行 docker run hello-world

    介紹:

    我們可以開始用docker 的方式來建立我們的程式。 首先我們要建立container, 好讓我們的程式在上面跑。再container 上面的app, service , service, stack , 以後的章節再介紹。

    • Stack
    • Services
    • Container (我們目前在此階段)

    我的新開發環境:

    以往我們要開放一支新的程式,如 Python 程式,首先必需在電腦上安裝 Python 開發環境。但這會造成你在你的主機裡建立一個你在開發 python 程式時所需的環境,但程式移到server 時,就可以跑你寫出的程式嗎?

    透過 Docker,你可以只安裝 python 執行環境 包成一個 image,而不需再重新安裝一次python 環境。而且,你的image 也可以包含你開發的app,確定你的程式,和其相依套件,都可以一起包進image 內。 這種 可攜式的image, 就稱作 Dockerfile

    Dockerfile 來定義一個 container

    Dockerfile 用來定義你想要你的container 內是什麼樣的環境,取在這image 環境內的虛擬化的主機資源(如網路介面和磁碟檔案),因為已經被隔離在主機外了,所以你必需自己去對映 port 到外面的世界(有點像網路的 pat 或 nat)。並指定你想要把檔案 copy 進你的container 環境裡。做完後,你就可以期待你的程式在 Dockerfile內設定好而建立的docker 內,順利執行了,拿去那裡,都可以順利執竹。

    Dockerfile

    先建立一個空的目錄,然後把以下內容建立成一個檔案名稱Dockerfile 的檔案。#代表註解。

    # Use an official Python runtime as a base image
    FROM python:2.7-slim
    
    # Set the working directory to /app
    WORKDIR /app
    
    # Copy the current directory contents into the container at /app
    ADD . /app
    
    # Install any needed packages specified in requirements.txt
    RUN pip install -r requirements.txt
    
    # Make port 80 available to the world outside this container
    EXPOSE 80
    
    # Define environment variable
    ENV NAME World
    
    # Run app.py when the container launches
    CMD ["python", "app.py"]

    這個 Dockerfile 裡面有兩個我們還沒建立的東西,即 app.py 和 requirements.txt


    app 本身

    上述兩個檔案也要放在和Dockerfile同一個目錄內。這樣就可以完成我們app 的環境,簡單吧。 當上述的 Dockerfile 被建立到 image 內後,app.py 和 requirements.txt 都會被包含在內,因為Dockerfile 使用 ADD 指令。而從 app.py的輸入則可以透過HTTP來讀取,因為我們在 Dockerfile內用了EXPOSE
    from flask import Flask
    from redis import Redis, RedisError
    import os
    import socket
    
    # Connect to Redis
    redis = Redis(host="redis", db=0)
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        try:
            visits = redis.incr('counter')
        except RedisError:
            visits = "<i>cannot connect to Redis, counter disabled</i>"
    
        html = "<h3>Hello {name}!</h3>" \
               "<b>Hostname:</b> {hostname}<br/>" \
               "<b>Visits:</b> {visits}"
        return html.format(name=os.getenv('NAME', "world"), hostname=socket.gethostname(), visits=visits)
    
    if __name__ == "__main__":
     app.run(host='0.0.0.0', port=80)

    然後我們可以看到 在 Dockerfile 內有一行 pip install requirements.txt 安裝了 Flask 和 Radis 的Python 函式庫。而我們的app 程式列出環境變數 NAME, 當它執行到 docker.gethostname()會用到。最後,因為 Redis 無法執行(我們只是將它的 python 函式include進來,而非 Redis 程式),所以我們會得到一個錯誤訊息,而無法再繼續程式。


    來建立 app 吧

    好了!你不需要在你的主體主機裡安裝python 或 requirements.txt裡的東西,也不需要建立或安裝這個image 在你的主體主機裡。看來雖然好像你還沒建立好 Python 和 Flask 的環境,但實事上你已經建好了。
    我們ls 一下看看:

    $ ls
    Dockerfile              app.py                  requirements.txt

    OK, 我們要開始建立我們的image 了。我們會用參數 -t 來建立一個 image 的名字。

    docker build -t friendlyhello .
    那建立出來的image 放在那呢?它會被docker 放在 你主體主機的 Docker image registry 指定的位置裡。用下列指令就可以知道 你的image 有那些:


    $ docker images
    
    REPOSITORY            TAG                 IMAGE ID
    friendlyhello         latest              326387cea398


    執行app

    要執行我們的 app.py 要先把 主體主機的 port 4000 用 -p 對映到 image 內 EXPOSE 的 port 80 :


    docker run -p 4000:80 friendlyhello
    其中-p  指要做 port mapping , 其中 4000 指 主體主機的 port 位,80 指 container 的 port 位,中間用 : 冒號隔開。按 Ctrl-C 離開container。
    OK,那接下來我們用 -d 讓我們的app 在背景執行:


    docker run -d -p 4000:80 friendlyhello
    然後畫面會出現一長串的 CONTAINER ID,然會就回到你的主體主機畫面。現在,我們剛做的container 已經在背景執行了。你可以用 docker ps 來看看你有那些container 正在執行。


    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED
    1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago
    現在我們可以用 docker stop 來中止我們的程式。


    分享你的image

    registry 是 repositories 的集合,而repository 是 image 的集合。而 registry 上的 account 可以建立許多的 repository。docker command line interface 指令 就是預設的 docker公用 registry。

    如果你己經有了 Docker account, 登入 cloud.docker.com。

    docker login
    畫面會要求你輸入你在 cloud.docker.com 建立的帳密。
    現在,我們就可以上傳我們做的image了。 在我們電腦裡的image 含在 registry 上的 repository 的表示式用 username/repository:tag ,其中 :tag 是選擇性的,但建議還是輸入,一般是用來表示這個image 的版本。

    docker tag friendlyhello username/repository:tag

    可以上傳了:

    docker push username/repository:tag
    上傳完之後,我門就可以在任何有裝docker 的電腦上,執行下列指令來啟動 我們剛裝的 image,當然,前題是要能上網。如果你沒下 :tag 指令,那它會找最新的,即它會自動加上 :latest 的tag.
    現在,用你的流灠器看一下 localhost:4000 ,看是不是有正確的 hello, World 會出現。