2016年12月15日

IBM WatsonのVisual Recognition API(画像認識API)をRaspberry Piから使う (AWS のS3も使う)


◆今日のゴール

初めての人工知能!人工知能を使ってみる。

以前の記事でRaspberry PiにWEBカメラを取り付けて撮影をしてみました。
「Raspberry Piを監視カメラにしてみた【motion】」

例えば、Raspberry Piで撮影した写真だったり、その他様々な画像を、IBMの人工知能サービス、IBM Watson™ Developer Cloudがデベロッパー向けに提供をしている Visual Recognition(画像認識)API をRaspberry Piから使って画像を解析してみます。

取得した解析結果を用いて、いろいろなアイディアに活かすことができると思います。

ibm_watson.png url.png

◆手順
  • 【手順1】IBM Watson™ Developer Cloudのアカウント登録→endpointとAPI Keyの取得
  • 【手順2】AWSのアカウント登録、IAMユーザーの作成、S3のバケット作成。
  • 【手順3】RaspberryPiにAWS CLIのインストール
  • 【手順4】RaspberryPiから画像をS3にアップロード
  • 【手順5】人工知能Watson、Visual Recognition APIで解析
API仕様や利用料金などは、2016/12/15現在の情報となります。


スポンサードリンク

【手順1】IBM Watson™ Developer Cloudのアカウント登録
→endpointとAPI Keyの取得

IBM Bluemixに登録」←こちらからIBMのBluemixに登録します。
※ 既に登録済みの場合は不要です。
※ 無料トライアル期間を過ぎている場合、利用料金が課金される場合がありますのでご注意ください

アカウントを作成しBluemixにログインしたら、「Visual Recognition」のサービスを作成してください。
作成したVisual Recognitionの画面に行くと、以下のように表示されます。「サービス資格情報」タブをクリックします。
watson001.jpg

資格情報がリストにない場合は、「新規資格情報」から作成をしてください。
「資格情報の表示」を押すと、JSON形式でAPI Keyが表示されます。
APIを叩くときに必要となりますので、この「api_key」の値を控えておいてください。(下記画像のベタ塗り部分) watson002.jpg
【手順2】AWSのアカウント登録、IAMユーザーの作成、S3のバケット作成

【手順2-1】【AWSのアカウント登録】

AWSのアカウント作成し、AWSコンソールにログインをします。
https://aws.amazon.com/jp/

※ 無料枠を越えた利用には、料金が発生しますのでご注意ください。

【手順2-2】【IAMユーザーの作成】

S3を操作する権限をもつユーザーを作成し、アクセスキーを取得します。

●AWSコンソールからIAM(Identity and Access Management )を開きます。
●「ユーザー」を開きます
●「ユーザーを追加」をクリック
●ユーザー名は好きな名前をつけてください。「アクセスの種類」は【プログラムによるアクセス】にチェックを入れ、次のステップ「アクセス権限の設定」に進みます。
●「既存のポリシーを直接アタッチ」を選択しポリシー一覧から「AmazonS3FullAccess」にチェックを入れ次のステップに進みます。
●確認画面が表示されるので、「ユーザーの作成」をクリックし、完了させます。
●認証情報が記載されたCSVファイルをダウンロードします
※ シークレットキーは、ユーザー作成直後のここでしか取得できません。後から管理画面で確認することができませんので、必ず、ここでCSVファイルを取得します。
※ ここで取得したCSVに記載れている「Access key ID」、「Secret access key」はCLIの設定で必要になります


次は、S3の準備です。

【手順2-3】【S3のバケット作成】

●AWS管理画面からS3(Amazon Simple Storage Service)の管理画面を開きます。

●「バケットの作成」をクリックします
●バケット名に任意の名前をつけ、Regionを選択します。リージョンはどこでもよいです。
今回は、バケット名「raspigo」、リージョン「TOKYO」としました。
※バケット名は他の全ユーザーも含めて、重複不可です(ドメインみたいなものなので)。重複するとエラーになります。
●バケットを作成したら「プロパティ」をクリックし、「バケット:raspigo」の設定をします。
●「アクセス許可」を開き「バケットポリシーの編集」をクリックし、下記の通り入力し保存をします。
※9行目「raspigo」の部分は自身で作成したバケット名に変更してください
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "AddPerm",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::raspigo/*"
		}
	]
}
●「静的ウェブサイトホスティング」を開き、「ウェブサイトのホスティングを有効にする」を選択、インデックスドキュメントに「index.html」と入力してして保存します。
下記のようなエンドポイントURLが発行されますので控えておいてください。
{バケット名}.s3-website-{リージョン名}.amazonaws.com

【注意】 エンドポイントURLを知っている全ての人が、このバケット内のファイルにアクセスできる状態になっておりますので、終了後は「ウェブサイトのホスティングを有効にしない」にチェックを入れて保存しなおすと共に、バケットポリシーを削除してください。

●バケット(raspigo)をクリックし、「フォルダの作成」をクリックします。名前は「img」としておきます。

以上でAWS上での操作は完了です。

【手順3】RaspberryPiにAWS CLIのインストール

ここからはRaspberryPiのコンソールでの操作になります。

pipでAWS CLIをインストールします。
※ Pythonが入ってない場合は、まずPythonからインストールしてください。
$ cd /tmp
# setuptoolsのインストール
$ sudo wget http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python ez_setup.py

# pipのインストール
$ sudo wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo python get-pip.py

# AWS CLIのインストール
$ sudo pip install awscli

CLIの設定をします。
$ aws configure

AWS Access Key ID [None]: ************
AWS Secret Access Key [None]: ************
Default region name [None]: **-*****-*
Default output format [None]: json

・AWS Access Key IDは【手順2-2】【IAMユーザーの作成】で取得したCSVファイルに記載されている「Access key ID」の値を入力。
・AWS Secret Access Keyは【手順2-2】【IAMユーザーの作成】で取得したCSVファイルに記載されている「Secret access key」の値を入力。
・Default region name は【手順2-3】【S3のバケット作成】でバケットを作る際に指定したリージョンのCLIリージョン値を入力。
Tokyoならば「ap-northeast-1」です。リージョンについては以下を参照してください。
http://docs.aws.amazon.com/ja_jp/ElasticMapReduce/latest/DeveloperGuide/emr-plan-region.html

【手順4】RaspberryPiから画像をS3にアップロード


画像をS3にアップロードします。
ここでは、サンプル画像として、著作権フリーアイドルMIKA☆RIKAさんの画像を使わせて頂いております。
$ cd /tmp
$ sudo wget http://raspi.up.seesaa.net/image/outdoor_108_mikarika.jpg
〜略〜
100%[==================================================>] 345,650      788K/s 時間 0.4s    
2016-12-15 15:00:26 (788 KB/s) - `outdoor_108_mikarika.jpg.1' へ保存完了 [345650/345650]

$ aws s3 cp outdoor_108_mikarika.jpg s3://raspigo/img/
upload: ./outdoor_108_mikarika.jpg to s3://raspigo/img/outdoor_108_mikarika.jpg


前半部分は、サンプルに使う画像をwgetで取得しています。
aws s3 コマンドの「cp」はファイルのコピーです。
S3のアップロード先は次のように指定します。最後にスラッシュを忘れずに。 
s3://{バケット名}/{フォルダ名}/

では、確認のため、【手順2-3】【S3のバケット作成】で取得したエンドポイントURLを使って画像にアクセスしてみます。
ブラウザのアドレスバーに以下のULRを入力し開いてください。
(raspigoの部分は、自身の作成したバケット名に変更してください)
http://raspigo.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg
<http://{バケット名}.s3-website-{リージョン}.amazonaws.com/{フォルダ名}/{ファイル名}>

画像が表示されていれば、S3にアップロード成功です。
次は、このURLを使用してWatsonで解析します。このURLを控えておいてください。

【手順5】人工知能Watson、Visual Recognition APIで解析

いよいよ、人工知能であるWatsonの出番です。
Visual RecognitionのAPIリファレンスは下記ですので詳しく知りたい方はご覧ください。
http://www.ibm.com/watson/developercloud/visual-recognition/api/v3/

引き続きRaspberry Piでの操作となります。今回はPythonでAPIを叩くことにします。
urllibとurllib2のモジュールが必要ですので、入っていない場合はインストールしてください。

任意のディレクトリで「raspi_watson.py」という名前でファイルをつくります。
$ sudo vi raspi_watson.py

以下のように編集します。
6行目{api-key} の部分は【手順1】で取得したVisual RecognitionのAPI KEYの値に置き換えてください。
7行目の画像のURLは自分がS3にアップロードした画像のURLに変更してください。
# coding utf-8
import urllib
import urllib2

watsonurl = 'https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify'
apikey = '{api-key} '
imgurl = 'http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg'
ver = '2016-05-19'

values = {'api_key': apikey, 'url': imgurl, 'version': ver}

data = urllib.urlencode(values)

watsonurl = watsonurl + '?' +  data

req = urllib2.Request(watsonurl)

response = urllib2.urlopen(req)

print (response.read())

(補足)7行目の画像のURLをWEB上で公開されている任意のURLに変更することで、様々な画像の解析ができます。

ファイルを保存して実行すると、以下のように、画像の解析結果がJSON形式で取得できます。
$ sudo python raspi_watson.py 
{
    "custom_classes": 0,
    "images": [
        {
            "classifiers": [
                {
                    "classes": [
                        {
                            "class": "ao dai (women dress)",
                            "score": 0.861
                        },
                        {
                            "class": "dress",
                            "score": 0.861
                        },
                        {
                            "class": "bridesmaid",
                            "score": 0.63,
                            "type_hierarchy": "/person/female/woman/bridesmaid"
                        },
                        {
                            "class": "woman",
                            "score": 0.633
                        },
                        {
                            "class": "female",
                            "score": 0.635
                        },
                        {
                            "class": "person",
                            "score": 0.783
                        },
                        {
                            "class": "sister",
                            "score": 0.554,
                            "type_hierarchy": "/person/sister"
                        }
                    ],
                    "classifier_id": "default",
                    "name": "default"
                }
            ],
            "resolved_url": "http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg",
            "source_url": "http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg"
        }
    ],
    "images_processed": 1
}

classが分類項目で、scoreがその精度です。scoreは1に近いほど精度が高いということです。

【表情解析もしてみる】

画像が人物の画像である場合は、年齢や性別なども解析することができます。
「Detect faces」というメソッドを使用します。
$ sudo vi raspi_watson_detectface.py

先ほどと同様、以下のように編集します。
6行目{api-key} の部分は【手順1】で取得したVisual RecognitionのAPI KEYの値に置き換えてください。
7行目の画像のURLは自分がS3にアップロードした画像のURLに変更してください。
8行目のバージョンも、先ほどの分類分けAPIとは異なりますのでご注意ください。
# coding utf-8
import urllib
import urllib2

watsonurl = 'https://gateway-a.watsonplatform.net/visual-recognition/api/v3/detect_faces'
apikey = '{api-key}'
imgurl = 'http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg'
ver = '2016-05-20'

values = {'api_key': apikey, 'url': imgurl, 'version': ver}

data = urllib.urlencode(values)

watsonurl = watsonurl + '?' +  data

req = urllib2.Request(watsonurl)

response = urllib2.urlopen(req)

print (response.read())

実行すると以下のように年齢や性別の推定値が取得できます。サンプルの画像は2人写っているので、2人分の結果が戻ってきます。
$ sudo python raspi_watson_detectface.py
{
    "images": [
        {
            "faces": [
                {
                    "age": {
                        "max": 44,
                        "min": 35,
                        "score": 0.427975
                    },
                    "face_location": {
                        "height": 104,
                        "left": 302,
                        "top": 53,
                        "width": 86
                    },
                    "gender": {
                        "gender": "FEMALE",
                        "score": 0.993307
                    }
                },
                {
                    "age": {
                        "max": 24,
                        "min": 18,
                        "score": 0.394433
                    },
                    "face_location": {
                        "height": 120,
                        "left": 200,
                        "top": 90,
                        "width": 69
                    },
                    "gender": {
                        "gender": "FEMALE",
                        "score": 0.989013
                    },
                    "identity": {
                        "name": "Lisa Ono",
                        "score": 0.817574,
                        "type_hierarchy": "/family members/friends/lisa/lisa ono"
                    }
                }
            ],
            "resolved_url": "http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg",
            "source_url": "http://{バケット名}.s3-website-ap-northeast-1.amazonaws.com/img/outdoor_108_mikarika.jpg"
        }
    ],
    "images_processed": 1
}

ハリウッドセレブやアメリカの有名人、大統領の写真なんかで試してみると、面白い結果が得られます。
ぜひ試してみてください。

お疲れ様でした。これで人工知能の第一歩を踏み出したも同然です!



posted by Raspberry Pi at 18:08 | Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。