21
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

エロ画像検出APIを用いてエロ画像のアップロードを阻止してみる【前編】

Last updated at Posted at 2024-09-01

こんにちは!
バックエンドエンジニアからフルスタックエンジニアに進化したいすぎちゃんです!

キャリアアップのため転職先にアピールする成果物のためポートフォリオを作成中 :muscle:
今までに培ったサーバーサイドの知識だけでなく新しく学んだAWSの知識もフルに活用して邁進しております!

皆さんも素晴らしいポートフォリオは作りたいですよね?
また見てくれる人から前向きなFBはもらいたいですよね?

しかし見てもらおうとポートフォリオを公開すると、どうしても民度の低い方が1人2人は出てきてしまうもの・・・ :crying_cat_face: (実際に被害を受けた人の声

そんな人たちのために時間を割かれてしまうのは実に勿体ないことですよね :thermometer_face:

なので今回は「エロ画像検出API」を用いて、
エロ画像をアップロードしようとしても未然にブロックされてしまう仕掛けを作ろうと思います :clap:

↓の記事も是非よろしくお願いします!

完成系

完成系はこちら!
猫ちゃんの画像をアップロードしたらプロフィール画像に設定できますが、
反対にエロ画像ははじかれる。

純粋な方に優しい機能を作っていきましょう:muscle:

cat_image_uploaded.gif

nsfw_image_uploaded.gif

準備

今回使用するのはnsqf_apiというもの。

yahooが開発したopen_nsfwに依存しする、画像がアダルトコンテンツを含むか予測するREST APIです。

README.mdには以下2つの方法が記載されています。

  • ローカル環境内でAPIリクエストを投げる方法
  • Herokuにコンテナをデプロイし、立ち上げたAPIサーバーにAPIリクエストを送る方法

しかしherokuは2022年の夏頃に無料枠が完全に撤廃したため、
2つ目の方法を実現するためには他のサービスを使う必要があることがわかりました :cry:

Herokuは2022年8月25日、Heroku DynosやHeroku Postgresなどの無料プランの廃止をアナウンスしました。このニュースには、個人開発者だけでなく、Web開発者であればほとんどの人が衝撃を受けたのではないでしょうか?

参照元:Heroku無料枠廃止で路頭に迷う開発者に捧ぐ、次世代PaaS「Render.com」の使い方

そのため、今回はAWSのECRとECS Fargateを用いて、エロ画像検出APIのサーバー構築をクラウド上で実現したいと思います!

ECRの設定

下記のコマンドを打つ前にDockerをインストール&起動しておきましょう。

1.nsfw_apiのdockerイメージをpullする

$ docker pull eugencepoi/nsfw_api:latest

2.ECRの作成

下記の手順でリポジトリを作成して下さい

  1. AWSマネージメントコンソールにアクセス
  2. 右上のリージョンをUS EAST(N. Virginia)に変更
  3. 右上のリージョンを選択
  4. ECSサービスを選択
  5. 左サイドバーの Repositories を選択
  6. Create repositoryボタン押下

リポジトリ名はわかりやすいようにdetect-noodie-imageに設定しておきましょう。

3. リモートリポジトリに取得したイメージをpushする

3-1. ECRにログイン

<アカウントID>は各ユーザーに紐づいている12文字の文字列に置き換えて下さい。

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.us-east-1.amazonaws.com

3-2. 取得したイメージのタグ付け

タグ名は<アカウントID>.dkr.ecr.us-east-1.amazonaws.com/detect-noodie-image:latestを設定して下さい。

docker tag eugencepoi/nsfw_api:latest <アカウントID>.dkr.ecr.us-east-1.amazonaws.com/detect-noodie-image:latest

3-3. イメージをpush

ECRのリポジトリにpushして下さい。

 docker push <アカウントID>.dkr.ecr.us-east-1.amazonaws.com/detect-noodie-image:latest

上記のコマンドを入力すると、ECRのリポジトリ詳細ページのイメージ一覧画面が以下の画像のにようになっているはずです。

スクリーンショット 2024-09-01 16.25.02.png

ECSの設定

1. タスク定義画面の表示

サイドメニューの「タスク定義」を選択して下さい。

スクリーンショット 2024-09-01 16.32.00.png

そうするとタスク一覧画面に遷移します。右上の「新しいタスク定義の作成」をクリックして下さい。
スクリーンショット 2024-09-01 16.33.15.png

クリックすればドロップダウンメニューが表示されます。
今回は「新しいタスク定義の作成」を選択して下さい。

スクリーンショット 2024-09-01 16.37.11.png

2. タスク定義の設定

2-1. タスク定義ファミリー名の設定

今回はnsfw-api-taskと命名します。

ECSTaskDefinition Name_0.png

2−2. インフラストラクチャの要件の設定

ECSTaskDefinition InfrastructureRequirement_1.png

起動タイプはAWS Fargateを選択、CPUサイズは一番最小のものに設定しておきましょう。

最小のものに設定しておくと月に2000円もかかりません。

2-3. コンテナ設定

名前はnsfw-api-container、イメージURLにはECRを作成した時に生成されたイメージURI(<アカウントID>.dkr.ecr.us-east-1.amazonaws.com/detect-noodie-image:latest)を設定して下さい。

ECSTaskDefinition container_2.png

コンテナとの通信を可能にするため、ポートマッピングも忘れずに設定しておきましょう。

コンテナポートは5000、プロトコルはTCP、ポート名は5000、アプリケーションプロトコルはHTTPを選択して下さい。

2-4. 環境変数の設定

キーにPORT、値を5000に設定しましょう。

ECSTaskDefinition Container EnvVal_2.5.png

以上の手順を踏み右下の「作成ボタン」を押すと、コンテナ詳細画面に遷移し画面上部に「正常に作成されたタスク定義」と表示されます。
ECSTaskDefinition Complete_4.png

3. コンテナサービスの設定

3-1. クラスターの作成

クラスター名は nsfw-cluster、インフラストラクチャでは**AWS Fargate(サーバレス)**を選択して下さい。
設定が終わったら画面右下の「作成ボタン」をクリックして下さい。

ECSCluster .png

そうするとクラスター一覧画面に詳細画面へのリンクが表示されます。

スクリーンショット 2024-08-31 2.03.47.png

3-2. クラスター詳細画面へ遷移

作成された詳細画面に移動しましょう。
詳細画面の下部は以下のように表示されているはずです。

スクリーンショット 2024-09-01 17.09.04.png

真ん中に表示されている作成ボタンをクリックし、サービス作成画面に遷移してください。

3-3. 環境の設定

コンピューティングオプションは起動タイプ、起動タイプはFARGATEを選択して下さい。

プラットフォームバージョンはデフォルトのLATESTのままで大丈夫です。

ECSService Environment_0.png

3-4. デプロイ設定

アプリケーションタイプはサービス、ファミリーはタスク定義で作成したnsfw-api-taskを選択してください。

サービス名はnsfw-api-serviceに設定しておきましょう。

ECSService DeploymentSetting_1.png

3-5. ネットワーキング

VPCはご自身が作成したもの、サブネットはパブリックのものだけを選択して下さい。

コンテナとの通信を可能にするため、セキュリティグループのインバウンドルールは以下のように設定します。

  • タイプ:カスタムTCP
  • ポート範囲: 5000
  • ソース: カスタム
  • 値: 自身のマシンのIP, もしくはアプリケーションがホスティングされているEC2のAPI

外部からのアクセスができるようパブリックIPの設定もONにしておきましょう :muscle:

ECSService Networking_2.png

以上の設定が終われば画面下部の「作成」ボタンをタップして下さい。

そうするとクラスター詳細画面に遷移し、画面下部の「タスク」を選択するとタスクも作成されているはずです。

スクリーンショット 2024-09-01 17.27.57.png

動作確認

作成したサービスに紐づいているタスクの詳細画面に移動します。

ECSService TaskDetail .png

設定のセクションにパブリックIPがされています。
APIのURLの形式は以下の通りです。

http://<タスクに紐づいたパブリックIP>:5000/?url=<調べたい画像のURL>

猫の画像
image.png

試しにいらすとや猫ちゃんの画像 :cat: がエロいかどうかを調べてみましょう。

{"score":0.026141654700040817,"url":"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA0XNyhytw0thfWMu4X6yK89mQ4lwuqPWmOTy4-UQ4NCOLFiYMJfetMdfCze2aGIZra6_SSqLtHvl-zXFmlFVqfu5RySPBi7gEXg8sP-QFPePD88dSmb0EQUU9nRZneIm36zSbUMT60nE/s400/animal_stand_neko.png"}

結果は約0.02。全くエロ画像っぽくないことがわかりました。
業務でも問題なく使用してもいいことがわかります。

他の画像でも色々試してみたところ、やはりGoogleで「●● エロ画像」と画像検索して最上位に来るものについては0.9以上のscoreを叩き出すことがわかりました。

しかし私は疑り深い性質なのか「ほんまかいな?どうせ肌色成分が多いからちゃうん? :rolling_eyes: 」と思い、念のため肩ロースの画像でも検証してみました。

{"score":0.092671982944011688,"url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSrgnoeiWSTDfAGdECsqMJqrVfs0CBF3r2-sA"}

結果は0.09とエロ画像と認識されていないことが判明しました。
ある程度の精度が保証されているようです :smile:

ここまでお読みいただき、誠にありがとうございます!
次週はlaravelアプリケーションと連携をして、アップロードされた画像がもしエロ画像だったら警告モーダルを表示する仕掛けを作っていこうと思います!

↓の記事も是非よろしくお願いします!

参考記事

21
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?