目的
今回のスクリプトでは,あるクエリに対する典型的な画像を自動的に収集する.
例えば,近年画像の分野で(元々は音声の分野だったが...)DeepLearningが流行っており,様々な学会で見かけたり,Shared Taskとして確立していたりする.
しかしながら,その学習データは膨大な数が必要で,収集からアノテーションまでにかける時間はかなりのコストが必要になる.
そこでDeepLearningをはじめとした機械学習に必要なタグ付き画像データを収集する!というような目的を想定して今回のスクリプトを作成した.
典型的な画像の収集
今回はbingの画像検索を利用して,画像収集の自動化を試みる.
下記のコードではクローリングやスクレイピングっぽいことを行っているが,今回は勉強のため便利なモジュール(BeautifulSoup,urllibなど)は使わずに実装した.
典型的な画像収集と銘打っているが,実際には検索上位N件を取ってくるだけの処理である.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import re
import commands as cmd
# クエリ検索したHTMLの取得
def get_HTML(query):
html = cmd.getstatusoutput("wget -O - https://www.bing.com/images/search?q=" + query)
return html
# jpg画像のURLを抽出
def extract_URL(html):
url = []
sentences = html[1].split('\n')
ptn = re.compile('<a href="(.+\.jpg)" class="thumb"')
for sent in sentences:
if sent.find('<div class="item">') >= 0:
element = sent.split('<div class="item">')
for j in range(len(element)):
mtch = re.match(ptn,element[j])
if mtch >= 0:
url.append(mtch.group(1))
return url
# ローカルに画像を保存
def get_IMG(dir,url):
for u in url:
try:
os.system("wget -P " + dir + " " + u)
except:
continue
if __name__ == "__main__":
argvs = sys.argv # argvs[1]: 画像検索のクエリ, argvs[2]: 保存先のディレクトリ(保存したい時のみ)
query = argvs[1] # some images e.g. leopard
html = get_HTML(query)
url = extract_URL(html)
for u in url:
print u
# 画像をローカルに保存したいときに有効にする
#get_IMG(argvs[2],url)
実行
実行方法
コマンドラインから下記のようにして実行する.
ただし,引数dirはget_IMGを用いない(画像を保存しない)場合は指定しない.
$ python collect_img.py query dir
- query: 欲しい画像の検索ワード (e.g. leopard)
- dir: 画像保存先ディレクトリ (./img/*)
実行結果
今回は,クエリ"leopard"で収集した結果の一部について紹介する.
まず,取得できた画像のURLリストは以下のもの.(ただし一部のみ)
http://images.china.cn/attachement/jpg/site1007/20120720/00016c8b5de01172f9e82e.jpg
http://farm2.static.flickr.com/1254/1174179702_fe9c9a5d2c_b.jpg
http://www.katzen-und-kater.de/Grosskatzen/Leopard/Leopard5.jpg
...
以上より,きちんと取得できていることがわかった.
といっても,画像の類似度計算を行ってノイズを削除したりしているわけではないし,単純に上位N件を取ってきているだけでしかない.(大量に延々と収集することも未実装なのでこれも課題)
まとめ
今回は機械学習のアノテーション済み画像データの自動収集という目的(という建前)でbing画像検索から典型的な画像を収集するスクリプトを記述した.
アノテーションについては,クエリがそのまま使えるかと思う.
また,今後の課題は以下の2つが考えられる.
- 任意の数(または限りなく多く)の画像を収集すること
- 画像間の類似度などの基準をもってノイズとなる画像を削除すること
今回のスクリプトは画像検索の上位にくるものは典型的な画像であることが多いという,画像検索エンジンの特徴に依存しているため,特に上記2つ目の課題について真面目に考えたほうがいいと思う.
それについては,また今度実装しよう.