4
7

More than 5 years have passed since last update.

マミルトンのゲーム実況動画で ffmpeg RMagick rekognition を使おう~その1~ヽ(゚ー゚*ヽ)(ノ*゚ー゚)ノわぁい

Last updated at Posted at 2014-10-17

※Ubuntuは12.04系です

はい。今日もゲーム実況動画をBGMにしてコーディングしてます。ゲーム実況をしているマミルトン、もうみなさんご存知ですよね?この↓の右側の女性です。

マミルトン

まだ、ご存知ない方は下の動画をどうぞ。これは、ステマじゃないよ!

マミルトンのゲーム実況動画:【パズドラ】聖の龍騎姫【同キャラ禁止】 地獄級にマミルトンと挑む!

ゲーム実況動画をうまいこと分類したりできないか試行錯誤してきます。使用環境は Ubuntu (12.04) とRubyがメインで、shellスクリプトも使います。画像APIを提供するRekognitionですが、月に5,000くおーたしか使えないので、一部OpenCV使う予定です。

ffmpeg を使ってフレーム画像の抜出し

YouTube 動画のダウンロード

youtube-dl を使って、動画をダウンロードします。顔が大きめに映っているものを使いたいので、今回は↓の動画を使わせてもらいます。※ステマじゃないって!でもこの動画、おいしそーです。

マミルトン

マミルトン&ミカリタンのカフェデート 第2弾!

youtube-dl コマンドライン

youtube-dl はそのままだとダウンロードしたファイル名に動画タイトルが含まれます。それはいやなので、videoId だけになるようにオプション渡します。

$ youtube-dl -f 22/17  -o "%(id)s.%(ext)s" https://www.youtube.com/watch?v=NNpOTng4b40

これで、NNpOTng4b40.mp4 というファイルがダウンロードされます。

フレーム画像の抜出 ffmpeg 使うよ

ダウンロードした動画からフレームの画像を抜き出します。全部は多いので、とりあえず1秒毎に1枚、最初の60秒ぐらい抜き出しましょう。シェル書きます。

mkimages.sh
#! /bin/bash

for i in `seq 1 1 60`
do
    echo "$i"
    #ls $1 -al
    ffmpeg -y -i $1 -vframes 1 -ss $i -r 1 -f image2 $i.jpg
done
exit 0

シェルは苦手です。もっと良い書き方があったら教えてください。 :laughing:

これで、 1.jpg から 60.jpg までの画像ができていると思います。

4.jpg

4.jpg

10.jpg

10.jpg

ffmpeg のコマンドライン引数の順番でエラー?

以前より厳密になったのでしょうか?ほかサイトでは

ffmpeg -vframes 1 -i hoge.mp4 -ss 1 -r 1 -f image2 1.jpg

みたいに書いていたのも、-vframesの位置が悪いとおこられました。こんな感じ:

Option vframes (set the number of video frames to record) cannot be applied to an input option to an output file or vice versa. Move this option before the fi
Error parsing options for input file NNpOTng4b40.mp4.

せっかくなので RMagick 使って mosaic

mamiruton.rb
# -*- coding: utf-8 -*-

require 'test/unit'
# RMagick
require 'rubygems'
require 'RMagick'

# http://www.imagemagick.org/ImageMagick-7.0.0/RMagick/doc/mosaic.rb.html
class TC_Foo < Test::Unit::TestCase
    def setup
        puts "setup"
    end
    def test_rmagick_mosaic
        puts "open_images"
        imageUrls = ["1.jpg",
            "2.jpg",
            "3.jpg",
            "4.jpg",
            "5.jpg",
            "6.jpg",
            "7.jpg",
            "8.jpg",
            "9.jpg"
            ]
        images = Magick::ImageList.new(*imageUrls)

        b = Magick::ImageList.new
        page = Magick::Rectangle.new(0,0,0,0)
        images.scene = 0

        3.times do |i|
            3.times do |j|
                b << images.scale(0.57)
                page.x = j * b.columns
                page.y = i * b.rows
                b.page = page
                (images.scene += 1) rescue images.scene = 0
            end
        end
        image = b.mosaic
        image.write("mamiruton2.jpg")
    end
end

test/unit を使っているのは、問題があったときのデバッグのためです。

マミルトン

Rekognition のAPIを使ってみる

とりあえずためしに 4.jpg を使ってみます

大きめの顔になっている 4.jpg を使います。

4.jpg

rekognize の gem を入れる

$ sudo gem install rekognize

APIを呼んでみる

rekognize.rb
class TC_Foo < Test::Unit::TestCase
    def setup
        @client = Rekognize::Client::Base.new(api_key: YOUR_API_KEY, api_secret: YOUR_API_SECRET)
    end
    def test_open_remote_image
        response = @client.face_detect(urls: "http://gameranking.scleen.com/images/mamiruton/4.jpg", jobs: 'face_part_aggresive_emotion_age_beauty')
        puts response
    end
end

※test/unit 使っているのはデバッグしやすいからです・・・
※face_detect はパラメーター base64 をサポートして無いのかな・・・

APIの結果

レスポンス:

項目 数値
happy 0.98
sad 0.03
disgust 0.01
age 17.07
smile 0.97
beauty 0.54331

とこんな感じのデータが得られます。happy と smile で数字が取れているのでこの数字を使ってみましょう。

顔の位置の確認

顔の位置も正しく認識できました。

result.jpg

このRectangleはRMagick使って描きました。

rekog.rb
class TC_Foo < Test::Unit::TestCase
    def setup
        @client = Rekognize::Client::Base.new(api_key: YOUR_API_KEY, api_secret: YOUR_API_SECRET)
    end
    def test_open_remote_image
        response = @client.face_detect(urls: "http://gameranking.scleen.com/images/mamiruton/4.jpg", jobs: 'face_part_aggresive_emotion_age_beauty')
        puts response
        # draw rectangles

        image = Magick::Image.read("http://gameranking.scleen.com/images/mamiruton/4.jpg").first
        response['face_detection'].each do |face|
            x = face['boundingbox']['tl']['x']
            y = face['boundingbox']['tl']['y']
            w = face['boundingbox']['size']['width']
            h = face['boundingbox']['size']['height']

            puts "#{x},#{y} #{w},#{h}"

            gc = Magick::Draw.new
            gc.stroke = 'red'
            gc.fill = 'transparent'
            gc.rectangle x, y, (w+x), (y+h)
            gc.draw(image)
        end
        image.write "result.jpg"
    end
end

ミカルタンが一緒のフレームでもうまく顔が認識できます。Rekognition のAPIは beauty という超主観的な結果を戻してくれますが、とりあえず使わないでおきます。smile happy 程度がまぁいいんじゃないでしょうか。

result7.jpg

えがおとHAPPY度合でスコアリング

Rekognition のAPIを使って開始1分間のえがおとHAPPY度合 :smile: をスコアリングして上位の画像を探してみた。

result8.jpg
7秒

result8.jpg
8秒

result8.jpg
11秒

result8.jpg
22秒

result8.jpg
32秒

result8.jpg
33秒

これはなかなかやるのではないか?マミルトンの笑顔をお楽しみいただけましたでしょーか? :smile:

いろいろ

Rekognition の制限事項

  • 画像サイズは縦横800pxまで、それを超える場合は内部的に縮小してから処理してるらしい。
  • 無料5,000回/月は少ないなー

検討すること

  • Rekognitionが800pxまでなので、YouTubeからのダウンロードする動画サイズを小さくした方がいろいろ良さそう。処理が速くなるしディスクサイズの節約にもなる。
  • ffmpeg のフレーム画像の切り出しに時間かかるので短縮する方法を考える。全部出してから削除したほうが速い感じだ。
4
7
1

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
4
7