m_shige1979のささやかな抵抗と欲望の日々

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(注意すること)

https://github.com/mshige1979

Google Homeアプリを作成

AIスピーカー

f:id:m_shige1979:20180310143808j:plain
こんなやつ

やること

APIを作成

プロジェクト作成
firebase init functions
npm install firebase-functions@latest firebase-admin@latest --save
npm install --save actions-on-google
ソースコード
'use strict'

process.env.DEBUG = 'actions-on-google:*';
const App = require('actions-on-google').DialogflowApp;
const functions = require('firebase-functions');

const NAME_ACTION = "age_check";

exports.age_ask = functions.https.onRequest((request, response) => {
    const app = new App({ request, response });

    function test1(app) {
        let age = app.getArgument("age");
        app.tell("年齢は" + age + "と聞こえています。");
    }

    let actionMap = new Map();
    actionMap.set(NAME_ACTION, test1);

    app.handleRequest(actionMap);
});
デプロイ
firebase deploy --only functions:age_ask

プロジェクト作成

https://console.actions.google.com/へアクセスし、新規プロジェクトを追加

f:id:m_shige1979:20180310200011p:plain

プロジェクト名や国を設定

f:id:m_shige1979:20180310200020p:plain

dialogflowの BUILDを選択

f:id:m_shige1979:20180310200028p:plain

アカウントを選択

f:id:m_shige1979:20180310200103p:plain

対象の権限を許可

f:id:m_shige1979:20180310200118p:plain

国情報や同意にチェック

f:id:m_shige1979:20180310200406p:plain

特定のアプリに対する許可を設定

f:id:m_shige1979:20180310200414p:plain

Agentを追加する

f:id:m_shige1979:20180310200555p:plain

Agentの名称などを設定

f:id:m_shige1979:20180310200606p:plain

インテントを確認

f:id:m_shige1979:20180310200618p:plain

メニュー確認

f:id:m_shige1979:20180310201733p:plain

インテントを設定

発話サンプルやパラメータの紐付けを設定

f:id:m_shige1979:20180310201442p:plain

WebHook有効化

f:id:m_shige1979:20180310201455p:plain

WebHook用URL設定

f:id:m_shige1979:20180310201507p:plain

テスト

Google アシスタンとを選択する

f:id:m_shige1979:20180310202317p:plain

追加用のインテントを追加して「TEST」を選択

f:id:m_shige1979:20180310202327p:plain

シミュレータを起動してテキストベースでテスト実施

f:id:m_shige1979:20180310202338p:plain

firebaseのfunctionsを作成してみた

firebase

Google用のサービスのBaasみたいのようです。
無料プランもあるので簡単にお試ししてみました。

functionとは

APIとかを作成できるサービス
サポートしているものはJavascript及びTypeScriptのようです。

準備

Nodejs(v6.11.5)

手順

firebaseツールのインストール
npm install -g firebase-tools

※使用環境に応じてsudoコマンドを設定する必要があります

ログイン
firebase login

※webブラウザが起動し、googleアカウントの選択及び、権限許可を求められるため設定します。

f:id:m_shige1979:20180310125045p:plain
f:id:m_shige1979:20180310125055p:plain
f:id:m_shige1979:20180310125105p:plain

以下へアクセスし任意のアプリを作成する

https://console.firebase.google.com/
f:id:m_shige1979:20180310125303p:plain

アプリ作成

ディレクトリ作成
mkdir -p work/firebase_samples/sample_test1
cd work/firebase_samples/sample_test1
アプリ初期化
firebase init functions
対象のプロジェクトを選択
? Select a default Firebase project for this directory:
  [don't setup a default project]
❯ sample-test01 (sample-test01)
  [create a new project]
各問い合わせ設定
? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
? What language would you like to use to write Cloud Functions? (Use arrow keys)
ファイル編集

functions/index.js

onst functions = require('firebase-functions');

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.sampleapp1 = functions.https.onRequest((request, response) => {
  response.send("Hello from Firebase! Sample App1");
});
デプロイ
firebase deploy --only functions

✔  functions: Finished running predeploy script.
i  functions: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (2.35 KB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: creating function sampleapp1...
✔  functions[sampleapp1]: Successful create operation.
Function URL (sampleapp1): https://us-central1-sample-test01.cloudfunctions.net/sampleapp1

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/sample-test01/overview
結果
curl https://us-central1-sample-test01.cloudfunctions.net/sampleapp1
Hello from Firebase! Sample App1

【備忘】AWSのDyanmoDBのCLIコマンドについて

DynamodDBの学習を一部していて

ちょっと簡単なコマンドの基本をメモ

テーブル操作系

テーブルの作成
aws dynamodb create-table --table-name 'test1' \
    --attribute-definitions '[{"AttributeName":"id","AttributeType": "S"}]' \
    --key-schema '[{"AttributeName":"id","KeyType": "HASH"}]' \
    --provisioned-throughput '{"ReadCapacityUnits": 5,"WriteCapacityUnits": 5}'
テーブルの一覧
aws dynamodb list-tables
テーブルの削除
aws dynamodb delete-table --table-name test1

データ取得系

データ取得
aws dynamodb scan --table-name test1
データ取得(件数のみ)
aws dynamodb scan --table-name test1 --select COUNT
条件指定
aws dynamodb get-item --table-name test1  \
    --key '{ "id": {"S": "1" }  }'

データ登録系

追加
aws dynamodb put-item --table-name test1 \
    --item '
    {
        "id": { "S": "1" },
        "data1": { "N": "100" },
        "date2": { "S": "aaaaaaa" },
        "data3": { "S": "bbbbbbb" }
    }'
更新1
aws dynamodb update-item --table-name test1 \
    --key '{ "id": {"S": "1"} }' \
    --attribute-updates '
    {
        "data1": {
            "Action": "PUT",
            "Value": {"S": "300" }
        }
    }'
更新2
aws dynamodb update-item --table-name test1 \
    --key '{ "id": {"S": "1"} }' \
    --update-expression 'SET data1 = :param1' \
    --expression-attribute-values '{
        ":param1": {"N":"90000"}
    }'
削除
aws dynamodb delete-item --table-name test1 \
    --key '{ "id": {"S": "1"} }'

まだ条件はいろいろありますが基本的な部分のみ抜粋

FaceApiを試す。(ローカルよりファイルをアップロードして結果を取得)

基本的にはURLを指定するサンプルしかない

ので探していろいろやってみた。

実装

sample2.go
package main

import (
    "log"
    "net/http"
    "bytes"
    "io/ioutil"
)

func main() {
    key1 := "生成したキー"
    jpegData, _ := ioutil.ReadFile("face.jpg")

    // EndPoint
    endPoint := "https://eastasia.api.cognitive.microsoft.com/face/v1.0"

    // params
    paramStr := "/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,glasses"

    // URL
    url := endPoint + paramStr
    log.Println(url)

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jpegData))
    if err != nil {
        log.Fatal("Request:", err)
        return
    }

    req.Header.Set("Content-Type", "application/octet-stream")
    req.Header.Set("Ocp-Apim-Subscription-Key", key1)

    httpClient := &http.Client{}

    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatal("Do: ", err)
        return
    }

    defer resp.Body.Close()

    byteArray, _ := ioutil.ReadAll(resp.Body)
    log.Println(string(byteArray))

}

2017/11/05 23:02:03 https://eastasia.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,glasses
2017/11/05 23:02:04 [{"faceId":"b28efd98-47db-460f-8556-d1882565d4a9","faceRectangle":{"top":156,"left":173,"width":178,"height":178},"faceAttributes":{"gender":"male","age":33.8,"glasses":"NoGlasses"}}]

必要なこと

application/octet-streamを送信

image/jpegなどではエラーが帰ってきた

所感

クライアントからファイルを送信するサンプルがなかなか見つからない感じ
ファイルの送信する方法はまだ調べないといけない感じ…

AzureのFaceAPIをgo言語で試す

FaceAPIとは?

Face API - 顔認識 | Microsoft Azure
画像より顔を認識してその情報を返すAPI

準備

AzureでFaceAPIのサービスを開始してキーを取得刷る必要があります。

手順

その他サービスより検索

f:id:m_shige1979:20171105214729p:plain

Cognitiveサービスを開始する

f:id:m_shige1979:20171105214739p:plain

FaceAPIを検索して開始する

f:id:m_shige1979:20171105214748p:plain

作成に同意

f:id:m_shige1979:20171105214800p:plain

設定情報を入力して作成

f:id:m_shige1979:20171105214810p:plain

ダッシュボードに追加されたことを確認

f:id:m_shige1979:20171105214822p:plain

エンドポイントを確認

f:id:m_shige1979:20171105214834p:plain

キーを確認

f:id:m_shige1979:20171105214842p:plain

実装

sample1.go
package main

import (
    "log"
    "net/http"
    "bytes"
    "io/ioutil"
)

func main() {
    key1 := "アクセスキー"
    jsonStr := []byte(`{"url":"画像のURL"}`)

    // EndPoint
    endPoint := "https://eastasia.api.cognitive.microsoft.com/face/v1.0"

    // params
    paramStr := "/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,glasses"

    // URL
    url := endPoint + paramStr
    log.Println(url)

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    if err != nil {
        log.Fatal("Request:", err)
        return
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Ocp-Apim-Subscription-Key", key1)

    httpClient := &http.Client{}

    resp, err := httpClient.Do(req)
    if err != nil {
        log.Fatal("Do: ", err)
        return
    }

    defer resp.Body.Close()

    byteArray, _ := ioutil.ReadAll(resp.Body)
    log.Println(string(byteArray))

}

2017/11/05 21:43:24 https://eastasia.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,glasses
2017/11/05 21:43:25 [{"faceId":"4e075f28-ce54-4844-ac63-a4a77b5da9ce","faceRectangle":{"top":64,"left":121,"width":152,"height":152},"faceAttributes":{"gender":"male","age":44.8,"glasses":"NoGlasses"}}]

※サンプル画像はネットより拝借しました。m(_ _)m

所感

料金プランかなんかで速度とか変わると良いです。なんか時間としてはそんなに早く感じていないので

go言語で画像を作成(編集)する【imagemagick】

ImageMagick

画像編集するライブラリで超優秀なやつ
文字列の設定なども可能
フォントは微妙

インストール(Mac

brew install ruby
brew install ImageMagick
brew install pkg-config
go get gopkg.in/gographics/imagick.v3/imagick

rubyは2.3以上
※imagickはimagemagickのインストールバージョンで切り替え

実装

sample2.go
package main

import (
    "gopkg.in/gographics/imagick.v3/imagick"
//    "fmt"
)

func main() {

    var err error

    imagick.Initialize()
    defer imagick.Terminate()
    mw := imagick.NewMagickWand()
    dw := imagick.NewDrawingWand()
    pw := imagick.NewPixelWand()
    defer mw.Destroy()

    // 短形を作成
    pw.SetColor("none")
    mw.NewImage(400, 300, pw)

    // フォント設定
    pw.SetColor("RGB(255, 0, 125)")
    dw.SetFillColor(pw)
    dw.SetFontSize(60)
    pw.SetColor("RGB(255, 0, 125)")
    dw.SetStrokeColor(pw)

    // テキスト設定
    dw.Annotation(25, 65, "Sample")

    // 短形の描画(塗りつぶしなし)
    pw.SetColor("RGB(100, 100, 100)")
    dw.SetStrokeColor(pw)
    dw.SetStrokeWidth(4)
    pw.SetColor("none")
    dw.SetFillColor(pw)
    dw.Rectangle(50, 150, 120, 250)
    dw.PushDrawingWand()

    // 描画
    mw.DrawImage(dw)

    // 合成用
    pw2 := imagick.NewPixelWand()
    mw2 := imagick.NewMagickWand()
    defer mw2.Destroy()
    pw2.SetColor("blue")
    mw2.NewImage(120, 100, pw2)
    // 指定の場所へ合成
    err = mw.CompositeImage(mw2, mw2.GetImageCompose(), true, 100, 100)
    if err != nil {
        panic(err)
    }

    // 出力フォーマット
    err = mw.SetFormat("png")
    if err != nil {
        panic(err)
    }

    // ファイルへ出力
    mw.WriteImage("text_shadow.png")
}

f:id:m_shige1979:20171029150935p:plain

所感

文字列を挿入できました(^^)
まあ、あまり画像を使うことはないですがとりあえず覚えておこうかと思います。

go言語で超シンプルな画像作成

画像を作成

短形の画像を作成する。

実装

sample1.go
package main

import (
    "log"
    "image"
    "image/jpeg"
    "image/color"
    "os"
)

var (
    x = 0
    y = 0
    width = 400
    height = 300
    quality = 100
)

func main() {
    log.Println("start")

    // 短形を作成する
    img := image.NewRGBA(image.Rect(x, y, width, height))
    // 短形に色を追加
    for i := img.Rect.Min.Y; i<img.Rect.Max.Y;i++ {
        for j := img.Rect.Min.X; j<img.Rect.Max.X; j++ {
            img.Set(j, i, color.RGBA{255, 255, 0, 0})
        }
    }

    // ファイルを作成し、終了時にクローズ
    file, _ := os.Create("sampleImage1.jpg")
    defer file.Close()

    err := jpeg.Encode(file, img, &jpeg.Options{quality});
    if err != nil {
        log.Println(err)
    }

    log.Println("end")
}

結果
f:id:m_shige1979:20171029133049p:plain

所感

文字列が入力してみたいけどネットで探したけど見つからない…
探してもう少し探してみる