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ということなので、今後開発が進むと、より便利な機能が追加されるかもしれません。

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


2017-01-24

顔の入れ替えを試してみた【Ubuntu】

ふとしたきっかけで画像の顔だけを入れ替える(正確にはある画像の顔を別の人の顔にする)というプログラムが公開されているのを知ったので、いつも利用しているPCにインストールして試してみました。
思ったより簡単にインストールできたので興味のある方はぜひ試してみてください。

【実行環境】 Ubuntu 16.04


※顔の入れ替えにはPythonが利用されています。もしPythonがインストールされていない場合はインストールしておいてください。


【手順1】 まず、メインとなるPythonプログラムは GitHub で公開されています。
そのため、まずこのプログラムを以下のようにしてダウンロードしましょう。


ダウンロードしたら適当な場所に展開しましょう。


【手順2】 そして、ついでにもうひとつダウンロードする必要があるので以下のようにGitHubのリンク(SourceForge)からダウンロードして中身を展開しておきます。


【手順3】 以下のURLへアクセスし、ページ中央からdlib C++ Libraryをダウンロード、これも展開しておきましょう。



展開したらそのフォルダにターミナルで移動し、以下の順番でコンパイルします。

cd examples
mkdir build
cd build
cmake ..
cmake --build . --config Release

そして、またdlibトップフォルダに戻り、setup.py を実行します。

sudo python setup.py install


【手順4】そして、Pyhon用の OpenCV もインストールしましょう。

sudo apt-get install python-opencv
 
 
では次に【手順1】で展開したフォルダの中に入って「faceswap.py」を
テキストエディタで開くと、

PREDICTOR_PATH = "/home/matt/dlib-18.16/shape_predictor_68_face_landmarks.dat"
 
という行があるはずなので、このパスを【手順2】でダウンロードしたファイルを指定します。

※私の環境では以下のようになりました。

PREDICTOR_PATH = "/home/sukohi/Downloads/shape_predictor_68_face_landmarks.dat"


【顔の入れ替えを実行】
では準備が完了したので実際に試してみましょう。
画像は以下の2枚をPixabay からダウンロードしてきました。

 face.jp

head.jpg

うまくいくと、head.jpg の顔が face.jpg の顔と入れ替えになります。

では、この2つの画像を【手順1】で作成した faceswap のフォルダの中に保存し、
以下のコマンドを実行しましょう。

sudo ./faceswap.py head.jpg face.jpg

うまくいくと output.jpg という画像が作成されているはずです。
上の画像を使って実際に作成されたは以下になります。



どうでしょう、すごくないですか?
お気づきかと思いますが、face.jpg 顔の暗い部分も元画像に適用されて
一枚の写真になっています。
こんなプログラムが公開されているなんてすごい時代になりましたね。

※ちなみに、入れ替えたい顔の目や口元などに髪の毛がかかってしまっていると
あまりうまくいかないパターンもありました。
また、背景にいろいろとものが写っていたりすると顔を検出できないパターンや、
まれなケースでは全く別の部分に顔が移植されてしまうこともありましたので
まだ完璧ではないようですが、こういうのを作る人ってすごいですよね。

今回は以上です。


2016-12-20

ファビコンを自動でつくってくれるサイト「Favicon Generator」を使ってみた。

サイト開発をしていて結構めんどくさい作業なのがファビコンの作成です。
特にこだわらない場合は favicon.ico というファイルを ico 形式の画像を作ってリンクすればいいだけですが、iPhoneなど様々な機種に対応させたい場合は個別に画像を用意してその全てにリンクなど HTML タグを追加しなければいけません。

そこで紹介するのが「Favicon Generator」です。

このサイトは画像を送信するだけで、様々なサイズのファビコンを作成してくれるというとても便利なサイトです。
また、必要なHTMLタグも表示してくれるので、それらをコピーするだけで設定も完了します。

では、作り方をひとつひとつ見ていきましょう。


1.画像のアップロード

画像の赤枠にあるボタンをクリックしてファビコンにしたい画像を選択します。

※注: 最低でも 70 x 70 px 以上の画像を選んでください。推奨は260 x 260 px 以上です。



2.ファビコンの設定をする

ここから iPhone など各機種向けの設定をします。

注意が必要なのは iOS です。
iOS のアイコンは透過画像に対応していません。
そのため、もしファビコンに png などの透過画像が利用されている場合、背景が真っ黒になってしまします。

これを防ぐためには以下の赤枠のラジオボタンにチェックを入れ、その下の色の設定を変更する必要があります。


その他 chrome や windows の設定ができますが、同じように設定を変更すると自動でサンプル画像が変更しますのでお好みの設定に変更してみましょう。

なお、もしファビコンをルートフォルダに設置したくない場合は、最後の項目で調整ができます。(ルートでいい場合はに特に設定する場合は必要ありません。)



3.ファビコンの作成

さぁ、それではファビコンを作成しましょう。
一番下にある以下のボタンをクリックすることで実行できます。


4.ファビコンのダウンロードと設置


まず「Download your package.」の横にある「Favicon package」ボタンをクリックするとダウンロードが始まりますので適当な場所に保存してください。
そして、保存した zip ファイルの中にあるファイル全てをサイトのルートフォルダへ展開します。
(つまり、http://example.com/favicon.ico にアクセスできるようになればOKです)

次に2個めの赤枠内の HTML コードを <head>〜</head>内に書き込みましょう。
これで設定は完了です。

5.テスト

もしきちんと設置されたかをテストしたい場合はチェックコンテンツも提供されていますので使ってみることをおすすめします。


なお、元になるファビコン画像を作りたいときは font-awesome で画像が作成できる fa2pngが便利です。 

今回は以上です。
おつかれさまでした。

2016-12-08

Laravel で全 view からログイン中のユーザー情報を取得する

Laravel を利用して開発をしていると、まだまだ全ての機能を使いきれていないことに気付かされることがあります。
ということで今回は ViewComposer を使って、どのビューからでもログイン中のユーザーにアクセスできるようにしてみたいと思います。

【実行環境】Laravel 5.3


手順は以下の3つです。
  1. ViewComposer を作る
  2. ServiceProvider を作る
  3. ServiceProvider を登録する

ではひとつひとつ見ていきましょう。

1. ViewComposer を作る

まず ViewComposer の作成です。
デフォルトでは専用のフォルダは用意されていませんので app/Http/ViewComposers というフォルダを新たに作成しましょう。
そして、その中に AuthViewComposer.php というファイルを作成&以下のコードを保存します。
 <?php namespace App\Http\ViewComposers;  
 use Illuminate\View\View;  
 class AuthViewComposer  
 {  
   protected $user;  
   public function __construct()  
   {  
     $this->user = \Auth::user();  
   }  
   public function compose(View $view)  
   {  
     $view->with([  
       'user' => $this->user  
     ]);  
   }  
 }  


2.ServiceProvider を作る

次に専用の ServiceProvider を作ります。
app/Providers/ViewComposerServiceProvider.php を作成&以下のコードを保存してください。
 <?php namespace App\Providers;  
 use Illuminate\Support\ServiceProvider;  
 class ViewComposerServiceProvider extends ServiceProvider  
 {  
   public function boot()  
   {  
     \View::composers([  
       \App\Http\ViewComposers\AuthViewComposer::class => 'layouts.*'  
     ]);  
   }  
 }  
※ ちなみに layouts.* の部分ではどの view に適用するかを設定することができます。


3.ServiceProvider を登録する

最後は先ほど作った ViewComposerServiceProvider を config/app.php へ登録します。
 'providers' => [  
   App\Providers\ViewComposerServiceProvider::class,  
 ],  

さあ、以上で設定は完了です。好きな view の中で {{ $user->email }} という風にユーザー情報にアクセスしてみましょう。
なお、念のために、以下のコマンドを実行しておくといいかもしれません。
 composer dumpautoload -o  

今回は以上です。
お疲れ様でした。



2016-11-10

Wikipediaを使って関連キーワード抽出プログラムを作ってみる

関連キーワードが必要になった

現在取り組んでいるプロジェクトの中で、キーワードを入力すると関連するキーワードを

「このキーワードもおすすめですよ」

という具合で表示する機能が必要になりました。

はじめはGoolgeのSuggestを利用すればいいかなと安易に考えていたのですが、この方法では関連するキーワードではなく、追加キーワードの提案という形になってしまいます。

実際の例をご覧ください ⇛ 「明石家さんま」をGoogle Suggestで検索

そうではなく、結果としては「明石家さんま」で検索すると「ビートたけし」や「タモリ」などといった関連するキーワードを取得したかったのでGoogle Suggest の利用は見送ることにしました。
(また、Googleに限らずAPIなどの提供は廃止されるリスクが常につきまとうという理由もありました。)

おもしろいアプローチを見つける

そこで、他の方法はないかとネットを探っているとひとつおもしろいアプローチをしている人がいました。それが以下のページです。

 [Yahoo!WebAPI+TwitterAPI]2つのAPIを組み合わせて関連キーワード抽出ツールを作ってみる

※ブログ記事、カッコ良かったのでオマージュさせていただきました。m_ _m


このページが提案している方法は以下になります。

1.まず Twitter API を使って検索したいキーワードのツイートを取得
2.Yahoo API のキーフレーズ抽出を使ってそのツイートから共通するキーワードを取得する
3.頻出する言葉が関連キーワード

つまり、検索するキーワードと一緒に使われている言葉を抽出するというアプローチです。

早速やってみた、、、しかし!

なるほど。
賢い人がいるものだなと感心し、実際に私もこのアプローチを試してみました。

・・・が!
結果はうまくいきませんでした。

なぜなら、現在Twitter に投稿されるものは無差別投稿しているものも多く、全く関連しないキーワードばかりが抽出されてしまったからです。

しかし、一緒に使われている言葉を抽出するというアプローチ自体はとても良い方法なのでなんとかTwitter以外の方法で考えてみることにしました。

YoutubeやHatena...
どれも納得できるような結果にはなりませんでした。

加えて、やはりAPIはそのうちにサービスが終了してしまうリスクも心にひっかかりこれら方法も断念しました。

そうだ wikipedia を使おう

そして、最終的に考えだしたのが Wikipedia を利用する方法でした。
流れとしては以下になります。

1.検索キーワードのことが書かれたwikipedia のページを読み込む
2.共通するキーワードを抽出(サイト内リンクのテキストを正規表現を使って取得)
3.集計して数が多いものを関連キーワードとする

この方法だと、APIが終了することはないですし読み込むページも1ページのみでいいのでレスポンスも早くすることができます。

さらに、関連語の抽出具合もより精度が上がったように思います。
以下は「明石家さんま」で検索した例です。
  • FNS27時間テレビ
  • ビートたけし
  • FNSの日
  • タモリ
  • 島田紳助
  • SMAP
  • さんま・中居の今夜も眠れない
  • フジテレビジョン 
  • 笑福亭鶴瓶
  • 所ジョージ 
※ちなみに以下のようなキーワード(リンク)は必要ないのでフィルターをかけて抽出しないようにしました。

1.Template: や Help: など wikipedia の特殊なリンク
2.年月日のみのリンク

ということで、このプログラムをクラス化しGitHubで公開していますので、実際のソースはそちらをご覧ください。

※ちなみに上記プログラムではHTTPアクセスにはGuzzleのバージョン6を利用しています。composerを利用してインストールする方法が楽かと思いますが、もしGuzzleを使いたくない人は file_get_contents() に書き換えて利用してみてください。

デモを見る


以上、Wikipediaを使って関連キーワードを抽出する方法でした。