読者です 読者をやめる 読者になる 読者になる

アラタナエンジニアブログ

aratana Engineer's Blog

【Raspberry Pi 2 Model B】増え続ける子どもの写真管理に特化したNASを構築しよう(第1回:技術ネタまとめ編)

f:id:issei-homan:20150217130254j:plain
0.自己紹介
アラタナエンジニアブログをご覧の皆様、初めまして。生涯現役でいたいと願っている穗滿です。ブログはアラタナ設立後1年くらいやってましたが、その後7年くらいやってないので時代についていけているのか心配です。


さて、そんな感じなので難易度の高い内容は他のスタッフにやってもらうとして、僕は今日からでもチャレンジしたくなるような、生活に密着したプチ便利で、簡単、美味しい話題をモットーに記事を書いていきたいと思います。といっても今回は技術ネタまとめ編のため、実施前の情報収集になります。高専出身なので、ちょっと実験レポート風になってます(笑)。普段何気に使ってるテクノロジーに対して、深ぼってみる機会として考えています。


最近の美味しい話題といえばもちろん「Raspberry Pi(ラズベリーパイ) 2 Model B」ですよね。もう名前からして美味しそう!小さなLinuxベースコンピュータボードで、サーバーを作ったりできる代物です。どのくらい小さいかというと、名刺と比較した画像を以下にご用意しました!なんと同じサイズ!!! 2015年2月上旬に最新バージョンが発売されたばかりの、アッツアツのパイです。

f:id:issei-homan:20150217205211j:plain
名刺と大きさ比較


Raspberry Pi で何をしようと思っているかというと、QNAPのような多機能NASを自作したいと考えています。さらにその中でも画像処理と閲覧機能を強化したいと考えています。


2014年8月に子供が生まれてから、ものすごい勢いで写真と動画が増え、なんか対策を練ろうと思っていました。2009年くらいから1TBのメーカー製NASを使っているのですが、CPU的性能に不満、そろそろHDD壊れるかも=NAS専用HDDって高すぎ、RAID 5で組んでるけど同時期生産・同時期利用開始したHDDであれば同時に壊れる可能性もあります。ということはRAID よりも異なるメーカーの安いHDD複数台にミラーリングしつつ、AWSのS3あたりに自動バックアップ取っておくほうがよっぽど冗長性あるかもとか考えていたら、自作したくなってしまいました。こんな時に自分で作れるプログラマっていいですね!ちなみに、僕は初めてRaspberry Piを触りますので処理能力の限界をしりません。なのでやりたいことをとりあえずやってみて、限界を見定めるのも今シリーズ記事の趣旨とします。2台もってますので、必要に応じて複数台構成でやっていこうと思います。

また、画像は今はDropboxに買収されてしまって新規ユーザーは利用できなくなってしまった「Snapjoy」のように、時系列で写真を見やすく、カッコよくレイアウトするサイトを作ってしまおうと思っています。


f:id:issei-homan:20150218100827p:plain



さて、前置きが長くなってしまいましたが、料理の準備に取り掛かりましょう。



数千円で手に入る小型のLinuxベースコンピュータボード「Raspberry Pi」の基礎を学び、ライフスタイルが楽しくなるように応用(料理)していく。今回は日々たまり続ける写真や動画の管理に特化したNASを構築する。


(以下、Raspberry Pi Model B+を「従来モデル」、Raspberry Pi 2 Model Bを「新モデル」と言います。)

f:id:issei-homan:20150217130415j:plain

Raspberry Piは基本的なコンピュータ科学の教育を促進することを意図して開発されたLinuxベースのコンピュータボードです。$35(日本円で約4,300円)程度で手に入ります。詳しいことの大概はWikipediaに掲載されていますので省略します(3分クッキングっぽく)。ここで強調したい事として、従来モデルに比べて、新モデルでは以下の部分が強化されていることです。


プロセッサ
従来モデルでは『ARM1176JZF-S 700 MHz シングルコア(ARM11 ファミリ)Broadcom「BCM2835」』を搭載していたのに対し、新モデルは『ARM Cortex-A7 900MHz クアッドコア Broadcom「BCM2836」』を搭載。


メモリ
従来モデルでは512MB、新モデルでは1GBを搭載。


これらの強化により、従来モデルに比べ新モデルは性能が6倍向上したと謳われています。加えて価格やボードの大きさが同等であることから、新モデルは2015年2月現在品薄状態となっています。また次期WindowsであるWindows 10で、Raspberry Pi 2がサポートされるとのことで話題になりました。


ちなみに、人気の箱庭シミュレーションゲームMinecraft」の Raspberry Pi 移植バージョンも存在していて、なんと無料です。もう美味しさ満載の RaspBerry Pi。この記事をみて1〜2人くらいはカートに入れたくなったのではないでしょうか!?


日本のRSオンラインで入手できます。ただし2015年2月時点で品薄となっていることから、早く欲しい方はYahoo!オークション等でも売りに出されている方がいますので、確認するとよいでしょう。ちなみに海外サイトで購入も可能かと思いますが、配送の時間、梱包や扱いが粗悪な可能性があるので、あまりおすすめできません。


f:id:issei-homan:20150217131609j:plain
microUSBケーブル
f:id:issei-homan:20150217131615j:plain
microSDカード

  1. microSDカード / 最低8GB SDHC Class10以上(1,000〜2,000円程度)※今回は32GBを用意
  2. 1.2A以上供給可能なmicroUSBケーブル&ACアダプター(1,500円程度)
  3. 画面表示用のHDMIケーブル(500円程度)&表示可能なディスプレイ(既存のPCモニター、TVなど)※SSH経由でアクセスする場合は不要
  4. USBキーボード&マウス(既存のPCで使ってるものでも)


Raspberry Pi 単体はPCでいうならばCPUとメモリがオンボードになったマザーボードという感じのため、OSをインストールするためのSDカードと電源供給するACアダプタ、ケーブルを別途調達する必要があります。


Raspberry Pi 2 Model BではHDDの代わりにmicroSDカードにOSを入れて動作します。microSDはおそらく一番消耗が激しいパーツになるので、できるだけ延命処置が取れるようにします。Swapやログ書き出しなどは、RAMかもしくは別でつないだHDDなどに書き出すように設定するのが良いです。また容量が大きい方が連続書き込みされる割合が少なくなるという視点から、できれば16GBや32GBを使う方が良いという情報もあるようです。そのほか、Raspberry PiとSDカードの相性もあるようですので、一度チェックされるとよいでしょう。


電源は電圧5V、電流1.2A以上が供給できるAndroidスマホなどの充電で利用しているMicroUSBケーブルとACアダプターが必要ですが、USBが4ポートあることなどを考えると2A供給できるのがベストです。この2A供給できるACアダプターは思いの外みつかりにくいです。iPad用のアダプターが10W(5V、2A)なので、僕はそれを使うことにしました。ちなみにUSBから供給可能な電力は3W(5V, 600mA)ですが、設定により6W(1200mA)まで供給可能なようで、これによりUSB HDDなどを接続して稼働させることができるので、NASが構築できます。詳細は必要に応じて今後説明します。


このほか、必須ではありませんが金属等に触れることでショートして壊れることを防ぐために、プラスチックやアクリル製のケース(500〜1,000円)に入れて使うのが良いと思います。CPUなどの性能があがると温度が上がりやすいので、300〜500円で手に入るヒートシンクもつけておいたほうが良さそうです(クロックアップする場合は絶対!)。

f:id:issei-homan:20150217131334j:plain
専用ケース
f:id:issei-homan:20150217131358j:plain
ヒートシンク



デジカメで撮影された静止画(写真)は、大概JPEG(Joint Photographic Experts Group)形式になっていると思います。一般的なJPEG非可逆圧縮が採用されています。非可逆圧縮は上書き保存してしまうとクオリティを元に戻す(復元する)ことができませんが圧縮率と画質のバランスを見ながら圧縮することができます。R(レッド)G(グリーン)B(ブルー)が各色0〜255の256段階(つまり2の8乗なので8ビット)、合計で24ビットフルカラー(約1,677万色)に対応しているので、色数の多い一般的な写真に向いた形式です。人間の目はだいたい700万色〜1000万色程度を見分けられると言われているので十分です。圧縮率をあげ過ぎるとモアレ(干渉縞)が目立つので注意が必要です。


24ビットフルカラーの場合、1ピクセルにつきRGB各色合計の24bit(=3バイト)も使って表現していて、これに画素数(横縦ピクセル)を掛け合わせたものが最終的に画像サイズになります。ただしJPEGで画像が生成される場合は少し圧縮されるので、同じ画素数であっても容量はマチマチになります。ここで重要なのは、例えばRが0であっても255であってもそれを表現するのに8bit必要、それが3色分1ピクセルが要しているので、そりゃ画像って容量大きくなるよねという話です。それではJPEGではどのように画像を圧縮してるのでしょうか。


JPEGの圧縮の仕組みは結構複雑です。圧縮について考える際の前提として「人間の目は明るさには敏感だが、色変化には結構鈍感である」ということです。JPEGではまず最初に、RGBからYUV(輝度色差信号)に変換します。Yは輝度で、Yだけを表示するとグレースケールと同様の画像が得られます。UはR(レッド)からYを引いたもの、VはB(ブルー)からYを引いたもので表現されます。Yは各ピクセルで保持されますが、UVは2〜4ピクセルで1情報となり、容量的には2/3程度になります。この時点で色差信号情報がRGB形式よりも失われるため少しぼやけた感じになりますが、先の通り人間が敏感な明るさであるYは1ピクセルずつあるので、その変化に気がつきにくいです。さらに画像を8×8ピクセルのタイル状のブロックに分割し、ブロック単位で信号圧縮に広く用いられている「離散コサイン変換 (DCT: discrete cosine transform) 」を施して空間領域から周波数領域へ変換します。画像が周波数?となってしまうかもしれませんが、画像の濃度値をパラメータとしてグラフを書くことにより、明るさの変化に応じて波を形成することができます(Fireworksなどの画像処理ソフトでも色の分布を知ったり補正できるレベル補正などがあると思います)。この後、量子化によって情報量を落とします。周波数が高い画像というのはコントラストや輪郭がはっきりしたものが多いことを示していますが、通常の写真は輪郭はあんまりはっきりしてないはずなので低周波に寄るケースが多い、と考えることができます。JPEGでは周波数の高い部分をカット(周波数の低い方に寄らせる)する考えですこしぼやけたような処理を施しながら、人間の目で判別つきにくい部分をカット(ぼやかす、平均化)することで結果的に画像容量を圧縮しているわけです。なので、イラストなどいろいろはっきりしている画像には向いていないわけです。JPEGを書き出す際に画質をパーセンテージ指定する際には、この量子化の程度を調整しているものと思われます。最後に残った規則的な情報に対し、ZIP圧縮などにも利用されるハフマン符号(可逆符号)によるエントロピー符号化がなされ、圧縮完了です。JPEGの仕様の詳しいことに関しては日本語のWikipediaよりも英語のWikipediaの方に掲載されています。


デジカメで撮影したJPEG画像には、目に見えている画像以外にもJFIF、さらにそれを拡張したExifというメタ情報を含んでいます。例えば、「撮影日時」「撮影機器のメーカー名」「撮影機器のモデル名」「画像全体の解像度」「シャッタースピード」「絞り(F値)」「サムネイル画像」などです。スマートフォンなど位置情報が取れる機器で撮影した写真では緯度・経度の「GPS情報」なども含まれます。専用のソフトやプログラム言語でExif情報を扱うことができますが、画像全体の容量を見た目以上に増やしている原因にもなっています。ただ、これらの情報は上手く使えば面白いので、これから作るシステムでは以下のような流れでExif情報をDBに格納し、画像自体からは削除して画像容量を削減できないかチャレンジすることにします。


JPEGmini という見た目のクオリティを損なわず1/3〜1/6までも画像容量を減らすアプリ・サービスが大人気です。無償バージョンもありますが、1日の利用枚数が20枚に制限されていますので、有料版を使っている方も数多くいます。ちなみに、このJPEGminiの仕組みを推測された記事を小飼弾(オン・ザ・エッジ(後のライブドア)の元取締役、PerlのJcode.pmを作った方でも有名)さんがブログに書かれているので、読んでみると面白いです。サーバーで動作するバージョンもあるようですが、ここではフリーソフトウェアGPLライセンスのライブラリを列記しておきます。これらを利用することでJPEGminiほどの高品質で低容量のものは難しくてもそれに近い状態を実現できるはずです。各種ライブラリの利用実績は別の回に考察し、採用するものを決定したいと思います。ちなみにGoogleもこのような画像圧縮技術を用いた画像をWebサイトで利用することを推奨してます

  1. jpegtran - JPEGのハフマンテーブルを最適に配置しなおす、Exifなどのメタ情報を削除することで、ロスレスサイズダウンが可能だとしています。フリーソフトウェア
  2. jpegoptim - 同じくExifなどメタ情報を削除でき、さらに再圧縮するために品質、または希望するサイズ容量を指定できる。GPL Version 2 License。


いろんな言語でExifを扱うことができます。Raspberry Pi では Pythonが標準のプログラム言語のようなので、Pythonで実装するのが一番シンプルかもしれません。

  1. Python: ExifRead 2.0.2 : Python Package Index
  2. PHP: PHP: exif_read_data - Manual


Facebookで顔写真と認識されると、知人をタグ付けしたり「もしかしXXさん?」というような機能があります。そのほかにもGoogle Gogglesなども挙げられます。つまり画像を認識して人間だとか物などを判断していることになります。これは物体照合、物体検出、画像分類、シーン理解などをプログラム的に行っていることになります。

この記事のシリーズでは、OpenCVというBSDライセンスのオープンソフトウェアを使うことで顔認識ができるようにしたいと考えています。


詳しくはGigazineの記事「JPEG画像の約半分のファイルサイズで同品質のものを表示できる画像形式「BPG」が誕生、実際に使ってみるとこんな感じ」をご覧いただきたいですが、現時点ではJavascriptを読み込ませることで既存ブラウザでも表示できるようになっています(そういえばPNGが出始めたころもそんな感じでしたっけ)。以前Windows環境で景を切り抜いた真っ白のJPEGをBPGに変換してみたのですが、画像の”ふち”が灰色のグロー掛かってしまって汚くなってしまいました。圧縮率などの設定が悪かった可能性もあるので、機会があれば試してみようかと思います。可逆圧縮にも対応していて、今後の画像の注目株です。


まず、ローカルでの冗長性構想についてですが、先述のようにRAIDを考えるのではなくて、単に異なるメーカーのHDD(またはSSD)を複数個用意し、それぞれにミラーリング保存することを考えたいと思います。使える容量は総容量の半分程度になってしまいますが、違うメーカーのHDDや容量の異なるHDDであっても使えるので便利です。ただ、物理的に同じ場所にあると地震などで一緒に壊れる恐れもあるので、余裕があればAWS S3などネット上のストレージにバックアップが取れてると完璧かと思います。

1TBであれば、Dropboxプロが1,200円/月Google Driveが(Gmailなどと共通ですが)$9.99/月(円為替の影響を受けそうです)、AWS S3が$30.0/月となっています。ただし、S3については1TB=1000GBで単純計算していることと、1TB使うまでは固定費ではなく1GB毎の従量課金のため、実際には1TB未満の場合では固定で$30かかるわけではありませんのでもう少し安くなると思います。また、別途OUTしていく通信料が加算されます(INは無料)。これらの情報を元にいずれかのストレージに保存していくことを決めていきたいと思います。技術ネタとしてはS3がスマートかもと思っています。


さて、今回は導入編ということでこれからやりたいことの基礎知識を中心にお送りしました。何気なく普段仕事で使ってる情報やテクノロジーは、先人の努力や知恵の恩を受けてるなーって感じますよね。写真管理に特化したNSAを作るための情報として大体集まってきましたので、次回以降は実践編としてお送りします!