2017-02-28

アフィン変形の他の座標を取得する【Python】

前回の「 Python で画像を引っぱるように歪める」に引き続き python を使ったアフィン変形(回転、縮小/拡大、並行移動を一括で行う変形)のお話です。

アフィン変形は3点を使って回転などをするのですが、数学が苦手な私には「じゃあ、その他の座標はどうやって計算するの?」ということがわかりませんでした。
そこで、今回も備忘録的にこの記事を書きたいと思います。



まずはアフィン変形の使い方(Python)

使い方は簡単で、移動前と移動先の3つの点(つまり三角形)を行列にして変形させるだけ。
コードはこんな感じです。

 import cv2
 import numpy as np
 im = cv2.imread('squares.jpg')  
 points1 = [[50,50],[150,50],[50,150]]  
 points2 = [[75,75],[150,50],[50,150]]  
 M = cv2.getAffineTransform(np.float32(points1), np.float32(points2))  
 im2 = cv2.warpAffine(im, M, (200,200))  
 cv2.imwrite('transformed_squares.jpg', im2)  

(流れ)
1.画像を読み込む
2.移動前の点を決める
3.移動後の点を決める
4.上の2つを使って行列を取得
5.200x200サイズでアフィン変形する
6.画像を保存

※つまり、他の2点は同じなので、(50,50) の点を (75,75)に移動させるだけになります。


実際に画像は以下になります。

(変形前)


(変換後)



移動した後、その他の点は?

さぁ、ではここからが本題です。
先ほど見ていただいた画像の右下に「?」マークと少し大きな赤丸があったかと思います。
この点は変形前は (150,150) の位置にあります。
じゃあ、変形後の座標をどうやって計算したらいいの?を解決する方法です。

実際のコードはこんな形です。

 import numpy as np 
 point = np.float32((150,150))  
 x = point[0]
 y = point[1]
 new_x = M[0][0]*x + M[0][1]*y + np.float32(M[0][2])  
 new_y = M[1][0]*x + M[1][1]*y + np.float32(M[1][2])  
 print (int(new_x), int(new_y))  

変形前の点を公式に当てはめるだけでOKです。

※ M は上のコードで作った行列になります。


終わりに

行列という概念は高校の数学ででくる(らしい)のですが、正直言って今回初見ぐらいの気分でした。
ただ、画像処理にはとても便利なのでやはりきちんと数学(幾何学?)も勉強していこうと思います。
学生の頃は何に役に立つんだ?と思ってましたが、これはとても役に立つし、正直やってて面白いですね。

新しい発見でした(^o^)



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 などを使って懐かしい反面、「え!こんな便利に使えるものなんだ!」と思いました。
学校の勉強がいかに面白くなく感じていたか、、、と思う今日このごろです(笑)

ではでは。


2017-02-14

React.js は SEO に悪いか?

最近では React や Angular などの JavaScript フレームワークの開発がとても活発になっていますが、ふと「クライアントサイドでコンテンツを作ってしまったら検索エンジンはページを読み込めないんじゃ?(つまりSEO的にやばいんじゃ?)」と思ったので少し調べてみました。


検索エンジンはJSのレンダリングに対応してる?

https://medium.freecodecamp.com/seo-vs-react-is-it-neccessary-to-render-react-pages-in-the-backend-74ce5015c0c9#.qwb5reylb


こちらの記事でいろいろな調査を行っているので参考にさせてもらいました。

まずこの記事では、「SEO業者はJavaScriptは使わずHTMLを使うほうがいい」と言っているがこれは間違っていて、その証拠に Google が公式ブログで投稿したページをあげています。

内容としては

Times have changed. Today, as long as you're not blocking Googlebot from crawling your JavaScript or CSS files, we are generally able to render and understand your web pages like modern browsers.

(日本語超意訳)  JS とか CSS をブロックしてない限り Google はちゃんとページを読んでるよ。(≒検索エンジンに反映するよ!)

となっています。

これは 2015年に投稿されたものですので2017年の現在では当然のように JavaScript & CSS を使ったクライアントサイドのレンダリングにも対応していると考えていいでしょう。

さらに、個人的な感想でいうと Angular は Google の開発プロジェクトなのでクライアントサイドのレンダリングは重要視していると考えています。

※ちなみにこの記事には2016/10/25に追記があって、他の人の調査でも Google は問題なくページを読み込んでいることが分かったとしていますが、検索エンジンに反映されるには数日遅れているという結論に達しています。


他の検索エンジンは?

では、Google は問題ないとして、Bing や Yahoo など他の検索エンジンはどうなのでしょうか。
正直言って日本の検索エンジンは Google の独占状態(YahooもGoogleの検索結果をもとにしているため)なのであまり他の検索エンジンを考えなくてもいいかもしれませんが以下に彼の調査結果を紹介したいと思います。

調査の対象になったのは Preact と呼ばれるたった 3KB しかない React の軽量版のウェブページです。Preactはいわゆる SPA(Single Page Application) なので、もし Google のクローラーが JavaScript を理解できていなければ検索エンジンに表示されることはないということになります。

※ちなみにPreact は今回初めて知りました。実際アクセスすればよくわかりますがホントに超高速で表示してくれます。少し今後の展望を考えてしまいました。(^^)


結果は以下のとおりです。


ご覧いただけるとわかると思いますが、問題なくインデックスされています。

ただし、一点だけインデックスされていない検索エンジンがあったようで、それが「Baido(百度)」です。

そのため、現時点では Baido へのインデックスが必須であるなら従来通りサーバーサイドでのレンダリングをするべきでしょう。


個人的な結論

Google をはじめ、クライアントサイドでのレンダリングも問題ないようなので、SEOに関しては気にする必要はなさそうです。
しかも、我々が持っているスマートフォンなどの機会がよりハイスペックになってきているため、クライアントサイドでのレンダリングは時代にかなったテクニックだとも思います。
ホントに高速表示が可能ですしね。

ということで、今回は以上です。

2017-02-03

Vue.js 2.0 を使ってみた9つの感想

これまで、ウェブサイト開発にはメインで Bootstrp(つまり jQuery) を利用していたので、最近よく聞くようになった React、Angular、それから今回感想を書く Vue.js は敬遠していました。
なぜなら、コードがどこかで衝突するんじゃないかと敬遠していたからです。

ただ、最近の盛り上がりを見るとそうもいっていられないな、と思い今回メインとして Vue 2.0 を試してみましたのでその感想をまとめておきたいと思います。



1.速い!!

とにかく初めて Vue を使ったときに感じたのが「速い!」でした。
元々 jQuery でも遅いとは感じたことはなかったのですが、Vue はさらに快適なリアクションをしてくると感じました。
特にループでコンテンツを量産する場合では速いですね。


2.簡単!

フレームワークなりプログラミング言語なり、新しいものを採用するときにどうしても避けられないのが「学習コスト」です。
みんながいいと言ってるから便利なのは間違いないんだろうけど、一から勉強するには時間がかかってしまうのはときに大きなハードルになります。

でも、Vue ならそんな心配は不要だと思います。
正直私も一連の YouTube 動画を見ただけですぐに使いはじめることができました。

※ちなみに以下が YouTube 動画のリスト(英語)です。

動画の一覧


3.メンテナンスがしやすい

書いたコードが jQuery よりもすっきりするのでメンテナンスもしやすいですね。


4.サーバーからのサイズが(少しだけ)減る

通常 PHP などでコンテンツを作成すると フルに HTML を作成する必要があるため、ループする内容が多いときなどは特にページのサイズが大きくなってしまいます。

でも、Vue を利用するとループする部分は実際にページを見る PC やスマートフォンで作成してくれるのでサイズが比較的少なくなり、これも速さに貢献できる部分だと思います。

最近のスマートフォンはハイスペックになってきているので時代にも合っているんじゃないでしょうか。


5.jQuery との衝突がなかった

まだそこまで Vue での開発経験があるわけではないので、今後何か問題がおこる可能性はありますが、今のところ全く衝突はありませんでした。

実際に開発した例では bootstrap を利用していたので Ajax 部分や タブの切り替えなどは jQuery を利用していましたが快適に開発を進めることができました。


6.デザイナーさんにもわかりやすい

例えば、Vue を使って画像データのバインディングをする場合は

<img :src="{{ url }}">
という風に通常の HTML と同じようにパッと見ただけでわかりやすい書き方になっています。
おそらくデザイナーさんにもわかりやすいので使いやすいんじゃないでしょうか。


7.単体で動く

以前 React を使ったことがあり React もいいなとは思っていたのですが、書き始めるまでにBabel を用意するなどの必要がありました(今は違う?)。でも Vue は単体でシンプルに動きますし、cdn も用意されているのでとても簡単に開発を始められます。


8.Laravel に採用されている

まだ実際には使ってはいませんが Laravel には Vue Component という機能があり、より Vue との統合がしやすくなっています。
私は Laravel Lover ですのでここもプラス要素ですね。


9.日本語のドキュメントも用意されている

やっぱり複雑なことを学ぶには母国語が一番です。


 【結論】

とても Vue は便利で使いやすいです。
ですので、今後の開発でも積極的に利用したいと思いました。

また、バージョンがまだ2ということなので、今後開発が進むと、より便利な機能が追加されるかもしれません。

みなさんも興味があったらぜひ使ってみてはいかがでしょうか。
ではではー!