この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
「お前は何をやっているんだ」という意見は正しいと思います。
はじめに
先日Amazon RekognitionにImage Moderation機能が追加されました。
今回はこの機能を使って、TwitterのPublic timelineから、不適切と思われる画像を収集してみます。
やってみた
スクリプト本体はAWS SDK for Goを使用しました。新機能を使う前に最新版を取得しておきます。
$ go get -u github.com/aws/aws-sdk-go/
また、TwitterのPublic timelineの収集にはChimeraCoder/anacondaライブラリを使用しました。
$ go get -u github.com/ChimeraCoder/anaconda/
スクリプト
スクリプトの内容は以下の通りです。詳細はコメントとして書きました。Golangとしてはもっと綺麗な書き方があるんだと思いますが、その辺はご容赦ください。もっと素敵なコードが書けるようになりたいものです。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/rekognition"
"github.com/ChimeraCoder/anaconda"
)
func main() {
// Twitter認証情報をセット
consumerKey := os.Getenv("TWITTER_CONSUMER_KEY")
consumerSecret := os.Getenv("TWITTER_CONSUMER_SECRET")
AccessToken := os.Getenv("TWITTER_ACCESS_TOKEN")
AccessTokenSecret := os.Getenv("TWITTER_ACCESS_TOKEN_SECRET")
// Twitter認証
anaconda.SetConsumerKey(consumerKey)
anaconda.SetConsumerSecret(consumerSecret)
api := anaconda.NewTwitterApi(AccessToken, AccessTokenSecret)
// TwitterのPublicStream(statuses/sample)を取得
twitterStream := api.PublicStreamSample(nil)
for {
// データを取得
data := <-twitterStream.C
switch tweet := data.(type) {
// Tweetの場合
case anaconda.Tweet:
// 画像URLを格納する配列を定義
var url []string
// 画像URLを配列に格納
m := tweet.ExtendedEntities.Media
for i := 0; i < len(m); i++ {
url = append(url, m[i].Media_url)
}
for i := 0; i < len(url); i++ {
// 画像を取得
getImage(url[i])
}
default:
}
}
}
func getImage(url string) {
// 画像ファイルのURLに:largeを追加
var buffer bytes.Buffer
buffer.WriteString(url)
buffer.WriteString(":large")
// largeな画像ファイルを取得
image, err := http.Get(buffer.String())
if err != nil {
fmt.Println(err.Error())
return
}
defer image.Body.Close()
// 画像ファイルのデータを全て読み込み
bytes, err := ioutil.ReadAll(image.Body)
if err != nil {
fmt.Println(err.Error())
return
}
// セッション作成
sess := session.Must(session.NewSession())
// Rekognitionクライアントを作成
svc := rekognition.New(sess, aws.NewConfig().WithRegion("us-east-1"))
// svc.DetectModerationLabelsに渡すパラメータを設定
params := &rekognition.DetectModerationLabelsInput{
Image: &rekognition.Image{
Bytes: bytes,
},
// Confidenceが70%以上
MinConfidence: aws.Float64(0.7),
}
// svc.DetectModerationLabelsを実行
resp, err := svc.DetectModerationLabels(params)
if err != nil {
fmt.Println(err.Error())
return
}
// 対象であれば処理継続
if len(resp.ModerationLabels) != 0 {
// URLからファイル名を取得
filename := filepath.Base(url)
if err != nil {
fmt.Println(err.Error())
return
}
// ファイルを作成
file, err := os.Create(filename)
if err != nil {
fmt.Println(err.Error())
return
}
defer file.Close()
// ファイルを書き込んで保存
file.Write(bytes)
// 保存した情報を出力
fmt.Println(resp.ModerationLabels)
fmt.Println("Save " + filename + ".")
}
return
}
作成したスクリプトはgo fmtで整形します。
$ go fmt getpic.go
そしてbuildします。
$ go build
バイナリが出来上がります。
$ ls
getpic getpic.go
実行結果
実行すると以下のように出力されます。
$ ./getpic
[{
Confidence: 53.97080612182617,
Name: "Explicit Nudity",
ParentName: ""
} {
Confidence: 53.97080612182617,
Name: "Graphic Male Nudity",
ParentName: "Explicit Nudity"
}]
Save C-KFERyXkAE1oGP.jpg.
[{
Confidence: 57.758872985839844,
Name: "Suggestive",
ParentName: ""
} {
Confidence: 57.758872985839844,
Name: "Female Swimwear Or Underwear",
ParentName: "Suggestive"
}]
Save C-H_9B1XkAIKTdK.jpg.
....snip....
そして保存された画像がこちら...なのですが、ちょっとお見せできないのでモザイクかけました。
というような使い方もできますね!
さいごに
Image Moderationは一般的にはフィルタリングするために使われますが、こういった使い方もできます。今回は単純にConfidenceが70%以上の画像を取得しましたが、ParentNameとNameを判別することで、特定のカテゴリと判定された画像のみを選別することも可能です。
以上、ちょっと変わったユースケースでした。