マラソン大会のゼッケン認識を自動化したら手作業が半分になった話

バックエンドを担当しているエンジニアの @kasai です。
この記事は [フォトクリエイト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/photocreate) の 13日目です。

# プロローグ（長い）

フォトクリエイトでは東京マラソンやホノルルマラソンなど著名なマラソン大会から、参加者１万人規模の全国の各種マラソン大会で撮影の許可をいただいます。撮影許可をいただいたイベントではランナーの皆さんの写真を撮影し、スポーツ写真を専門に取り扱っている[オールスポーツコミュニティ](https://allsports.jp/) で販売しています。各種マラソン大会では複数人のカメラマンが各撮影スポットでカメラを構えて、ランナーの皆さんの写真をひたすら撮り続けています。そうして撮り上がった写真は一度のマラソン大会で数十万枚（特に参加者の多いマラソン大会では百万枚以上！）に及びます。

（オールスポーツコミュニティは[PDCAを回しながらtwitterを運用している話](https://qiita.com/yonekawa_a/items/754d1c0aa32298bf2cf0)にもあるように、ランナーの方からはオールスポーツという呼称で親しまれています。）

市民ランナーの皆さんにはこの数十万枚の写真の中から、ご自身の写真を探してご購入いただいてるのですねえ。

数十万枚からご自身の写真を探して・・

・・無理ですよね。

ということで、オールスポーツでは以前から「ナンバーカード（ゼッケン）検索」という機能を提供してます。ランナーの皆さんは胸にユニークになるゼッケン番号を付けて走っていますので、そのゼッケン番号で写真を検索できるようになっています。ゼッケン検索で出てくる枚数はタイミイングやゼッケンの見え具合によってまちまちなのですが、これでおよそ目視確認できる程度には一覧できるようになります。我ながら素晴らしいサービスですね。

ユーザとしては購入できて万事解決でおわるところなのですが・・

気になりますよね、**どうやって写真とゼッケン番号が紐付いているのか**。

お教えしましょう。

**全部手作業でした。**

数十万枚を１枚ずつ、ときには前後の写真と見比べながら、専用の管理画面でゼッケン番号をひたすら入力していく簡単なようで地獄のような作業が発生していました。その作業自体は提携企業の手作業部隊にお願いしていたのですが、およそ２日程度はかかってこの作業をしていただいていました。

この運用を長年に渡って行ってきたのですが、課題もいくつかありました。

- 手作業なのでどんなに気をつけてても間違える
- 提携企業が稼働する営業時間内でしか作業が依頼できない。
- 人手が限られている。

下２つに関しては要するに**スケールしない**って話ですね。例えば大型マラソン大会の日程が過剰に重なってしまったとしても、作業を依頼できる量は限られてしまいます。このあたりはオペレーションの担当者がスケジュールを調整するなどして上手くコントロールしていました。

オペレーションを担当する部署がこれらの課題を何とか自動化出来ないかと取り組んだ結果、令和の幕開けと共についにそれを実現できました。

# ゼッケン認識の自動化

自動化したゼッケン認識処理はディープラーニングを使っています。過去の膨大な写真データとゼッケン情報を元にしてます。余談ですが当社は過去に撮影した何ペタバイトといった写真データを保管してます。データ解析には困りません。

具体的な手法は省略させていただきます。前年からの複数回のチューニングを経て、人海戦術で付与したのと遜色のないゼッケン付与を行えるようになりました。

## システム概要
システム構成もある程度省略しますが、おおよそ以下のような構成です。

- ゼッケン認識処理自体を独立したアカウントで独立したサービスとして構成してます。
- 写真納品用バックエンド処理はゼッケン認識用アカウントのAPIGateway+Lambdaに対してリクエストを行います。
- リクエストを受けたらSQSにキューが積まれていき、認識処理自体はBatchでゴリゴリと進めてもらいます。
- ゼッケン認識を行う対象の画像はS3に配置しています。
- 認識結果を格納するストレージにはDynamoDBを使っています。

![構成図概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57229/4ff34f22-84b5-a54a-3c17-d60f60f0720a.png)


何十万枚といった画像に対して画像認識処理をかけるにあたって、無限にスケールするAWS Batchのパワーはとても心強いです。単純に量を気にしなくて済むので、どんどんぶっこんでいけますね。

ちなみにどの程度のBatch処理が行われてたかというと・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57229/aa4069f9-1fe5-7844-3dd3-abda3106d660.png)


最初見たときはビビりました。10000vCPUもあれば十分で使い切ることも無いだろうと思ってたのですが・・。スクショは残してませんが、日によっては最大vCPUまで使い切った上で未処理のジョブが残っていた日もあったりします。コンピューティングはSPOTインスタンスを利用しているのですが、スケーラビリティに任せて横着ができるのもクラウドコンピューティングならではというか、AWS様様です。


# 自動化した結果

自動化した結果、いくつかの成果がありました。

## 成果１：手作業部隊への依頼が約半分になった

この記事のタイトルの通りの話ですね。自動化だから全部自動でゼッケン付与できたんじゃないの？とお思いかもしれません。実は全部はまだ厳しいです。ＡＩでも対応できないパターンがいくつかありまして、例えば以下のようなケースです。

- ゼッケン番号が部分的に隠れてしまっている。
 - 腕がかかっているなど
 - 雨天時のレインウエアで見にくい
- 被写体の写りが微妙に悪い
  - ゼッケンは認識できたけど、メインで写っているランナーの背景のように写っているから検索結果（＝購入を提案する商品）として適切かどうかの判断が必要

ゼッケン認識の結果についてはゼッケン番号だけでなく、キチンと認識できているかとか、被写体がきちんと写っているかなどをスコア化してます。そのスコアを見てゼッケン認識の結果が間違いないものであれば自動でのゼッケン認識を完了とし、それ以外は手作業部隊へ回すようにしています。それがだいたい半々でした。（自動で完了したほうが気持ち多め。）

自動での完了率というのは経過を見ながら引き続き調整を続けていきます。手作業ゼロは難しいかもしれませんが、まだまだ改善の余地はありそうです。

## 成果２：夜間にゼッケン認識＆紐付け作業が終わっている

プロローグで「提携企業が稼働する営業時間内でしか作業が依頼できない。」とご紹介しましたが、そこが解消されました。コンピュータなので夜間もバリバリ働いてもらえます。

## 成果３：運用コストが削減できた

運用コストは下がりました。先にお伝えしたとおり、BatchのvCPUが10000程度とかなってましたが、それがペイできています。それほどに手作業に人的コストがかかってたとも言えます。

## 総評価

とても良い✨✨

# 今後

まだ導入したばかりなので手探りのような状態です。先にお伝えした、手作業に回さなければならないパターンもまだ改善の余地がありそうです。また、他の改善と合わせることで公開開始スケジュールの短縮化も目指せそうです。

引き続き、フォトクリエイトではマラソン大会をはじめとした各種イベントにおいて感動を新鮮なままカタチにしてお届けできるよう努めてまいります。少しでもご興味をお持ちいただけたようでしたら、人事部門の担当者 [twitter: @tetsunosuke](https://twitter.com/tetsunosuke) へお知らせください。