2017-02-24

Python で画像を引っぱるように歪める

最近の開発で python の画像処理を勉強しているのですが、なかなか「引っぱるように画像を歪める」ということができませんでした。
いわゆる gimp でいうところの「対話的歪め」とか iwarp というやつです。
そして、それを今回なんとか実現することができましたので、備忘録として残しておこうと思います。

(追記) pip でインストールできるようパッケージ化しました

 PiecewiseDistortion


(つまり画像で言うと↓↓↓)


ということです。

※ちなみにこの処理には scikit-image を利用するので以下のようにインストールをしておいてください。

pip install scikit-image
 
 

まずは手順

手順としては

  1. 歪めたい範囲を指定
  2. どこからどこまで移動させたいかを指定
とするとやりたいことが実現できました。


実際のコード

では実際のコードを紹介します。

import skimage.transform  
from PIL import Image  
import numpy as np  

def distort(file_path, roi_points, from_points, to_points):  
    im = Image.open(file_path).convert('RGBA')  
    from_points = np.concatenate((roi_points, from_points))  
    to_points = np.concatenate((roi_points, to_points))  
    affin = skimage.transform.PiecewiseAffineTransform()  
    affin.estimate(to_points, from_points)  
    im_array = skimage.transform.warp(im, affin)  
    im_array = np.array(im_array * 255., dtype=np.uint8)  
    if im_array.shape[2] == 1:  
        im_array = im_array.reshape((im_array.shape[0],im_array.shape[1]))  
    warped_im = Image.fromarray(im_array, 'RGBA')  
    im.paste(warped_im, (0, 0), warped_im)  
    return im  

file_path = 'lena.jpg'  
roi_points = [(100,100),(400,100),(400,400),(100,400)]  
from_points = [(300,300),(250,250)]  
to_points = [(350,350),(200,200)]  
im = distort(file_path, roi_points, from_points, to_points)  
im.save('lena_distorted.jpg')  


(上のコードを実行した結果↓↓↓)


※画像のサイズは 512x512でした。元画像の lenaさんには申し訳ないですがうまくゆがんでいるのがわかるかと思います。


この作業を通じて思ったこと

どこかの記事で「プログラミング別収入ランキング」というのを読んだことがあるのですが、たしか python が一位でした。
その時はそうなんだ、ぐらいに思っていたのですがその理由が少し分かった気がします。
つまり、

python の収入が高いというよりは、python は数学、科学との連携が強みのため、そういった理数系の知識が豊富な開発は収入が高い

ということになるのだと思いました。
やっぱり理数系の知識って必要ですね。
今回久しぶりに sin cos などを使って懐かしい反面、「え!こんな便利に使えるものなんだ!」と思いました。
学校の勉強がいかに面白くなく感じていたか、、、と思う今日このごろです(笑)

ではでは。


0 件のコメント:

コメントを投稿