Azure AI Vision のビデオ検索 APIを試してみた

こんにちは。Azure ビジネス部の岩上です。
この記事は「[NEXTSCAPE Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nextscape)」の16日目です。


# はじめに
Azure AI Vision のVideo検索（Preview）がある事は知っていましたが、どんな検索が出来るのか気になっていましたので今回のアドベントカレンダーのネタにできるかと思い実際に触ってみました。
執筆時はPreview機能の為、あくまで参考としてください。

# 結論
先に結論を記載します。
抽象度の高い質問や、検索は映像か音声を明示的に指定しないと余計な検索結果がでてしまい欲しい結果は出せません。
最低限以下サンプルの様に動画登録時のメタデータや、検索時に使用する機能Vision or Speech は指定した方がよさそうでした。

また、それでも多くの検索結果が帰ってきてしまう場合は、
レスポンスにrelevance（関連度）があるので、閾値に満たないものは除外する様な実装をした方がよさそうです。

```
curl --location 'https://<YOUR_ENDPOINT_URL>/computervision/retrieval/indexes/my-video-index:queryByText?api-version=2023-05-01-preview' \
--header 'Ocp-Apim-Subscription-Key: <YOUR_SUBSCRIPTION_KEY>' \
--header 'Content-Type: application/json' \
--data '{
  "queryText": "走っている人",
  "filters": {
    "stringFilters": [
      {
        "fieldName": "remarks",
        "values": [
          "first-half"
        ]
      }
    ],
    "featureFilters": ["Vision"]
  }
}'
```
- filters
  動画のIndex登録時に設定したメタデータの検索が出来る
- featureFilters
  Vision、Speech どちらの検索かを限定できる。


# 準備
[MSのDocument](https://learn.microsoft.com/ja-jp/azure/ai-services/computer-vision/how-to/video-retrieval) を参考にIndexを作って、動画を登録していきます。
また、今回はサンプルとして用意した動画は、ホームビデオで撮影した子供のテニスの習い事動画を使用しました。

### Indexの作成
```
  curl --location --request PUT 'https://<YOUR_ENDPOINT_URL>/computervision/retrieval/indexes/my-video-index?api-version=2023-05-01-preview' \
  --header 'Ocp-Apim-Subscription-Key: <YOUR_SUBSCRIPTION_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "metadataSchema": {
        "language": "ja",
        "fields": [
            {
                "name": "sport-name",
                "searchable": false,
                "filterable": true,
                "type": "string"
            },
            {
                "name": "remarks",
                "searchable": false,
                "filterable": true,
                "type": "string"
            }
        ]
    },
    "features": [
        {
            "name": "vision",
            "domain": "generic"
        },
        {
            "name": "speech"
        }
    ]
  }'
```
  
### Indexにビデオ ファイルを追加する
```
curl --location --request PUT 'https://<YOUR_ENDPOINT_URL>/computervision/retrieval/indexes/my-video-index/ingestions/my-ingestion?api-version=2023-05-01-preview' \
--header 'Ocp-Apim-Subscription-Key: fad535807adc4a87acb8f97f38b58ae6' \
--header 'Content-Type: application/json' \
--data '{
  "videos": [
    {
      "mode": "add",
      "documentId": "MOV_0127",
      "documentUrl": "https://<YOUR_ENDPOINT_URL>/<YOUR_BLOB_CONTAINER>/MOV_0127.mp4?<SAS Token>",
      "metadata": {
        "sport-name": "tennis",
        "remarks": "latter-half"
      }
    },
    {
      "mode": "add",
      "documentId": "MOV_0126",
      "documentUrl": "https://stadvuse.blob.core.windows.net/<YOUR_BLOB_CONTAINER>/MOV_0126.mp4?<SAS Token>",
      "metadata": {
        "sport-name": "tennis",
        "remarks": "first-half"
      }
    }
  ]
}'
```
Index作成時に定義したmetadataSchemaのfieldsの内容を、動画毎にメタデータとして登録できます。

# 検索
Indexの作成から、動画の登録までサクッと出来てしまいますね。
それでは実際に検索してみたいと思います。

```
curl --location 'https://<YOUR_ENDPOINT_URL>/computervision/retrieval/indexes/my-video-index:queryByText?api-version=2023-05-01-preview' \
--header 'Ocp-Apim-Subscription-Key: <YOUR_SUBSCRIPTION_KEY>' \
--header 'Content-Type: application/json' \
--data '{
  "queryText": "走っている人"
}'
```
## 結果
※レスポンスは一部抜粋しています。
```
{
    "value": [
        {
            "documentId": "MOV_0126",
            "documentKind": "SpeechTextInterval",
            "start": "00:00:11.4800000",
            "end": "00:00:12.1600000",
            "best": "00:00:11.4800000",
            "relevance": 0.24782827496528625
        },
        {
            "documentId": "MOV_0126",
            "documentKind": "VideoInterval",
            "start": "00:02:16.0030000",
            "end": "00:02:39.0260000",
            "best": "00:02:29.0160000",
            "relevance": 0.24688373506069183
        },

```
上記の様に動画のタイムラインとrelevance（関連度）が帰ってきます。
検索結果のタイムラインから動画を見てみるとあまり正しく検索出来ていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624624/296d3157-625f-234d-a974-690521fb1a13.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624624/04063d3b-eba7-6761-1f7e-0da7241a6d97.png)
※Qiitaアップ様にボカシ加工をしています。

結果をよく見てみると、`"documentKind"`があります。
一つ目の結果`"documentKind": "SpeechTextInterval"`は、音声から走っている人がいると判断されたようです。

そこで、[APIのリファレンス](https://learn.microsoft.com/ja-jp/azure/ai-services/computer-vision/reference-video-search#searchfiltersmodel)を見ると、
`"featureFilters": ["Vision"]`で検索時に機能を選択できるとありましたので、設定したところ検査結果から消せました。

今回使用した動画が悪く、スクリーンショットだと表現ができないので結果は割愛しますが、`"featureFilters": ["Speech"]`にして、『拍手』や、『大きい声』で検索した時、応援してるシーンのタイムラインが返却される事も確認しています。

# 纏め
今回検索APIでは以下ができる事がわかりました。
- 検索する時は、検索するテキストによっては機能を絞らないと、余計な結果が帰ってきてしまう。
- 映像、音声などで絞って検索する事ができる
- Index作成時に、メタデータを定義する事ができる
- Indexに動画を登録する時に動画毎にメタデータを登録する事ができ、それを使用してフィルタする事ができる。
- レスポンスにrelevance(関連度)が帰ってくるので、その値を評価する事ができる

他にも色々設定できるパラメータはありますが、使用した動画データが悪かったせいか、結果にあまり差が出なかった為、本記事はここまでとしたいと思います。