Help us understand the problem. What is going on with this article?

Swiftから画像認識(AlchemyAPIによる画像のタグ付け)サービスを使う

More than 3 years have passed since last update.

画像認識(画像のタグ付け)って何?

画像をアップロードすると(または画像のURLを伝えると)、その画像を認識して、それが何かってことを返してくれるサービス。

例えば、public-domain-photosから拾ってきた下のヨセミテ公園の画像をアップロードすると、
yosemite-meadows.png

下記のようなレスポンスで、それが"自然(nature)"であるとか、"ヨセミテ国立公園(yosemite)"であることを教えてくれる。scoreはその確からしさを表す。画像の自動分類なんかに使われる。

    "imageKeywords": [
        {
            "text": "nature",
            "score": "0.916827"
        },
        {
            "text": "yosemite",
            "score": "0.900249"
        }

Alchemy APIって?

・機械学習系の技術で、言語認識や画像認識のサービスを提供している。日本語だとこちらの方のブログが詳しい。ただし、現在はIBMに買収されていて、IBMのPaaS(Bluemix)から使える(後述)。

・今回使うのは AlchemyVisionのImage TaggingというAPI。デモサイトがあり、簡単に試せる。ちなみに日本では食べログが使っているらしい。

Alchemy APIを利用可能にする

Free Planがあり、1日あたり1000回の呼び出しまで無料。以下、AlchemyAPIのapikeyとurlを取得するまでの手順。

1.Bluemixへの登録

登録はここから。30日無料で、30日以降も使用するのであれば要クレジットカード登録。クレジットカード登録ってのが若干敷居高いですが、フリープランだけ使ってれば課金されないはず。

2.Bluemixにログイン

BluemixのTOPからログインする。

3.Alchemy APIサービスを作成する

①上部のメニューからカタログを選ぶ
Kobito.gIpoKg.png

②AlchemyAPIを見つけてクリック(Watsonカテゴリにある)
Kobito.izX9dI.png

③「選択済みプラン」が「Free」であることを確認しつつ、デフォルトの状態で作成する
Kobito.hrO2q6.png

④サービスが作成されたら、左側のメニューから「サービス資格情報」をクリックして、"url"とapikeyを確認してメモる。これでAlchemyAPIを利用する準備は完了。
Kobito.ksevoH.png

4.Swiftから画像をアップロードして、AlchemyAPIのImage Taggingを利用する

ごにょごにょ苦労したんですが、下記で画像アップロード&呼出が成功しました(戻り値はJSON形式の例、XMLも可)。Image TagginのAPIドキュメントはこちら。url-encodedで投げろというのがイマイチわかりにくかったのですが、"x-www-form-urlencoded"をヘッダーにつけて、bodyにバイナリを直接入れるリクエストとなるようです。

    let image = UIImage(named: "yosemite-meadows.png")
    getImageTag(image!)

    func getImageTag(image:UIImage){
        let apiKey = "xxx-xxx-xxx-xxx-xxx"//ここを先の手順で取得したapikeyに変更
        let url = "https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&outputMode=json&apikey=" + apiKey
        let myURL = NSURL(string: url)!
        let request = NSMutableURLRequest(URL: myURL)
        request.HTTPMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        let imageData = UIImagePNGRepresentation(image)
        request.HTTPBody = imageData!
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            // Your completion handler code here
            if let error = error {
                print("error: \(error)")
            }
            print(response)
            print(NSString(data: data!, encoding: NSUTF8StringEncoding))
        }
        task.resume()
    }

上記コードの戻り値はこんな感じ

//response
Optional(<NSHTTPURLResponse: 0x7fff32c0de00> { URL: https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&outputMode=json&apikey=d3a529b15ac9ebe550a51006815bf7a4xxxxxxxxx } { status code: 200, headers {
    "Access-Control-Allow-Origin" = "*";
    "Cache-Control" = "no-cache";
    Connection = "keep-alive";
    "Content-Length" = 473;
    "Content-Type" = "application/json";
    Date = "Sun, 29 Nov 2015 15:17:02 GMT";
    Server = nginx;
    "X-AlchemyAPI-CurrentVersion" = "12.22";
    "X-AlchemyAPI-Key" = d3a529b15ac9ebe550a51006815xxxxxxxx;
    "X-AlchemyAPI-Params" = "sentiment=0&knowledgeGraph=0&detectedLanguage=unknown&submitLanguage=detect";
    "X-AlchemyAPI-Status" = OK;
    "X-AlchemyAPI-Total-Transactions" = 4;
} })
//data
Optional({
    "status": "OK",
    "usage": "By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html",
    "url": "",
    "totalTransactions": "4",
    "imageKeywords": [
        {
            "text": "nature",
            "score": "0.916827"
        },
        {
            "text": "yosemite",
            "score": "0.900249"
        }
    ]
}
)

参考までにcurlやでリクエストするときは、下記コマンドで試せる。

//curl
curl --data-binary @YOUR_IMAGE.png "https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&apikey=d3a529b15ac9ebe550a5100xxxxxx"
//wget 未検証
wget -qO- --post-file YOUR_IMAGE.png 

終わりに

リクエスト投稿しか試せていないけど、カメラで撮った写真をタグ付けるとか、アルバムから取得した画像を自動分類するとかできればちょっと便利なものができそう。本当はAlamofireで書きたかったのでそこは宿題。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away