Google Cloud Vision API でTwitterでリプライされた画像がエッチかエッチじゃないかを判定するプログラムを作ってみた


Google Cloud Vision API にアダルトコンテンツを判定する機能があるようなので
Twitter APIと組み合わせてリプライされた画像がエッチかエッチじゃないかを判定するプログラムを作ってみました。

Twitter API の認証

まずは、Twitter Deveropersでアプリケーション登録してAPIキーを発行します。
APIキー発行の方法はTwitter REST APIの使い方を参照。

発行したキーを以下にセットして認証するとTwitterAPIが使用できるようになります。

client = Twitter::REST::Client.new do |config|
        config.consumer_key        = CONSUMER_KEY
        config.consumer_secret     = CONSUMER_SECRET
        config.access_token        = ACCESS_TOKEN
        config.access_token_secret = ACCESS_TOKEN_SECRET
    end

Google Cloud Vision APIの認証

Google Cloud PlatformでGoogle Cloud Vision APIの登録をします。
Cloud Vision APIの使い方まとめ (サンプルコード付き)を参考にAPIキーを取得します。

Google Cloud Vision API のリクエスト方法

まず、取得したAPIを以下URLにセットしてリクエストURLを作成します。

URL = "https://vision.googleapis.com/v1/images:annotate?key=#{API_KEY}"

そして、以下のようにリクエストのJSONを作成します。
今回はアダルトコンテンツの判定がしたいので、"type"に"SAFE_SEARCH_DETECTION"を指定します。
"content"に画像のパスを入れてあげましょう。

uri           = URI.parse(URL)
https         = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true

req                 = Net::HTTP::Post.new(uri.request_uri)
req["Content-Type"] = "application/json"
param               = {
  "requests" =>
  [
    {
      "image" =>
      {
        "content" => Base64.strict_encode64(open(filepass).read) #画像のfilepassを入れる
      },
      "features" =>
      [
        {
          "type"       => "SAFE_SEARCH_DETECTION",
          "maxResults" => 10
        }
      ]
    }
  ]
}
req.body = param.to_json
res      = https.request(req)

すると、以下のようなレスポンスが帰ってきます。

================ 実行結果 ===============
  "responses": [
    {
      "safeSearchAnnotation": {
        "adult": "VERY_UNLIKELY",
        "spoof": "VERY_UNLIKELY",
        "medical": "VERY_UNLIKELY",
        "violence": "VERY_UNLIKELY"
      }
    }
  ]
}

今回はアダルト判定がしたいので"adult"の値を取得します。
ちなみに"spoof"だとコラージュ判定、"violence"だとグロテスク判定ができます!

str = res.body
hash = JSON.parse(str)
answer = hash.dig("responses",0,"safeSearchAnnotation","adult")
p answer

# →  "VERY_UNLIKELY"

リプライされた画像をGoogle Cloud Vision APIで解析して判定結果をリプライする

①client.searchで「@ツイッターID」を含むツイートを取得します。(リプライ取得)
②取得したツイートに対して、mediaメソッドで画像を取得し、media_urlメソッドで画像パスを取得します。
③画像パスをGoogle Cloud Vision APIに投げ、レスポンスを日本語に直します。
④日本語に直したレスポンスをツイートしてあげれば、リプライされた画像がエッチかエッチじゃないかを判定するプログラムの完成です!

query = '@アカウントID'
str = ""
count = 0
client.search(query, :result_type => "recent", :exclude => "retweets" ,:include_entities => true).each do |tweet|
  tweet.media.each do |media|
  break if count > 5
    media_url = media.media_url
    answer = imgAnalyze(media_url) #Google Cloud Vision APIで画像解析
    case answer
    when "VERY_LIKELY" then
      str = "とてもエッチです"
    when "LIKELY" then
      str = "エッチです"
    when "POSSIBLE" then
      str = "エッチかもしれないです"
    when "UNLIKELY" then
      str = "エッチじゃないです"
    when "VERY_UNLIKELY" then
      str = "全然エッチじゃないです"
    else
      str = "よくわからないです"
    end
    #ツイートする文字列を作成
    user_name = tweet.user.screen_name
    tweet_str = "@" + user_name + " " + str
    id = tweet.id
    #リプライツイートを投稿
    client.update(tweet_str,in_reply_to_status_id: id)
    count += 1
  end
end

まとめ

ちゃんとアダルトな画像はエッチ判定してくれます!
三次元なアダルト画像だけでなく、二次元のエッチな画像もちゃんと判定してくれるのがすごい。
ただ、ツイッター本垢で実装してしまったため、大量のエロ画像が送りつけられてきて大変でした。。