Vision APIとナレッジグラフの検索で画像認識対象をより深く理解する(Google Knowledge Graph Search API)

本記事では、Vision APIのランドマーク検出、ロゴ検出、ラベル検出から得られる認識対象の情報からGoogle Knowledge Graph Search APIを利用して、より詳細な情報を得る流れを、具体的な例とともに見ていきます。

【目次】

[1]はじめに

Google Vision APIを利用すると、与えられた画像に対するラベリング、顔やランドマークの検出、光学式文字認識(OCR)などができます。

このうち、「ランドマーク検出」、「ロゴ検出」、「ラベル検出」、「テキスト検出(OCR)」の機能には、検出結果にGoogleのナレッジグラフ検索に使える情報(エンティティID)に関するフィールドを持っています。

ここでGoogleのナレッジグラフとは、Google検索を行ったときに表示される情報ボックス(ナレッジパネル:PC等では検索結果の右側に表示される情報)の元になる情報のデータベースのようなものです。
(詳細については、記事『Googleのナレッジグラフ検索APIを使ってみる(Google Knowledge Graph Search API)』を参照して下さい。)

Vision APIの検出結果とGoogleのナレッジグラフを組み合わせれば、検出対象のより詳しい情報が得られて、より深く認識対象を理解できるかもしれません。

そこで本記事では、このVision APIの検出結果からGoogleのナレッジグラフを検索することで、より詳細な認識対象の情報を得る流れを、具体的な例とともに見ていきます。

[2]Vision APIとGoogle Knowledge Graph Search APIの連携

(1)連携方法の概要

Vision APIの機能のうち、「ランドマーク検出」、「ロゴ検出」、「ラベル検出」、「テキスト検出(OCR)」は、画像に対する検出結果として EntityAnnotation 型のデータのリストが得られます。

このEntityAnnotationには、midというフィールドがあり、以下のように説明されています。
  • mid
    • Opaque entity ID. Some IDs may be available in Google Knowledge Graph Search API.

つまり、midの値は、Google Knowledge Graph Search API に利用できるエンティティIDということです。

具体的には、Google Knowledge Graph Search API の ids パラメータに mid の値を設定してAPIを呼び出すことで、Google Knowledge Graphが持っている情報が得られます。

(注意)
Vision APIの「テキスト検出(OCR)」機能も上記  mid フィールドを持っていますが、いままでの経験上、mid フィールドに値が設定された経験が無いので、OCRでは mid フィールドは未使用フィールドかもしれません。このため、本記事でもOCRの例は扱っていません。(記事『Vision API OCR事始め(3):textAnnotations』もご参照ください。)

(追記:2021/8/11)
Vision APIの「テキスト検出(OCR)」で抽出したテキストからナレッジグラフの情報を取得したい場合は、抽出したテキストに対して Google Natural Language API のエンティティ分析を行うことになると思います。以下の記事を書きましたので参考にしてください。

(2)本記事の実行例について

本記事では、技術的詳細は割愛して、Vision APIで得られる情報(mid)と、Google Knowledge Graph Search APIから得られる情報を確認しています。

画像のサンプルは、GoogleのVision APIのドキュメントサンプルにある画像を利用します。
この画像に対して以下の手順を実行しています、
  1. Vision APIを利用して画像から情報を検出し、midフィールドの内容を得る。
  2. ブラウザからGoogleのナレッジグラフを検索して結果を確認する。

この手順にしたがって[3]以降で実行結果を書いています。
各実験例毎にドキュメントと画像のURLを記載していますので、まずはドキュメントにある画像を見てVision APIの認識結果を見て頂くのがよいと思います。

実際に試してみる場合は、以下の情報を参考にしてください。

①画像サンプルのダウンロードについて

本記事の画像データはGoogle Cloud Storageで公開されています(各実験例毎に画像のURLを記載しています)。もし画像データをPC等にダウンロードしたい場合は、gsutilを利用するのが便利だと思います。
gsutilの使い方などについては、記事『Colaboratory環境でGoogle Cloud Storage(GCS)と連携する(gsutil,gcsfuse)』を参考にしてください。

②Vision APIの呼び出し

Vision APIを利用するためにはGCP(Google Cloud Platform)での準備が必要です。
そして本記事ではPythonクライアントライブラリを利用してVision APIの各種検出機能を利用しています。(「pip install --upgrade google-cloud-vision」でインストールできます。また、認証情報として、サービスアカウントの秘密鍵ファイル(JSONファイル)を環境変数(GOOGLE_APPLICATION_CREDENTIALS)に設定します。)

Vision API の準備とPythonクライアントライブラリについては、必要に応じて以下の記事などを参考にしてください。(本記事の内容は Google Colaboratoryで動作確認しています。)

また、Vision APIのEntityAnnotation 型のデータ構造については、以下の記事も参考にしてください。

③ナレッジグラフ検索について

Google Knowledge Graph Search APIは無料で利用できますが、GCP(Google Cloud Platform)での準備が必要です。(APIの有効化とAPIキーの取得)
そして本記事ではGoogle Knowledge Graph Search APIをブラウザから利用した結果を貼り付けています。

ナレッジグラフの概要と検索APIをブラウザから利用する方法については以下の記事を参考にしてください。

[3]ランドマーク検出の例

(1)Vision APIによる検出

ランドマーク検出は「よく知られている自然のランドマークや人工建造物を画像から検出」するものです。

上記ドキュメントにあるサンプル画像で試してみます。
  • 画像のURL:gs://cloud-samples-data/vision/landmark/st_basils.jpeg

実行コード
from google.cloud import vision
client = vision.ImageAnnotatorClient()
landmark_response = client.landmark_detection(
    {'source':{'image_uri':'gs://cloud-samples-data/vision/landmark/st_basils.jpeg'}})
for i, ea in enumerate(landmark_response.landmark_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Saint Basil's Cathedral,mid=/m/014lft
Entity[1]:description=St. Basil's Cathedral,mid=/m/014lft

descriptionが「Saint Basil's Cathedral」と「St. Basil's Cathedral」の2つのエンティティを検出しています。
なぜか「Saint」と「St.」の違いがありますが、midは同じ「/m/014lft」が得られます。midが同じという事は、名前は微妙に違いますが、2つは同じものであると考えられます。

実際に、Google検索で「Saint Basil's Cathedral」と「St. Basil's Cathedral」を検索すると、どちらも右側に「聖ワシリイ大聖堂」の情報が表示されます。(検索結果や順位は微妙に違いますが、ほぼ同じような結果だと思います。)

この例の場合、知っている人は「Saint」と「St.」を同じことを意味していると考えると思いますが、一般的には文字が異なると同一性の判定は難しいと思います。
その点で、上記の例は mid が同一性の判定に利用できる例になっていると思います。

ちなみに、「Saint Basil's Cathedral」と「St. Basil's Cathedral」を認識した領域(bounding_poly)が微妙に異なるところも面白いです。今回の結果は、Googleの学習データのラベル付けの問題なのでしょうか。。。

(2)ナレッジグラフ検索

midの値(/m/014lft)をidsパラメータに設定して、日本語と英語の両方で情報を取得してみます。([APIキー]は、GCPから取得したAPIキーに置き換えてください。)

ブラウザに指定するURL
https://kgsearch.googleapis.com/v1/entities:search?key=[APIキー]&ids=/m/014lft&languages=ja&languages=en

検索結果
{
  "@context": {
    "kg": "http://g.co/kg",
    "EntitySearchResult": "goog:EntitySearchResult",
    "@vocab": "http://schema.org/",
    "detailedDescription": "goog:detailedDescription",
    "goog": "http://schema.googleapis.com/",
    "resultScore": "goog:resultScore"
  },
  "@type": "ItemList",
  "itemListElement": [
    {
      "resultScore": 0,
      "result": {
        "url": "http://www.shm.ru/pokrovskiy.html",
        "name": [
          {
            "@value": "聖ワシリイ大聖堂",
            "@language": "ja"
          },
          {
            "@language": "en",
            "@value": "St. Basil's Cathedral"
          }
        ],
        "@type": [
          "Thing",
          "LandmarksOrHistoricalBuildings",
          "Place",
          "CivicStructure",
          "PlaceOfWorship",
          "TouristAttraction",
          "Cemetery",
          "Museum"
        ],
        "detailedDescription": [
          {
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License",
            "articleBody": "聖ワシリイ大聖堂はロシアの首都、モスクワの赤の広場に立つロシア正教会の大聖堂。正式名称は「堀の生神女庇護大聖堂」。\n「聖ワシリー大聖堂」「聖ヴァシーリー大聖堂」「聖ワシーリー寺院」とも日本では表記される。\n1551年から1560年にかけて、イヴァン4世が、カザン・ハーンを捕虜とし勝利したことを記念して建立した。ロシアの聖堂でもっとも美しい建物のひとつと言われる。1990年にユネスコの世界遺産に登録された。\nゲームソフト等で有名なテトリスでは、ロシア文化をイメージとした背景や音楽等がよく用いられており、聖ワシリイ大聖堂もしばしば背景画像やパッケージとして使われている。\n「クレムリンの聖ワシリイ大聖堂」といった説明がされることもあるが、大聖堂はクレムリンの城壁の内側には位置していないため誤りである。聖ワシリイ大聖堂が位置する赤の広場はクレムリンの城壁の外側にある。",
            "url": "https://ja.wikipedia.org/wiki/%E8%81%96%E3%83%AF%E3%82%B7%E3%83%AA%E3%82%A4%E5%A4%A7%E8%81%96%E5%A0%82",
            "inLanguage": "ja"
          },
          {
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License",
            "inLanguage": "en",
            "url": "https://en.wikipedia.org/wiki/Saint_Basil's_Cathedral",
            "articleBody": "The Cathedral of Vasily the Blessed, commonly known as Saint Basil's Cathedral, is an Orthodox church in Red Square of Moscow, and is one of the most popular cultural symbols of Russia. "
          }
        ],
        "description": [
          {
            "@value": "ロシア モスクワの教会",
            "@language": "ja"
          },
          {
            "@language": "en",
            "@value": "Cathedral in Moscow, Russia"
          }
        ],
        "@id": "kg:/m/014lft"
      },
      "@type": "EntitySearchResult"
    }
  ]
}

この結果から、少なくとも以下のことが分かります。
  • ナレッジグラフに登録されている名前は、英語で「St. Basil's Cathedral」、日本語で「聖ワシリイ大聖堂」となっています。
    • Vision APIで検出した2つの名前のどれを利用するかのヒントとして利用できるかもしれません。
  • 本家のURLがわかります。(但し、現在はリンク切れのようです。。。)
  • @typeの値から検出したランドマークがどのようなものかを知る(例えば分類などの)ヒントになるかもしれません。
    • 例えば、これは自然のランドマークではなく人工建造物とわかりますし、礼拝堂であることもわかります。
  • WikipediaのURLや英語と日本語の要約が得られます。
    • なぜか英語の説明はあっさりしているのに、日本語の説明は少々詳しい?ですね(笑)。

[4]ロゴ検出の例

(1)Vision APIによる検出

ロゴ検出は「よく知られている商品のロゴを画像から検出」するものです。

上記ドキュメントにあるサンプル画像で試してみます。
  • 画像のURL:gs://cloud-samples-data/vision/logo/google_logo.jpg

実行コード
from google.cloud import vision
client = vision.ImageAnnotatorClient()
logo_response = client.logo_detection(
    {'source':{'image_uri':'gs://cloud-samples-data/vision/logo/google_logo.jpg'}})
for i, ea in enumerate(logo_response.logo_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Google,mid=/m/045c7b

あまり面白くないサンプルといわれそうですが、それはそれとして、ちゃんとGoogleのロゴが検出されて、そのmidは「/m/045c7b」となっています。

(2)ナレッジグラフ検索

midの値(/m/045c7b)をidsパラメータに設定して、日本語と英語の両方で情報を取得してみます。([APIキー]は、GCPから取得したAPIキーに置き換えてください。)

ブラウザに指定するURL
https://kgsearch.googleapis.com/v1/entities:search?key=[APIキー]&ids=/m/045c7b&languages=ja&languages=en

検索結果
{
  "@context": {
    "EntitySearchResult": "goog:EntitySearchResult",
    "@vocab": "http://schema.org/",
    "detailedDescription": "goog:detailedDescription",
    "resultScore": "goog:resultScore",
    "goog": "http://schema.googleapis.com/",
    "kg": "http://g.co/kg"
  },
  "@type": "ItemList",
  "itemListElement": [
    {
      "resultScore": 0,
      "@type": "EntitySearchResult",
      "result": {
        "url": "https://www.google.com/",
        "name": [
          {
            "@value": "Google",
            "@language": "ja"
          },
          {
            "@language": "en",
            "@value": "Google"
          }
        ],
        "@id": "kg:/m/045c7b",
        "@type": [
          "Organization",
          "Thing",
          "Corporation"
        ],
        "detailedDescription": [
          {
            "url": "https://ja.wikipedia.org/wiki/Google",
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License",
            "articleBody": "Google LLCは、インターネット関連のサービスと製品に特化したアメリカ合衆国の企業 。世界規模の検索エンジン、オンライン広告、クラウドコンピューティング、ソフトウェア、ハードウェア関連の事業がある。アメリカ合衆国の主要なIT企業で、GAFA、FAANGの一つ。",
            "inLanguage": "ja"
          },
          {
            "url": "https://en.wikipedia.org/wiki/Google",
            "articleBody": "Google LLC is an American multinational technology company that specializes in Internet-related services and products, which include online advertising technologies, a search engine, cloud computing, software, and hardware. ",
            "inLanguage": "en",
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License"
          }
        ],
        "description": [
          {
            "@language": "ja",
            "@value": "企業"
          },
          {
            "@value": "Technology company",
            "@language": "en"
          }
        ]
      }
    }
  ]
}

この結果から、少なくとも以下のことが分かります。
  • ナレッジグラフに登録されている名前は、英語も日本語も「Google」で同じです。
    • Googleは日本語名もカタカナ表記ではなく英語表記のままですが、カタカナ表記になる場合は何が基準なのか、私は理解していません。。。
  • URLがわかります。
  • @typeの値から検出したロゴの対象である「Google」は、企業を表していることが分かります。
    • 商品のロゴというより企業のロゴを検出したというヒントになるかもしれません。
  • Wikipediaの英語と日本語の要約が得られます。
    • 今回は「聖ワシリイ大聖堂」と違って、英語と日本語の説明が殆ど同じです。一方、説明(description)の値は、日本語では「企業」であるのに対して、英語は「Technology company」と少し突っ込んだ説明になっています(笑)。

[5]ラベル検出の例

(1)Vision APIによる検出

ラベル検出は「一般的な物体、場所、活動、動物の種類、商品などを識別」するものです。

上記ドキュメントにあるサンプル画像で試してみます。
  • 画像のURL:gs://cloud-samples-data/vision/label/setagaya.jpeg

実行コード
from google.cloud import vision
client = vision.ImageAnnotatorClient()
label_response = client.label_detection(
    {'source':{'image_uri':'gs://cloud-samples-data/vision/label/setagaya.jpeg'}})
for i, ea in enumerate(label_response.label_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Bicycle,mid=/m/0199g
Entity[1]:description=Tire,mid=/m/0h9mv
Entity[2]:description=Wheel,mid=/m/083wq
Entity[3]:description=Automotive lighting,mid=/m/0768fx
Entity[4]:description=Infrastructure,mid=/m/017kvv
Entity[5]:description=Bicycle wheel,mid=/m/01bqk0
Entity[6]:description=Building,mid=/m/0cgh4
Entity[7]:description=Mode of transport,mid=/m/079bkr
Entity[8]:description=Electricity,mid=/m/02lts
Entity[9]:description=Vehicle,mid=/m/07yv9

実行結果を見ると「自転車」に関するものが多いです。自転車に関連して、車輪のような構成部品や一般的な乗り物の概念まで検出しています。Vision APIは、かなりの自転車好きなのでしょうか(笑)。元の画像を見なければ、自転車の画像の検出結果と勘違いしそうです。

元の画像は、なかなか味のある画像だと思いますが、正直なところ、私はGoogleの検出結果を見るまで自転車をほとんど意識してませんでした(笑)。その意味では凄いのですが。。。

実は、デフォルトの検出数だと上記の通りですが、後に書いている通り、最大検出数を増やすと印象が異なってきます。

(2)モデルのアップグレードによる違いや最大検出数など

Vision APIのリリースノート(https://cloud.google.com/vision/docs/release-notes?hl=ja)によると、ラベル検出は2020年12月4日にモデルのアップグレードが行われたようです。記事を書いている時点では、APIのパラメータに"builtin/legacy"を指定するとアップグレード前のモデルを試すことができるようです。

本記事の目的はラベル検出の内容については深く考えませんが、モデルのバージョンアップでどのように変わるものか興味があったので試してみました。

実行コード
from google.cloud import vision
client = vision.ImageAnnotatorClient()
legacy_label_response = client.annotate_image(
    {'image':{'source':{'image_uri':'gs://cloud-samples-data/vision/label/setagaya.jpeg'}},
    'features':[{'type_': vision.Feature.Type.LABEL_DETECTION, 'model':'builtin/legacy'}]})

for i, ea in enumerate(legacy_label_response.label_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Street,mid=/m/01c8br
Entity[1]:description=Snapshot,mid=/m/06pg22
Entity[2]:description=Town,mid=/m/0dx1j
Entity[3]:description=Night,mid=/m/01d74z
Entity[4]:description=Alley,mid=/m/01lwf0
Entity[5]:description=Road,mid=/m/06gfj
Entity[6]:description=Building,mid=/m/0cgh4
Entity[7]:description=City,mid=/m/01n32

モデルが変わると、認識結果もかなり変わるようです。

一番大きな違いは、モデルのアップグレードによって、Vision APIが自転車好きになったというところでしょうか(笑)。
それはともかく、旧モデルでは自転車は全く認識されていないので、モデルのアップグレードによって認識対象が広がった感じを受けました。

そう考えると、いい感じで認識されていた概念が全く認識されなくなるのも変だと思い、新モデルで検出の最大数を増やして試してみました(今回は50を指定)。

実行コード
from google.cloud import vision
client = vision.ImageAnnotatorClient()
label_response_max50 = client.annotate_image(
    {'image':{'source':{'image_uri':'gs://cloud-samples-data/vision/label/setagaya.jpeg'}},
    'features':[{'type_': vision.Feature.Type.LABEL_DETECTION, 'max_results':50}]})
for i, ea in enumerate(label_response_max30.label_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Bicycle,mid=/m/0199g
Entity[1]:description=Tire,mid=/m/0h9mv
Entity[2]:description=Wheel,mid=/m/083wq
Entity[3]:description=Automotive lighting,mid=/m/0768fx
Entity[4]:description=Infrastructure,mid=/m/017kvv
Entity[5]:description=Bicycle wheel,mid=/m/01bqk0
Entity[6]:description=Building,mid=/m/0cgh4
Entity[7]:description=Mode of transport,mid=/m/079bkr
Entity[8]:description=Electricity,mid=/m/02lts
Entity[9]:description=Vehicle,mid=/m/07yv9
Entity[10]:description=Neighbourhood,mid=/m/0180xr
Entity[11]:description=Public space,mid=/m/01lqfm
Entity[12]:description=Road,mid=/m/06gfj
Entity[13]:description=City,mid=/m/01n32
Entity[14]:description=Midnight,mid=/m/01kv7h
Entity[15]:description=Metropolitan area,mid=/m/0j_s4
Entity[16]:description=Gas,mid=/m/037xy
Entity[17]:description=Metropolis,mid=/m/056mk
Entity[18]:description=Market,mid=/m/09y4pm
Entity[19]:description=Electronic signage,mid=/m/0522cz4
Entity[20]:description=Urban area,mid=/m/039jbq
Entity[21]:description=Signage,mid=/m/0bkqqh
Entity[22]:description=Alley,mid=/m/01lwf0
Entity[23]:description=Neon,mid=/m/025s4r0
Entity[24]:description=Darkness,mid=/m/01kyr8
Entity[25]:description=Motor vehicle,mid=/m/012f08
Entity[26]:description=Street,mid=/m/01c8br
Entity[27]:description=Lane,mid=/m/033j3c
Entity[28]:description=Night,mid=/m/01d74z
Entity[29]:description=Mixed-use,mid=/m/0c1vxg

今度は30個の概念が検出されています。アップグレード前に検出していた概念をほとんど含んでいます。さらに、SignageやNeonといったものも検出されています。

アップグレードによって、単なる自転車好きになった、ということではなくて、とても安心しました(笑)。同時に凄いと思いました。
とはいえ、最大数の設定をうまく設定しないと微妙な結果になってしまう気もしたりして。。。

ちなみに、アップグレード前のモデルでは最大値を増やしても結果は変わりませんので、アップグレードによる性能向上を感じました。

(3)ラベル検出とランドマーク検出、ロゴ検出

ラベル検出が「一般的な物体、場所、活動、動物の種類、商品などを識別」するものならば、ランドマークだとかロゴという概念も識別できるものなのか、興味がわきました。
これも本記事の主題とは異なりますが、ついでに試してみることにしました。

①ランドマーク検出のサンプル画像にラベル検出を行ってみる

最大検出数を50としてラベル検出を行ってみます。
from google.cloud import vision
client = vision.ImageAnnotatorClient()
landmark_label_response = client.annotate_image(
    {'image':{'source':{'image_uri':'gs://cloud-samples-data/vision/landmark/st_basils.jpeg'}},
    'features':[{'type_': vision.Feature.Type.LABEL_DETECTION, 'max_results':50}]})
for i, ea in enumerate(landmark_label_response.label_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Cloud,mid=/m/0csby
Entity[1]:description=Sky,mid=/m/01bqvp
Entity[2]:description=Window,mid=/m/0d4v4
Entity[3]:description=Temple,mid=/m/08g_yr
Entity[4]:description=Tree,mid=/m/07j7r
Entity[5]:description=Building,mid=/m/0cgh4
Entity[6]:description=City,mid=/m/01n32
Entity[7]:description=Facade,mid=/m/01x314
Entity[8]:description=Temple,mid=/m/0cx45
Entity[9]:description=Dome,mid=/m/016br2
Entity[10]:description=Finial,mid=/m/03jnkr
Entity[11]:description=Dome,mid=/m/0c85fd
Entity[12]:description=Spire,mid=/m/01c6yl
Entity[13]:description=Byzantine architecture,mid=/m/01sqnx
Entity[14]:description=Church,mid=/m/01wb7
Entity[15]:description=Steeple,mid=/m/051rmm
Entity[16]:description=Symmetry,mid=/m/0f28m
Entity[17]:description=Holy places,mid=/m/065zs54
Entity[18]:description=Plant,mid=/m/05s2s
Entity[19]:description=Place of worship,mid=/m/02nvjx
Entity[20]:description=Tourism,mid=/m/07bxq
Entity[21]:description=Historic site,mid=/m/07yr8h
Entity[22]:description=Chapel,mid=/m/0173tc
Entity[23]:description=Event,mid=/m/081pkj
Entity[24]:description=Stock photography,mid=/m/036jvk
Entity[25]:description=Turret,mid=/m/01xgbj
Entity[26]:description=Classical architecture,mid=/m/0dvh9
Entity[27]:description=Medieval architecture,mid=/m/01ht1r
Entity[28]:description=Tourist attraction,mid=/m/0pgl9
Entity[29]:description=Roof,mid=/m/06hyd
Entity[30]:description=Monastery,mid=/m/0cfkj
Entity[31]:description=Convent,mid=/m/0_ch6
Entity[32]:description=Shrine,mid=/m/02cwf_
Entity[33]:description=Art,mid=/m/0jjw
Entity[34]:description=National historic landmark,mid=/m/0245zn
Entity[35]:description=Cathedral,mid=/m/0cfs8
Entity[36]:description=Parish,mid=/m/05wqv


「National historic landmark」、「Place of worship」など、いろいろランドマークの匂いがする概念が多く検出されるようで、凄いです。

但し、'max_results'を指定しない場合は、上記のEntity[9]までしか得られないので、ランドマークっぽい概念を含んでいることは分かりにくいです。

また、ランドマークっぽい概念を含むことは分かりますが、ラベル検出では、それが「聖ワシリイ大聖堂」まではわかりません。

このため、ラベル検出を行った結果を詳しく知ろうとすると、さらにランドマーク検出を行ってみる、という流れが考えられます。
(Vision APIではラベル検出とランドマーク検出を同時に行うこともできますので、オーバーヘッドを減らすことができます。但し、ラベル検出とランドマーク検出は別々に課金が発生します。)

②ロゴ検出のサンプル画像にラベル検出を行ってみる

最大検出数を50としてラベル検出を行ってみます。
from google.cloud import vision
client = vision.ImageAnnotatorClient()
logo_label_response = client.annotate_image(
    {'image':{'source':{'image_uri':'gs://cloud-samples-data/vision/logo/google_logo.jpg'}},
    'features':[{'type_': vision.Feature.Type.LABEL_DETECTION, 'max_results':50}]})
for i, ea in enumerate(logo_label_response.label_annotations):
  print("Entity[{}]:description={},mid={}".format(i, ea.description,ea.mid))

実行結果
Entity[0]:description=Azure,mid=/m/03jn2m
Entity[1]:description=Orange,mid=/m/0jc_p
Entity[2]:description=Purple,mid=/m/09ggk
Entity[3]:description=Pink,mid=/m/01fklc
Entity[4]:description=Font,mid=/m/03gq5hm
Entity[5]:description=Wall,mid=/m/09qqq
Entity[6]:description=Ceiling,mid=/m/03gfsp
Entity[7]:description=Magenta,mid=/m/0ckc5
Entity[8]:description=Electric blue,mid=/m/02vwbzz
Entity[9]:description=Event,mid=/m/081pkj
Entity[10]:description=Space,mid=/m/06wqb
Entity[11]:description=Logo,mid=/m/0dwx7
Entity[12]:description=Display device,mid=/m/029zz6
Entity[13]:description=Graphics,mid=/m/021sdg
Entity[14]:description=Entertainment,mid=/m/02jjt
Entity[15]:description=Visual effect lighting,mid=/m/0h8n2vs
Entity[16]:description=Signage,mid=/m/0bkqqh
Entity[17]:description=Room,mid=/m/06ht1
Entity[18]:description=Brand,mid=/m/01cd9
Entity[19]:description=Advertising,mid=/m/011s0
Entity[20]:description=Neon,mid=/m/025s4r0
Entity[21]:description=Projection screen,mid=/m/06ycgh
Entity[22]:description=Graphic design,mid=/m/03c31
Entity[23]:description=Circle,mid=/m/01vkl
Entity[24]:description=Light fixture,mid=/m/08jpwt
Entity[25]:description=Multimedia,mid=/m/0541p
Entity[26]:description=Flooring,mid=/m/01c34b
Entity[27]:description=Gadget,mid=/m/02mf1n
Entity[28]:description=Visual arts,mid=/m/0p9xx
Entity[29]:description=Curtain,mid=/m/03rszm
Entity[30]:description=Night,mid=/m/01d74z

「Logo」の概念が検出されています。
但し、'max_results'を指定しない場合は、上記のEntity[9]までしか得られないので、対象が何なのかわかりにくいです。
また、ラベル検出では、それが「Google」ということまではわかりません。
このため、ラベル検出を行った結果を詳しく知ろうとすると、さらにロゴ検出を行ってみる、という流れが考えられます。
(Vision APIではラベル検出とロゴ検出も同時に行うこともできますので、オーバーヘッドを減らすことができます。但し、ラベル検出とロゴ検出は別々に課金が発生します。)

③モデルのアップグレードによる性能向上

ちなみに、ランドマークとロゴのサンプル画像に、「builtin/legacy」を指定すると、上記の例に比べるとランドマークやロゴを連想させる概念が少ないです。(例えば、「National historic landmark」や「Logo」という概念はありません。)
これらを見ても、アップグレードによる性能向上を感じました。

(4)ナレッジグラフ検索

ラベル検出は「一般的な物体、場所、活動、動物の種類、商品などを識別」するものなので、ナレッジグラフの@typesにあたるものを検出しているようなものと考えることができるように思います。
そういう意味では、ナレッジグラフ検索を行うことで、Wikipediaなどの説明テキストが得ることが典型的な利用例かもしれません。

以下は(1)のVision APIで検出されたラベルの一部をナレッジグラフで検索した例です。
(私には少しなじみが薄いものを2つだけを選びました。)

①description=Automotive lighting,mid=/m/0768fx

ブラウザに指定するURL
https://kgsearch.googleapis.com/v1/entities:search?key=[APIキー]&ids=/m/0768fx&languages=ja&languages=en

検索結果
{
  "@context": {
    "EntitySearchResult": "goog:EntitySearchResult",
    "goog": "http://schema.googleapis.com/",
    "resultScore": "goog:resultScore",
    "kg": "http://g.co/kg",
    "detailedDescription": "goog:detailedDescription",
    "@vocab": "http://schema.org/"
  },
  "@type": "ItemList",
  "itemListElement": [
    {
      "resultScore": 0,
      "@type": "EntitySearchResult",
      "result": {
        "@type": [
          "Thing"
        ],
        "@id": "kg:/m/0768fx",
        "detailedDescription": [
          {
            "url": "https://en.wikipedia.org/wiki/Automotive_lighting",
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License",
            "inLanguage": "en",
            "articleBody": "The lighting system of a motor vehicle consists of lighting and signalling devices mounted or integrated to the front, rear, sides, and in some cases the top of a motor vehicle. "
          }
        ],
        "name": [
          {
            "@language": "en",
            "@value": "Automotive lighting"
          }
        ]
      }
    }
  ]
}

②description=Mode of transport,mid=/m/079bkr

ブラウザに指定するURL
https://kgsearch.googleapis.com/v1/entities:search?key=[APIキー]&ids=/m/079bkr&languages=ja&languages=en

検索結果
{
  "@context": {
    "goog": "http://schema.googleapis.com/",
    "kg": "http://g.co/kg",
    "resultScore": "goog:resultScore",
    "@vocab": "http://schema.org/",
    "detailedDescription": "goog:detailedDescription",
    "EntitySearchResult": "goog:EntitySearchResult"
  },
  "@type": "ItemList",
  "itemListElement": [
    {
      "result": {
        "detailedDescription": [
          {
            "license": "https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License",
            "articleBody": "Means of transport is a term used to distinguish between different ways of transportation or transporting people or goods. The different modes of transport are air, water, and land transport, which includes Rails or railways, road and off-road transport. ",
            "url": "https://en.wikipedia.org/wiki/Mode_of_transport",
            "inLanguage": "en"
          }
        ],
        "@type": [
          "Thing"
        ],
        "name": [
          {
            "@value": "Mode of transport",
            "@language": "en"
          }
        ],
        "@id": "kg:/m/079bkr"
      },
      "@type": "EntitySearchResult",
      "resultScore": 0
    }
  ]
}

コメント

このブログの人気の投稿

VirtualBoxのスナップショット機能

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

Ubuntu/Colab環境でPDFファイルのページを画像化する(pdf2image、pdftoppm、pdftocairo)