2013年8月19日月曜日

画像の回転

画像をFFTした結果の回転を行うプログラムを組む。

画像をスライスした時の値(複素数)が欲しかったので組み始めた。回転なんてちょろいと思ったら、意外と組めなかった。
Scikit-imageにもrotateという関数が準備されていたが、回転後の画像が切れてしまう。

今回は以下のページを参考にした。
http://homepage2.nifty.com/tsugu/sotuken/rotation/

Pythonでそのまま組むと速度がかなり遅い。いままで何も考えてなかったけど回転って計算負荷あるんやなー。今回は実験なので速度のことは(そんなに)気にしない。




また使うか分からんけど、一応ソースも貼っておこう。

import numpy as np

def rotate_img(src, a):
 #src: numpy array
 #rotation angle in degree
 #returns rotated image

 a = np.pi/180. * a 
 vcos = np.cos(a)
 vsin = np.sin(a)

 #calc dist image size
 wsrc = src.shape[1]
 hsrc = src.shape[0]
 wdist = int(np.abs(wsrc*vcos) + np.abs(hsrc*vsin) + 0.5)
 hdist = int(np.abs(wsrc*vsin) + np.abs(hsrc*vcos) + 0.5)

 #allocate memory
 dist = np.zeros((hdist, wdist), dtype=src.dtype)

 #center of the images
 cxsrc = wsrc / 2
 cysrc = hsrc / 2
 cxdist = wdist / 2
 cydist = hdist / 2

 for y2 in xrange(hdist):
  for x2 in xrange(wdist):
   x1 = ((x2-cxdist)*vcos - (y2-cydist)*vsin) + cxsrc
   y1 = ((x2-cxdist)*vsin + (y2-cydist)*vcos) + cysrc

   if x1 >= 0 and x1 < wsrc and y1 >= 0 and y1 < hsrc:
    dist[y2,x2] = src[y1,x1]
 return dist

def slice_img(src, a):
 #src: numpy array
 #rotation angle in degree
 #return sliced 1d array

 a = np.pi/180. * a 
 vcos = np.cos(a)
 vsin = np.sin(a)

 #calc dist image size
 wsrc = src.shape[1]
 hsrc = src.shape[0]
 wdist = int(np.abs(wsrc*vcos) + np.abs(hsrc*vsin) + 0.5)
 hdist = int(np.abs(wsrc*vsin) + np.abs(hsrc*vcos) + 0.5)

 #allocate memory
 dist = np.zeros((wdist), dtype=src.dtype)

 #center of the images
 cxsrc = wsrc / 2
 cysrc = hsrc / 2
 cxdist = wdist / 2
 cydist = hdist / 2

 for x2 in xrange(wdist):
  x1 = ((x2-cxdist)*vcos) + cxsrc #y2 = cydist
  y1 = ((x2-cxdist)*vsin) + cysrc

  if x1 >= 0 and x1 < wsrc and y1 >= 0 and y1 < hsrc:
   dist[x2] = src[y1,x1]
 return dist


if __name__ == "__main__":
 import Image
 import matplotlib.pyplot as plt
 img = Image.open("_image0-0.png").convert('L')

 a = 10.

 src = np.array(img)
 dist = rotate_img(src, a)
 sliced = slice_img(src, a)

 #dist = Image.fromarray(np.uint8(dist))
 
 plt.figure()
 plt.subplot(131)
 plt.title("original")
 plt.imshow(src, cmap=plt.cm.Greys_r)
 
 plt.subplot(132)
 plt.title("rotated")
 plt.imshow(dist, cmap=plt.cm.Greys_r)

 plt.subplot(133)
 plt.plot(np.arange(len(sliced)), sliced)
 plt.title("sliced at y = N/2")
 plt.show()



0 件のコメント:

コメントを投稿