Web Perception Toolkit を使用した画像検索

使いやすい現実世界でのインタラクティビティ。

Joe Medley
Joe Medley
ユーザーがカメラを使ってサイトを検索できたら便利だと思いませんか?次のような状況を想像してみてください。お客様のサイトは Razor McShaveyface です。お客様から、カミソリの替えのカートリッジを再注文する際に、適切なカートリッジを見つけられないというお問い合わせがありました。商品検索に適したキーワードを知らない。正直なところ、おそらくは決して実現しないでしょう。

必要がない場合はどうすればよいですか?スマートフォンのカメラをパッケージの UPC コードに向けると、サイトに適切なカートリッジと大きな赤い [再注文] ボタンが表示されたらどうでしょうか。

サイト上でカメラを活用できる他の方法を検討します。店頭での価格チェックをサポートするサイトがあるとします。美術館の展示物や歴史的標識に関する情報を取得するとします。ジオキャッシングや宝探しなどのゲームで、現実世界のランドマークを特定することを想像してみてください。

ウェブ パーセプション ツールキットを使用すると、このようなカメラベースのシナリオを実現できます。場合によっては、コードを記述せずにエクスペリエンスを作成することもできます。

仕組み

オープンソースの Web Perception Toolkit を使用すると、ウェブサイトにビジュアル検索を追加できます。デバイスのカメラ ストリームを、現実世界のオブジェクト(ここでは「ターゲット」と呼びます)をサイト上のコンテンツにマッピングする一連の検出機能に渡します。このマッピングは、サイトの構造化データ(JSON-LD)を使用して定義されます。このデータを使用して、カスタマイズ可能な UI に適切な情報を表示できます。

使い方を簡単に説明します。詳細については、スタートガイドツールキット リファレンスI/O サンドボックスのデモサンプルデモをご覧ください。

構造化データ

ツールキットは、カメラの視野内の任意のターゲットを検出できるわけではありません。認識するターゲットのリンクされた JSON データを指定する必要があります。このデータには、ユーザーに表示されるターゲットに関する情報も含まれます。

下記の画像のようなユーザー エクスペリエンスを作成するには、このデータのみが必要です。何も設定しない場合、Web Perception Toolkit はターゲットを特定し、データに提供された情報に基づいてカードを表示または非表示にします。アーティファクト マップのデモで、この方法を試してみてください。

デフォルトのインターフェースは、リンクされたデータのみを使用して使用できます。
デフォルト インターフェース。

<script> タグと "application/ld+json" MIME タイプを使用して、JSON リンクされたデータファイルをサイトに追加します。

<script type="application/ld+json" src="//path/to/your/sitemap.jsonld">

ファイル自体は次のようになります。

[
  {
    "@context": "https://schema.googleapis.com/",
    "@type": "ARArtifact",
    "arTarget": {
      "@type": "Barcode",
      "text": "012345678912"
    },
    "arContent": {
      "@type": "WebPage",
      "url": "http://localhost:8080/demo/artifact-map/products/product1.html",
      "name": "Product 1",
      "description": "This is a product with a barcode",
      "image": "http://localhost:8080/demo/artifact-map/products/product1.png"
    }
  }
]

ユーザー エクスペリエンス

デフォルトのユーザー エクスペリエンス以上のものを希望する場合はどうすればよいですか?このツールキットには、ライフサイクル イベント、それらのイベントを基にユーザー エクスペリエンスを作成するための Card オブジェクトと Button オブジェクト、カードのスタイルを簡単に設定する方法が用意されています。スタートガイドをベースにしたコードで、この仕組みを簡単に説明します。

最も重要なライフサイクル イベントは PerceivedResults です。これは、ターゲットが検出されるたびに発生します。ターゲットは、現実世界のオブジェクトや、バーコードや QR コードなどのマーカーにできます。

このイベントへの対応プロセスは、すでに説明した例外を除き、他のイベントの場合と同じです。イベントを実装しない場合、構造化データを使用してユーザー インターフェースが自動的に作成されます。この動作をオーバーライドするには、event.preventDefault() を呼び出してイベント ハンドラを開始します。

const container = document.querySelector('.container');
async function onPerceivedResults(event) {
  // preventDefault() to stop default result Card from showing.
  event.preventDefault();
  // Process the event.
}
window.addEventListener(PerceptionToolkit.Events.PerceivedResults, onPerceivedResults);

イベントについて詳しく見てみましょう。イベント自体には、検出されたマーカーとターゲット、および検出できなかったマーカーとターゲットの配列が含まれています。ワールド内でターゲットが検出されると、イベントがトリガーされ、検出されたオブジェクトが event.found に渡されます。同様に、ターゲットがカメラビューから通過すると、イベントが再び発生し、event.lost で失われたオブジェクトが渡されます。これにより、手やマーカーの動き(カメラを安定して保持していない、マーカーを落としたなど)を補正できます。

async function onPerceivedResults(event) {
  // preventDefault() to stop default result Card from showing
  event.preventDefault();
  if (container.childNodes.length > 0) { return; }
  const { found, lost } = event.detail;
  // Deal with lost and found objects.
}

次に、ツールキットで検出された内容に基づいて適切なカードを表示します。

async function onPerceivedResults(event) {
  event.preventDefault();
  if (container.childNodes.length > 0) { return; }
  const { found, lost } = event.detail;
  if (found.length === 0 && lost.length === 0) {
    // Object not found.
    // Show a card with an offer to show the catalog.
  } else if (found.length > 0) {
    // Object found.
    // Show a card with a reorder button.
  }
}

カードとボタンを追加するには、インスタンス化して親オブジェクトに追加するだけです。次に例を示します。

const { Card } = PerceptionToolkit.Elements;
const card = new Card();
card.src = 'Your message here.'
container.appendChild(card)'

最後に、全体の様子を示します。ユーザー エクスペリエンスに追加した便利な機能に注目してください。マーカーが見つかったかどうかにかかわらず、状況に応じて最も有用と思われるものにワンクリックでアクセスできるようにします。

async function onPerceivedResults(event) {
  // preventDefault() to stop default result Card from showing
  event.preventDefault();
  if (container.childNodes.length > 0) { return; }
  const { found, lost } = event.detail;
  const { ActionButton, Card } = PerceptionToolkit.Elements;
  if (found.length === 0 && lost.length === 0) {
    //Make a view catalog button.
    const button =  new ActionButton();
    button.label = 'View catalog';
    button.addEventListener('click', () => {
      card.close();
      //Run code to launch a catalog.
    });
    //Make a card for the button.
    const card = new Card();
    card.src = 'We wish we could help, but that\'s not our razor. Would you like to see our catalog?';
    card.appendChild(button);
    //Tell the toolkit it does not keep the card around
    // if it finds something it recognizes.
    card.dataset.notRecognized = true;
    container.appendChild(card);
  } else if (found.length > 0) {
    //Make a reorder button.
    const button = new ActionButton();
    button.label = 'Reorder';
    botton.addEventListener('click', () => {
      card.close();
      //Run code to reorder.
    })
    const card = new Card();
    card.src = found[0].content;
    card.appendChild(button);
    container.appendChild(card);
  }
}

カードの書式設定

Web Perception Toolkit には、デフォルトのスタイルシートでカードとボタンの書式設定が組み込まれています。ただし、独自のアイコンを簡単に追加できます。提供される Card オブジェクトと ActionButton オブジェクトには、組織のスタイルを外観に反映できる style プロパティが含まれています。デフォルトのスタイルシートを含めるには、ページに <link> 要素を追加します。

<link rel="stylesheet" href="//path/to/toolkit/styles/perception-toolkit.css">

まとめ

冒頭で述べたように、これは ウェブ認識ツールキットのすべてを網羅したものではありません。これで、ウェブサイトにビジュアル検索を追加するのがいかに簡単かがお分かりいただけたと思います。詳しくは、スタートガイドサンプルデモをご覧ください。ツールキットのドキュメントで、ツールキットの機能を確認してください。