Murayama blog.

プログラミング教育なブログ

ImageNetから画像データをダウンロードする方法

機械学習、画像認識を始めると「大量の画像データないかなー」とググることになります。そうするとすぐにImageNetなる存在に気づきます。

ImageNet

ImageNetとはスタンフォード大学がインターネット上から画像を集め分類したデータセット。一般画像認識用に用いられる。ImageNetを利用して画像検出・識別精度を競うThe ImageNet Large Scale Visual Recognition Challenge(ILSVRC)などコンテストも開かれる。(:AI白書より引用)

ILSVRC、2012年のコンテストでディープラーニングを使ったチームが圧勝した話も有名です。

それでImageNetのサイトを訪問すると、画像を検索して、そんで画像選んで、ダウンロードしようとするとURLの一覧が表示されてー。え。これからどうしようとなります。一括ダウンロードするサンプルプログラムもネット上にいくつかありますが、Python2系のものだったり、すぐに動かなかったので自分の勉強用に作ってみました。Anacondaとか入れておいて必要なライブラリが揃っていれば動くと思います。

ダウンロードできる画像は、著作権フリーというのではないので、自己学習用のものです。

import sys
import os
from urllib import request
from PIL import Image

def download(url, decode=False):
    response = request.urlopen(url)
    if response.geturl() == "https://s.yimg.com/pw/images/en-us/photo_unavailable.png":
        # Flickr :This photo is no longer available iamge.
        raise Exception("This photo is no longer available iamge.")

    body = response.read()
    if decode == True:
        body = body.decode()
    return body

def write(path, img):
    file = open(path, 'wb')
    file.write(img)
    file.close()

# see http://image-net.org/archive/words.txt
classes = {"apple":"n07739125", "banana":"n07753592", "orange":"n07747607"}

offset = 0
max = 10
for dir, id in classes.items():
    print(dir)
    os.makedirs(dir, exist_ok=True)
    urls = download("http://www.image-net.org/api/text/imagenet.synset.geturls?wnid="+id, decode=True).split()
    print(len(urls))
    i = 0
    for url in urls:
        if i < offset:
            continue
        if i > max:
            break

        try:
            file = os.path.split(url)[1]
            path = dir + "/" + file
            write(path, download(url))
            print("done:" + str(i) + ":" + file)
        except:
            print("Unexpected error:", sys.exc_info()[0])
            print("error:" + str(i) + ":" + file)
        i = i + 1

print("end")

imagenet.pyとかで保存して、

python imagenet.py

みたいにプログラムを実行すると apple, banana, orange 3種類の画像をダウンロードしてきます。カレントフォルダ上にapple, banana, orangeフォルダができます。

apple, banana, orange以外の画像を集めたい場合は以下の部分を編集してみてください。

# see http://image-net.org/archive/words.txt
classes = {"apple":"n07739125", "banana":"n07753592", "orange":"n07747607"}

ImageNet上にwords.txtというファイルがあり、そこに画像分類ごとのIDみたいなのが振られています。

それからダウンロードする枚数は以下の部分で調整できます。

offset = 0
max = 10

なんとなく見た感じだと、apple, banana, orangeだと1000枚程度はあるので、maxを2000くらいにしておけばそれなりにデータが揃います。offsetは続きからダウンロードしたいとき用です。

あとImageNetからの画像のリンク先がFlickrであることが多く、公開停止になっているリンクも多いです。その場合、エラー画像をダウンロードしてしまうので、その部分を回避するコードです。

response = request.urlopen(url)
if response.geturl() == "https://s.yimg.com/pw/images/en-us/photo_unavailable.png":
  # Flickr :This photo is no longer available iamge.
  raise Exception("This photo is no longer available iamge.")