ミツモア Tech blog

「ミツモア」を運営する株式会社ミツモアの技術ブログです

チャット画像からQRコードと電話番号を検知してみた

※ こちらはミツモアAdvent Calendar 2022の8日目の記事です。

こんにちは、ミツモア データチームの増田です。今回は、ミツモアで行っているチャットの画像分析による中抜き検知について紹介したいと思います。

要約

  • ミツモアで中抜きを行った事業者を検知するために、チャットでやりとりされた画像からQRコードと電話番号が記載されているものを検知できるようになりました。
  • QRコードの検知はpyzbarというOSSソフトウェアを使用しました
  • 電話番号の検知にはTesseractというOSSのOCRソフトウェアを使用しました。OCRで画像をテキストに変換してから電話番号のパターンで検知します
  • OSSをベースに短期感(トータルで1人日〜2人日程度)で作成したプログラムですが、今まで検知しづらかった部分のカバーもできるようになりました

背景

ミツモアでは、エアコンクリーニングや引越しや税理士などの多様な領域で、依頼者と事業者をマッチングするサービスを展開しています。マッチング後、依頼者と事業者が基本的にはチャットでやり取りを実施するのですが、この際、違反行為として禁止されている、依頼者と事業者がマッチングした段階でチャット内外でのやりとりを通じて中抜きを行おうとする場合が稀に存在します。

そのようなやりとりを撲滅する活動の一環として、中抜き疑惑の画像検知を新たにすることになり、今回のプロジェクトがスタートしました。

方針

実際に中抜きが行われたチャットを分析したところ、事業者が中抜きを行う際に取る方法として、大きく次の二つのパターンがあることがわかりました。どちらも画像を使用してミツモアを経由しない別チャネルに誘導します。

  1. LineなどSNSのQRコードを送り、依頼者をQRコード先でのやりとりに誘導するパターン
  2. 電話番号が書かれた画像(ホームページのスクリーンショットやパンフレットの画像など)を送り、電話でのやりとりに誘導するパターン

このようなチャットのやりとりを検知するため、チャットで事業者から依頼者に送られている画像から、QRコードと電話番号が記載されているものを検知するプログラムをデータチームで作成することになりました。

使用する技術

データチーム内で簡単に議論して開発の方針を以下のように決定しました。

  • QRコード検知と電話番号検知の両方とも、既に存在するライブラリやサービスを利用して工数をかけずにクイックに作成する
  • QRコード検知に関しては、既に存在するQRコード関連のライブラリやサービスを利用する
  • 電話番号検知では、OCRを使用して画像をテキストに変換し、テキストから電話番号のパターンを検知する

必要な技術はQRコードの検知とOCRになります。それぞれどのように技術を選択していったかを簡単に記載します。

QRコードの検知

QRコードを検知するライブラリについて調べたところ、pyzbarとZXingが候補として挙がりました。

今回はpyzbarを使用することにしました。理由はpyzbarがpythonから利用できるためです。データチームはpythonをメインに使用しているため、pythonで開発できる方が開発も保守運用も楽です。ZXingはJavaから利用するようですが、データチームがJavaでプログラムを開発していくのはスキル的にミスマッチです。ZXingのthird-partyのpythonラッパーを使用することも少し考えましたが、選択したthird-partyのライブラリ自体がどれほど信頼できるか(継続して保守運用されていくのかなど)が懸念になり、最終的てにpyzbarを選択しました。

OCR (電話番号の検知に使用)

OCRはTesseractというOSSのOCRソフトウェアとGCPのCloud Vision APIが候補として挙がりました。

今回はTesseractを使用することにしました。理由はTesseractの方が早く開発ができると考えたためです。データチームは普段からクラウドサービスとしてGCPを利用しているためCloud Vision APIを使用すること自体はすぐできるのですが、使用する前に開発や運用に必要な料金の見積もりを、将来の画像を用いたチャットの増加なども考慮しながら考えないといけないので、開発に着手できるまでに多少時間がかかります。今回は2人日程度で全て開発しきりたかったので、無料で利用できるTesseractを使用することになりました。精度的にはCloud Vision APIの方が良さそうでしたが、電話番号を検知するだけならTesseractでもそれほど大きな差にならないだろうとも考えました。

使い方の紹介

利用したpyzbarとTesseractについて、インストールや使用方法などを簡単に紹介していきたいと思います。いずれも公式ドキュメントに詳細に手順が記載されているので、それを見れば良い話ではありますが、読者の皆様にもこの機会に手元で作業してみて使用感を確認いただければと思います。

動作環境としてm1 macbookを想定しています。

pyzbar

インストール

pyzbarはzbarをpythonから利用するライブラリで、実際のQRコードの解析はzbarを使用しています。そのため、pyzbarをpythonパッケージとしてpipでインストールするのに加えて、zbarもインストールする必要があります。zbarのインストールにはhomebrewを利用します。

brew install zbar
pip install pyzbar

githubのissueに挙がっていますが、m1 macbookだとzbarのlibraryを認識させるために、以下のようにしてシンボリックリンクを貼る必要があります。

mkdir ~/lib
ln -s $(brew --prefix zbar)/lib/libzbar.dylib ~/lib/libzbar.dylib

実行

pyzbarのリポジトリのREADMEに記載されていますが、以下のpythonコードで簡単にQRコードを検知できます。

from pyzbar.pyzbar import decode
from PIL import Image
decode(Image.open("path/to/image.png"))

デフォルトだとQRコード以外にもバーコードも検知します。QRコードだけ検知したい場合はdecodeの引数で指定します。

from pyzbar.pyzbar import ZBarSymbol
decode(Image.open("path/to/image.png"), symbols=[ZBarSymbol.QRCODE])

decodeの返り値は検知されたQRコード全ての情報を格納したlist[dict]形式です。decodeの返り値が空リスト([])かどうかで、画像にQRコードが含まれているか判定します。

Tesseract

インストール

こちらもhomebrewを利用して簡単にインストールできます。tesseract-langは英語以外の言語もOCRする際に必要になります。

brew install tesseract tesseract-lang

実行

日本語でOCRする場合は以下のコマンドで実行できます。

tesseract path/to/image.png - -l jpn

最後のjpnは日本語の意味です。英語と日本語が混じった文章の場合はeng+jpnに、英語のみの文章はengにします。サポートされている言語の一覧はここから確認できます。

工夫した点、困った点

pyzbarが特定の画像でエラー

こちらにissueが立っていますが、pyzbarでは頻度は少ないですが特定の画像でエラーが発生し処理が落ちます。issueもopenで、try~exceptでも対応できないため、エラーが出たら手作業で除外リストに追加していき処理をスキップするようにしています。

まとめ

ミツモアで画像による中抜き検知を行うプログラムを作成した話をさせていただきました。既存のソフトウェアやライブラリを組み合わせただけで、工数も1人日〜2人日程度しかかけていない簡単なプログラムですが、ミツモアにとって重要な役割を担えていると思っています。また今回のようにスモールスタートでクイックに開発していくのはミツモアが重視している開発文化でもあるのかなと思います。中抜き検知としてデータチームができることはまだまだあるはずなので、引き続きアイディアを出していき改善していけたらと思っています。