2017年08月01日

Pythonで画像処理

Anaconda環境ですが、欲張って色々入れてしまうと競合するみたいですね。Anaconda 4.3.0(64ビット)だけインストールするようにしたら、前回のエラーが出なくなりました。

今回は機械学習で使うため画像の枚数を回転させて無理矢理増やす方法です。OpenCVに付属のcreatesamplesユーティリティの真似です。といってもあちらはx、y軸の回転や明るさの変化などもできますが。
  from PIL import Image
  import numpy as np
  import os

  # 「実践コンピュータビジョン」より改変
  def get_imlist(path, ext):
      # pathに指定されたディレクトリのすべてのext拡張子を持つ画像のリストを返す
      return [os.path.join(path,f) for f in os.listdir(path) if f.endswith(ext)]

  folder = "./image"
  filelist = get_imlist(folder, '.jpg')

  # 増やしたい枚数
  samples = 100
  # クラス番号
  classNo = 1

  # 増やした画像ファイル名とクラス番号のリスト
  txtfile = folder + "imagelist.txt"
  fout = open(txtfile, 'wt')

  # 画像ファイルの数だけ繰り返す
  for infile in filelist:
      # splitext: パス名を(root, ext)のペアに分割
      root = os.path.splitext(infile)[0]
      # -180.0〜180.0の回転角度を乱数で生成
      randDeg = 360.0 * np.random.rand(samples) - 180.0

      # 増やしたい枚数だけ繰り返す
      for idx in range(samples):
          # ゼロパディングしたファイル名を作成
          # 参考URL: http://www.lifewithpython.com/2015/10/python-zero-padding.html
          number_padded = '{0:05d}'.format(idx)
          filename = root + "_" + number_padded + ".png"
          # ファイル名をテキストファイルに書き出す
          fout.write(filename + ' ' + str(classNo) + '\n')
          # 画像を開いて乱数の角度で回転して保存
          out = Image.open(infile).rotate(randDeg[idx])
          out.save(filename)

  # ファイルを閉じる
  fout.close()
機械学習の時は画像のパスとクラス番号が書かれたファイルもよく使いますので、それも出力するようにしてみました。

forループのところなどはpythonに慣れていればもっとスマートに書けそうですが。後、既に混ざってしまってアレですが、シングルクォートとダブルクオートってPythonだとどういう扱いなんですかね。C言語だと文字定数と文字列の違いがあったのですが…。

実行結果

Lenna00000.png
Lenna.jpg1枚から回転した100枚が増えました。

参考文献
[1] Ja Erik Solem著,相川 愛三 訳,「実践コンピュータビジョン」,オライリー・ジャパン
[2] Bill Lubanovic著,斎藤 康毅 監訳,長尾 高弘 訳,「入門Python3」,オライリー・ジャパン
[3] Python Tips: Pythonでゼロパディングしたい
web拍手 by FC2
posted by シンドラー at 18:00 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする