画像内の特定の文字をぼかすLogic Appsを作る
はじめに
ブログや登壇資料で毎回Azureのアカウント情報やサブスク情報をマスクするのが結構気を遣う作業で大変だな~画像投げたら自動で大事なところをマスクしてくれるbot作れないかな~と思ったので、挑戦してみました。
しかし、現時点では完璧に情報を認識してマスクするというところまでは至っておらず…
何ができてなくて、何をできるようにしないといけないのか整理するために今できているところまでを書き起こします。
参考サイト様
ASCII.jp:文字入り画像を送るとテキストに書き起こすLINEボットを作ろう (1/3)
ASCII.jp:人物写真の顔をAIが検出し、ぼかしてツイートするLogic Appsを作ろう (1/3)
メモ:Cloudmersive Image コネクターを利用して、画像の顔に自動でぼかしを入れる - MoreBeerMorePower
作りたいもの
Azure Portalの画面キャプチャを送ると、アカウント情報などにぼかし処理を施して画像を返信してくれるBot
今できていること
今できていないこと
Azure以外の事前準備
このあたりについては参考サイト様に丁寧な説明があります。
作成手順
全体図
トリガーの作成
参考サイト様そのままです。
トリガーを[HTTP要求の受信時]にし、LINE botに画像を送信することをトリガーとします。
透明画像の準備
事前にDropboxに1200×1200サイズの透明画像を格納しておきます。
透明画像はiPhoneアプリのibisPaintで用意しました。無料で使えますし、サイズ指定もわかりやすいです。
透明画像のサイズは大きければ大きいほうがいいだろうと思い、初めは無駄に大きいものにして失敗したので、ひとまず1200×1200で統一しておいたほうが無難そうです。
コンテンツの取得
以降、[For each]内での処理になります。
LINEで送られてきた画像情報を取得します。
URI:concat('https://api.line.me/v2/bot/message/',items('For_each')?['message']?['id'],'/content')
ぼかし処理をするための情報収集
ぼかし処理をするためには、ぼかしたい対象の範囲を座標で指定する必要があります。
アカウント情報の文字列の座標を取得するために、[Computer Vision API]の[Optical Character Recognition (OCR) to JSON]を使います。
このアクションを使うと、画像から認識した文字ごと位置エリアごとにJSONグループ、階層に分けてくれます。
[boundingBox]で対象の座標がわかります。今回はメールアドレスの部分の座標を使います。
座標の意味はこんな感じだと思います。
"boundingBox": "左上端のX座標, 左上端のY座標, 幅, 高さ"
似たようなアクションで、[Computer Vision API]の[Optical Character Recognition (OCR) to Text]というものがあります。
これは認識した文字をテキストにしてくれます。
単純な画像の文字起こしならこの機能を使えば十分そうです。(やや日本語が怪しそうなところはありますが…
ぼかしたい情報が画像内に入っているか判定する
今回はメールアドレスが入っていればぼかし処理をするようにしたいので、[Optical Character Recognition (OCR) to Text]で取得したテキスト内にメールアドレスのドメインがあるかを確認します。
ぼかす範囲を切り抜くための座標指定
アクション名:Crop an image to a rectangular area
ぼかす範囲を切り抜くために座標指定します。
この座標は[Optical Character Recognition (OCR) to JSON]で取得したものを使います。アイコンの部分までぼかしにいれたいので、横幅を少し大きくしました。
今回は完全に座標を固定で入れていますが、将来的にはここを変数化したいです。
対象範囲のぼかし処理
アクション名:Perform a guassian blur on the input image
ぼかし具合を設定します。
ぼかす大きさとかにじみ具合とか指定できます。参考サイト様のこの比率が滑らかでちょうどいいなと思っています。
透明画像と合成する
アクション名:Composite two images together
ぼかし処理済みの画像と透明画像を合成します。
合成するとこんな感じになります。
右側の真ん中に載るように指定しました。
元画像と合成するための切り抜き
アクション名:Crop an image to a rectangular area
上記のぼかし処理済みの画像と元画像を合成したときに、対象位置がちゃんと重なるように切り抜いて調整する必要があります。
重ねる位置が極端に右上端であることと切り抜き範囲を座標で固定していることから、この辺りは参考サイト様そのままではなく少し調整しました。
(考え方ややってることはそんなに変わらないはず…
sub(div(variables('ciwidth'),2),div(158,2))
sub(div(variables('cihight'),2),div(25,2))
div(add(variables('ciwidth'),add(1650,1808)),2)
div(add(variables('cihight'),add(6,19)),2)
切り抜いた結果がこんな感じです。
元画像と合成する
アクション名:Composite two images together
元画像に先ほど切り抜いた画像を合成します。
結果、こんな感じの画像ができます。
狙い通りの位置がぼかされています。
ぼかし処理済みの画像をDropboxに保存する
完成した画像はDropboxに保存します。
フロー上のCloudmersiveのアクション名が英語で分かりづらいので、画像処理の合間合間にこの処理(ファイルの作成)を挟むと、途中経過の画像が保存されて段階がわかりやすいです。
おまけ:文字起こしした内容を返す
画像から文字起こしした内容をbotに変えさせたい場合は、任意の場所にこのアクションを入れるとできます。[Optical Character Recognition (OCR) to Text]で取得した内容を返すような形です。
おわりに
「今できていないこと」にも記載したように、現状のフローだと、対象箇所をぼかすためにはいろいろと制限があります。(元の画像にブラウザのタブが入っていてはだめとか…
もう少し利便性があげられるように改修していきます。
正直、コードで書いてしまえば早いような気もしますが、Logic Appsを使いこなすために始めた題材なので、できるところまで粘ってみます。