最小二乗法を用いた直線式の算出

二次元空間上に分布する2つ以上の座標集合を直線で近似する際、最小二乗法という手法を使います。

定義

直線の式を一次関数

[math]f(x)=ax+b\,[/math]

とおくと、直線の傾き a と切片 b は次の式で求めることができます。

[math]a=\frac{\displaystyle n\sum_{k=1}^n x_ky_k-\sum_{k=1}^n x_k\sum_{k=1}^n y_k}{\displaystyle n\sum_{k=1}^n x^2_k-\left( \sum_{k=1}^n x_k \right)^2}[/math]

[math]b=\frac{\displaystyle \sum_{k=1}^n x^2_k\sum_{k=1}^n y_k-\sum_{k=1}^n x_ky_k\sum_{k=1}^n x_k}{\displaystyle n\sum_{k=1}^n x^2_k-\left( \sum_{k=1}^n x_k \right)^2}[/math]

Ruby スクリプト

この式を Ruby で書いていきたいと思います。

まず、座標値の集合を配列で定義します。

s = [[ 32.0,  24.0],
     [131.0,  62.0],
     [159.0, 110.0],
     [245.0, 146.0]]

今回は4つの座標値をサンプルとして用います。配列の中は、

[[x0, y0], [x1, y1], ... ]

という構造として扱います。 次に、ab を求めなければいけないのですが、上の式で頻出している数列の総和[math]\sum_{k=1}^n[/math]をシングルトンメソッドとして座標値集合 s に突っ込みます。

def s.sum(&b)
  self.inject(0.0) do |t, pnt|
    t + b.call(pnt[0], pnt[1])
  end
end

この sum メソッドは、自身の全ての要素について与えられたブロック引数を処理し、その結果の総和を返すメソッドです。Enumerable モジュールに組み込まれている inject メソッドもそもそも総和を求めるメソッドなのでそのままabを求める式に利用することも可能ですが、呼び出し側で最低限の記述をしたいために sum メソッドでラッピングしています。

つまり、

[math]\sum_{k=1}^n x_k+y_k[/math]

という式は、

s.sum {|x, y| x + y}

というシンプルなブロック構文付きのメソッド呼び出しに置き替えることができます。今回の場合、k は 1 から総数 n まで、つまり全ての要素についての処理のみしかありませんので、sum メソッドにはこれらを指定する引数は取りません。

この sum メソッドを用いて n, a, b をそれぞれ記述すると、次のようになります。

n = s.size.to_f
a = (n * s.sum{|x,y|x*y} - s.sum{|x,y|x} * s.sum{|x,y|y}) /
  (n * s.sum{|x,y|x**2} - (s.sum{|x,y|x})**2)
b = (s.sum{|x,y|x**2} * s.sum{|x,y|y} - s.sum{|x,y|x*y} * s.sum{|x,y|x}) /
  (n * s.sum{|x,y|x**2} - (s.sum{|x,y|x})**2)

これを実行すると

p a => 0.5913598269802649
p b => 1.6747445255474454

という結果になりました。これだけ見ると正直、合っているのかどうか分かりません。

グラフにプロット

そんなわけで gnuplot でプロットしてみます。 まずは座標値群ファイルを準備します。

$ cat ./ten
32.0   24.0
131.0  62.0
159.0  110.0
245.0  146.0

次に先ほど求めた直線の式から、[math]x = 0[/math] の時と [math]x = 300.0[/math] の時の x, y それぞれの値を求めます。

if b.nan?
  # 切片の解なし(Y軸に対して平行)
else
  x = 0.0
  puts "#{x} #{a*x+b}"
  x = 3000.0
  puts "#{x} #{a*x+b}"
end

結果は

0.0 1.6747445255474454
300.0 179.08269261962693

となります。 この結果を ./sen に保存しておいて、

$ gnuplot4-qt
gnuplot> plot "./ten", "./sen" w lp

すると次のように表示されました。

plot

んー、なかなか合ってるような気がします!

どうもちゃんと動いているようなので、以下に Ruby スクリプトの全文を掲載しておきます。

OpenCASCADE 6.9.0 を LMDE でビルド

先日、自宅サーバの Debian GNU/Linux Jessie 32bit 版で OpenCASCADE 6.9.0sirenビルドしました

自宅サーバは、SSH で外部からアクセスして開発ができるので便利である一方、オンボード Atom 搭載の省電力サーバなのでコンパイルにはもの凄く時間がかかります。そこで、Intel Core i7 を搭載した普段使い用のラップトップでもビルドしようと思います。

ラップトップは、LMDE(Linux Mint Debian Edition) の無印、あえて言うなら version 1 です。先日、LMDE 2 がリリースされましたが環境を壊すかもしれないのが怖くてまだ移行していません。なお、こちらは 64 bit です。

OCCT 6.8.0 ベースの siren をビルドして開発に使っていたので、こちらも難なくビルドできると思いきや、VTK を指定しないと Visualization 以下のモジュールが上手くビルドすることができませんでした。

configure の出力では、VTK は optional 扱いになっていたのですが、必須なのかなあ…?たしかに先日の Debian の記事でも明示的に VTK を指定していました。なお、VTK は自分の記憶が正しければ 6.8.0 の時点で既に OCCT に利用されていたようですが、その時は確実に optional だったはずです。(VTK をインストールしなくても Visualization 以下のビルドが通っていました)

ないなら入れてしまえと apt-cache search vtk するも、バージョン 5.8 しか公式リポジトリにはありませんでした。試しに libvtk5.8, libvtk5-dev を install して OCCT 6.9.0 をビルドしてみても、やはりビルドが通りません。 なお、Debian の Jessie には公式リポジトリに VTK 6.1 があったため、APT 経由で入れたらビルドが通りました。

ということで、ソースコードを取得して自分でビルドしましょう。VTK の公式サイトのダウンロードページから、対象となる 6.1 の tar ボールをダウンロードします。

cd /tmp
wget http://www.vtk.org/files/release/6.1/VTK-6.1.0.tar.gz
tar zxvf VTK-6.1.0.tar.gz
cd VTK-6.1.0

README.html にビルド方法が載っているので、それに従ってビルドします。

cmake.
make

README.html では cmake ではなく curses 版の cmake である ccmake と書いてありますが、cmake でも通ります。

ビルドにはもちろん CMake が必要です。また、依存しているライブラリもいくつかあると思いますが、幸運なことに自分の環境では追加ライブラリを指定することなく全てのビルドが成功しました。VTK を Debian で APT 経由からインストールした際、200 MB 前後の依存ライブラリがどっと降ってきたので心配でした。ヨカッタ。

例に漏れず、インストールは次のようにします。

sudo make install

インストールによって、ヘッダファイルは /usr/local/include/vtk-6.1 以下に、ライブラリファイルは /usr/local/lib 以下に設置されました。インストールパスは cmake オプションで指定できるはずです。

さて、これで OCCT 6.9.0 のビルド環境は整ったはずです。前回の手順どおりに、一気にやっちゃいます。

cd /tmp
wget http://files.opencascade.com/OCCT/OCC_6.9.0_release/opencascade-6.9.0.tgz
tar zxvf opencascade-6.9.0.tgz
cd opencascade-6.9.0/
./build_configure
./configure -prefix=/opt/occ690 \
-with-vtk-include=/usr/local/include/vtk-6.1 \
-with-vtk-library=/usr/local/lib

configure の出力で Visualization 以下のパッケージもすべて「Yes」になっていることを確認し、

make -j8 install

で、ビルド&インストール。 ビルド時間を計測すると次のとおりになりました。

real  17m11.411s
user  97m46.908s
sys   5m26.720s

前回、3時間以上かかっていたビルドは17分で終わりました。これは強い。

6.9.0 を用いて siren をビルドし直すとこちらでもちゃんと動いているようです。ひとまず安心です。

艦船キットコレクション Vol.6 スリガオ海峡 1/2000 戦艦「扶桑」

\扶桑姉さまが鎮守府に着任しました!/

Google ハングアウトの画面共有をしながら同僚とペアプロもどきをしている最中、手元が暇だったので、数週間前に購入した「艦船キットコレクション Vol.6 スガリオ海峡」の扶桑を組みました。

DSC06004

1/2000スケールモデルなので、全長192メートルの姉さまでも手のひらに乗るサイズになりました。ちなみに、全長だけでいうと航空巡洋艦最上の方が大きいです。(200メートル)

DSC06005

調子に乗って最近購入したばかりの50mm単焦点レンズで撮影したら、被写界深度がめちゃくちゃ小さくてボケボケになってしまいました。見苦しくてすみません。もっとカメラの方も練習せねば…。

DSC06006

丸みを帯びた木の葉型の船体に棒が突き刺さったような艦橋が、日露戦争の頃から第二次世界大戦まで試行錯誤して作り上げてきた日本海軍の艦の過渡期を彷彿させます。ちょっとアンバランスな感じがまた、扶桑型らしいです。

DSC06014

このシリーズで最初に組んだ航空巡洋艦「最上」との比較です。戦艦と航空巡洋艦なので兵装を単純比較することはできませんが、改装を受けた最上の方がなんだか近代的な感じがしますね。

次回は山城…と言いたいところですが、気分を変えて駆逐艦「山雲・満潮・朝雲」のいずれかを組みたいと思います。

OpenCASCADE 6.9.0 を Debian でビルド

先月の12日にリリースされた Open CASCADE の 6.9.0 をビルドしました。公式のロードマップでは 6.x 系列は 6.8 が最後で、次は 7.0 になるとの話だったはずですが、何だかんだで 6.9 がリリースされた模様

v6.9 のリリースノートを読んではいましたが、ここのところ忙しくて対応ができなかったので出遅れてしまいました。

ここ数バージョンは、ビルドの仕方マニュアルがいろいろと整備されてきて、時代に合わせてなのか、ビルド環境ごとの Markdown なドキュメントも付属しています。このブログで改めて紹介する必要性もあまりなくなってきました。詳しい内容は公式ドキュメントに任せるとして、要点だけかい摘まんで紹介したいと思います。

公式ドキュメンテーション

v6.9.0 の内容は次のドキュメントで網羅されています。

v6.9.0 のリファレンスマニュアルは、ソースコード tar ボールや Windows インストーラー内に同梱されています。最も最新バージョン(開発版)のリファレンスマニュアルであればこちらで参照できます。

v6.9.0 リリースの要点

モデリング・アルゴリズム

ファジー ブール演算

これまでのバージョンでは、ソリッドモデル等で行うブール演算時に対象と対象がちょうど同一の位置にある面や線を共有して存在していた場合、意図した演算結果にならない事が多くありました。意図した結果にならない場合はまだ良かったんですが、いつまで経っても計算が帰ってこない、または例外を吐いてお亡くなりになるケースもありました。この点が改善されているようです。

複数の引数を取るブール演算

これまでのブール演算では TopoDS_Shape を二つ用いて、Fuse, Common, Cut 等の演算を実行していました。あんまり詳しく見てませんが、同時に複数の TopoDS_Shape を演算させることができるようになるようです。これまで数回の処理で書いていたものが一度にできるわけですが、複数のソリッド群の一つに reverse させたソリッドを混ぜて Common に投げて、結果的にその部分だけは Cut させる動作にするなど、より「ブーリアン」っぽい演算としてコーディングできるようになりそうです。

ビジュアライゼーション

選択処理を再設計して、より良いパフォーマンスに

OCCT のビジュアライゼーションは長いことほったらかしになっていた様子で、ちょっと貧弱でした。これは、あくまでも OCCT は三次元幾何演算とトポロジックな形状の演算がメインであり、代替ライブラリーを用いて解決できるビジュアライゼーションは二の次でも大丈夫!という背景もあります。 実際、OCCT を採用している有名なオープンソース三次元 CAD ソフトの FreeCAD は、OCCT 提供のビジュアライゼーションを使用せずに別のライブラリで三次元ビューを提供しています。 ただ、ここ数バージョンでは、前述の幾何を扱うことろがだいぶ安定してきたのか、二の次だったビジュライゼーションが次々と強化されており、パフォーマンスも改善しています。まだ実験的な印象ではあるものの、レイトレーシングレンダリングの採用、GLSLシェーダが読み込めるようになっていることなど、単なる計算ライブラリから本当に「CAD」として必要な機能の強化が見てとれます。 後述する VTK の採用も注目すべき点です。

OpenGL ES 2.0 互換

ビジュアライゼーションの改良の特記すべきもう一つの点は、iOS, Android などのモバイル端末への対応です。OpenGL ES はモバイル端末向けの OpenGL のサブセットです。OCCT の幾何ライブラリの部分は、早い段階から Android にも移植されて動作していましたが、ビジュアライゼーションはそのままではビルドできませんでした。ES 互換となることにより、これらの環境へもシームレスな移植が可能となりそうです。

シェイプを表示する際の三角形メッシュ化の制御

コンテキストにシェイプを追加する際、これまでは必要に応じて自動的にシェイプの描画データである三角形メッシュを内部で生成していました。これを外側から無効にするオプションが導入されたようです。 形状の変形はなく、大量のシェイプを回転させるだけでも再三角形メッシュ化が走って表示速度が落ちていましたが、それらを動的に制御することができそうです。(※回転も行列演算している意味では変形(トランスフォーメーション)ですが、自由曲面の式まで遡って、形状の三角形メッシュを再構築する必要すらない場合も往々にあります)

その他

Intel TBB ライブラリを使わない並列処理のサポート

こちらも詳しく追っていませんが、自前で並列処理を行う環境が整いつつあるようです。

サンプルに AndroidQt, JniViewer for Android が追加

Android 環境のサンプルも充実してきました。

JniViewer

JniViewer for Android

AndroidQt

GUI は QML を使って書いてあるみたいです。本当に WPF/.NET Framework なんて使ってる場合じゃないです。

AndroidQt

その他のサンプルに、Qtデスクトップ版、MFC、C# があります。C# では WPF ベースのものと System.Windows.Forms 版があり、今のご時世でいうと半ばどうでもいいですが、Direct3D デモも追加されています。

v6.9.0 の全体的な感想

幾何演算部分の改良は喜ばしい限りで、ビジュアライゼーションの強化も頑張ってほしいところです。ようやくモバイル端末のサポートも視野に入れてきているようですが、個人的にはいっそのこと三次元ビューアは WebGL 環境へシフトしていくのもアリなんじゃないかなぁと考えています。OCCT をサーバ上で並列処理させて、クライアントの WWW ブラウザ上で表現する…素晴しいじゃないですか。最近は NW.js (Node.js + Webkit)のようなツールキットも存在しますので、ライトウェイトなビューアーからワークステーションで動かす CAD まで環境に依存しないビジュアライゼーション機能になっていけばいいな、と思っています。え?お前が Context や Viewer, View を JavaScript で再実装しろって?それが仕事になればいいんだけどなぁ…;)

v.6.9.0 のビルド

ビルド方法は次のドキュメントに詳しく書いてあります。

なお、このドキュメントはソースコード tar ボールを解凍して生成されるdoxディレクトリ以下に markdown ファイルとして収録されています。(逆に言うと、上記の HTML はそれらのファイルを doxygen にかけたものと思います。)

ビルド環境

OCCT のビルド環境もかなり充実してきており、以前のようにチューニングしながらあれやこれやする必要もほとんどなくなりました。公式サポートしているのは次の環境です。

  • Automake
  • CMake
  • CMake + ADT (Android SDK)
  • Code::Blocks (Mac OSX)
  • Xcode (Mac OSX)
  • Microsoft Visual C++ (Windows)

また、パフォーマンスチューニングレポートでは Linux 版の Clang/LLVM でも検証されているようです。

今回は一番馴染みがある Automake でいきたいと思います。

ビルド手順

作業ディレクトリに入り、tar ボールを落としてきます。ソースコードは前バージョンまではユーザー登録&ログインしないとアクセスできなかった気がしますが、今回から下記の URL で落とせるようです。なお、git での clone は登録が必須です。

cd /tmp
wget http://files.opencascade.com/OCCT/OCC_6.9.0_release/opencascade-6.9.0.tgz

解凍してディレクトリにはいります。

tar zxvf opencascade-6.9.0.tgz
cd opencascade-6.9.0/

configue をビルドして configure します。オプションについては後述します。

./build_configure
./configure -prefix=/opt/occ690 \
-with-vtk-include=/usr/include/vtk-6.1 \
-with-vtk-library=/usr/lib/i386-linux-gnu/

make して install します。

sudo make -j2 install

とりあえずこれだけです。便利。

貧弱な自宅サーバ(Debian GNU/Linux、32bit環境、Intel Atom)では、make で

real    183m57.121s
user    336m24.168s
sys     16m36.896s

となりました。

configue オプション

-prefix=

最終的にビルドしたファイルをインストールする場所です。自分は /opt/occ690 に指定しています。

-with--include=, -with--library=

ヘッダのインクルードパスとライブラリパスを追記しています。VTK が見えてなかったようなので、明示的に指定しました。

その他のオプションはこちらを参考にしてください。

ビルド時のテクニック

configure では、ビルドする環境にインストールされているライブラリの有無によって OCCT のモジュールとよばれるライブラリ群の Makefile を生成します。

モジュール > ツールキット > パッケージ > クラスや列挙型など

OCCT は上記のように階層構造を持ったライブラリです。ツールキットの部分が共有ライブラリファイル(.so)に当たります。Windows ではダイナミックリンクライブラリ(.dll)になります。モジュールはそれらをまとめて用途別にグループにしたものだと思ってください。

モジュールには次のものがあります。

  • FoundationClasses … 共通関数などを提供
  • ModelingData … 幾何形状をデータとして表現する機能
  • ModelingAlgorithms … 幾何形状を構築する機能
  • Visualization … 幾何形状を画面に描画する機能
  • ApplicationFramework … OCCT を使ったアプリのための有用な機能
  • DataExchange … 幾何データファイルのサポート(IGES,STEP,STLなど)
  • Draw … テスト環境

ざっくりと説明すると上に行くほど依存関係が少なくてすみます。詳細な依存関係はリファレンスマニュアルの図のとおりです。

occt modules

さらに、個々のモジュール内のツールキットの中で依存関係があります。なお、IGES などのデータファイルをサポートするには、GUI が必要がない場合でもビジュアライゼーションやアプリケーションフレームワークの各ツールキットを全て背負い込まなければならないかというと、実はそうではありません。具体的にはモジュール同士の依存関係の奥にはツールキット同士の依存関係があり、それを満たしていればこの図の限りではありません。今のところ、モジュールを越えた関係図はないので、リファレンスマニュアルを見て何が必要なのかを調べる必要があります。

さて、ビジュアライゼーション以下のモジュールは、さらに多くの別の人(サードパーティ)が開発しているグラフィック系のライブラリに依存しています。

そのため、グラフィック系のライブラリがない環境で configue すると、ビジュアライゼーション以下のモジュールが無効になった Makefile が生成されます。

configure の出力に各モジュール名と Yes/No といった表示が出力されるので、それでモジュールが有効になっているか無効になっているか、無効の場合はどのライブラリが足りていないのかを表示してくれます。以下に私の環境の configure 出力を示します。

3rdparty mandatory products       
---------------------------------
freetype      : yes 
tcltk         : yes 

3rdparty optional products       
---------------------------------
gl2ps         : no (--with-gl2ps=DIR option was not defined)
freeimage     : no (--with-freeimage=DIR option was not defined)
tbb includes  : no (--with-tbb-include=DIR option was not defined)
tbb libraries : no (--with-tbb-library=DIR option was not defined)
opencl        : no 
qt            : no (--with-qt=DIR option was not defined)
vtk           : yes 

Component                   Build
--------------------------  -----
FoundationClasses           yes 
ModelingData                yes 
ModelingAlgorithms          yes 
Visualization               yes 
ApplicationFramework        yes 
DataExchange                yes 
Draw                        yes 

「3rdparty mandatory products」は必須ライブラリ、「optional」は指定があったら使うライブラリです。必要なライブラリとそのバージョンは、以下にまとめてあります。

Open CASCADE Technology: Overview

Debian GNU/Linux jessie 32bit 版では、すべてのサードパーティ・ライブラリを標準リポジトリからインストールすることができました。(ソースコードの取得とビルドは不要)

また、テスト環境である Draw や Qt のサンプルプロジェクトをビルドする必要がなければ、 Tcl/Tk や Qt のインストールは必要ありません。 上記の「mondatory products」に Tcl/Tk が入っているのは、すべてのモジュールをビルドする際に必須、という意味だと思います。

siren をビルド

OCCT を使った siren というソフトを作ってます。OCCT が提供する三次元幾何演算機能を Ruby で簡単に記述することができ、ちょっとした演算なら手軽にすることができます。

上記でビルドした OCCT 6.9.0 を使って siren の最新リビジョン(OCCT6.8.0ベースで記述)をビルドし直してみると、あっけなくビルドが通りました。クラス名が変更されたり、siren で使っている機能が変更されることがなかったようです。

ひとまず安心しました。


艦船キットコレクション Vol.6 スリガオ海峡 1/2000 航空巡洋艦「最上」

エフトイズの艦船キットコレクション Vol.6 スガリオ海峡 航空巡洋艦「最上」(1/2000スケール)を作成しました。

1/2000スケールの艦船キットの話をIRCでしていたら、知人からちょうどこの艦船キットコレクションを教えてもらいました。その後、西海模型さんに入ってみると、ちょうど「山城」「扶桑」「最上」「山雲・満潮・朝雲」の4種類があったので大人買い。それでも一つ500円ちょっとなので、2000円でこれだけ楽しめるのはリーズナブルでよいです。特に1/2000スケールモデルはパーツ数が少ないので、造り始める前に気合いを注入しなくていいのも良いです。このシリーズはいいぞもっとやれ、です。

さて、エフトイズの食玩モデルは、去年の「現用艦船キットコレクション」の護衛艦「しらね」以来です。食玩といえど、手軽に塗装済みモデルを組めるのは楽しいです。

このシリーズは、「山城」「扶桑」「最上」「山雲・満潮・朝雲」がそれぞれフルハルモデル・洋上モデル(いわゆるウォーターラインモデル)の2種類があって、合計は8種類になります。自分が購入したものは、最上だけ洋上モデルで、その他はフルハルモデルでした。外箱にはどの艦が入っているか、ちゃんと番号が記載されていますが、フルハルか洋上なのかは買ってみてのお楽しみということです。

今回は最上から作成することにしました。

DSC02300-2

箱から出して、本体に煙突や飛行甲板を取りつけた直後です。重巡ですらこの小ささ…、さすが1/2000スケールです。全長200メートルの船体が、自分の人差し指とほとんど変わらない大きさです。かわいい。

ちなみに最上は、建造時にはロンドン軍縮条約の絡みで15.5センチ砲装備の軽巡として誕生しましたが、条約失効後に改装を行い、20.3センチ砲を備えた重巡として生まれ変わっています。ミッドウェー海戦後、後部の主砲を撤去して飛行甲板の延長工事を経て、航空巡洋艦になりました。レイテ沖海戦の米軍による猛攻の結果大破し、味方駆逐艦により魚雷処分されました。

DSC02301-2

小さい点と食玩という割には、塗装はしっかりしています。外箱には「おまけ…中国製 菓子…日本製」と書かれています。中国のパートのオバチャンたちが丁寧に塗装してくれているんだろうなあと考えると頭が下がるばかりです。

DSC02304-2

一通り組み終わった状態です。パーツ数は船体・船底を除いて17個と少ないので、パーツ自体が小さいものの、そんなに時間はかかりません。大きな面もほとんどないので、ランナー接合部を削る手間もほとんどありませんでした。(やすりがけをしようと思い始めると、そもそも塗り直しになっちゃうので、というところもありますが)

DSC02308-2

アップです。さすがにレンズから数センチの距離まで近づくと、特にアンテナ支柱などの作りが甘いのが分かってしまいますが、強度上最低限の細さと1/2000スケールということを考えたら大健闘なんじゃないでしょうか。

なお、公式サイトやパッケージには記載がなく、組立説明書にも表記がありませんが、単葉の艦載機(瑞雲?)が3機同梱されています。写真ではボケていますが、後部飛行甲板に搭載してみました。ちゃんとエンジン、風防、日の丸、裏面の薄いグレイ塗装までしてあって、さらにはちゃんとフロートがモールドで表現されているなど、素晴しいの一言です。

mogami-yamashiro-fusou-asagumo-michishio-yamagumo

シリーズの他のキットと並べたところ。上から「山城」「扶桑」「最上」「山雲・満潮・朝雲」です。手前の駆逐艦に至っては10円玉との対比で分かると思いますが、ボールペンやタバコでも隠すことができるほど小さいです。

また、扶桑と山城は同型艦ですが、こうやって並べてみると色々と違うところがあるのがよく分かりました。(山雲・満潮・朝雲はモデルは同一のもののようです)

僕が考えた最強のモバイルターミナル

…と、釣りみたいな題名ですが、あくまでも自分にとってということです。

ハードウェアキーボードを実装したau初のAndroid端末「IS01」や、モバイルギアの再来と謳われたNECの「LifeTouch NOTE」など、ハードウェアキーボードを搭載したモバイル端末の魅力に惹かれていろいろなハードウェアを買ったり使ったりしてきましたが、結局、どれもしっくり来るものがありませんでした。

普段の自分のコンピュータ環境は

  • Happy Hacking Keyboard ユーザである(Ctrlキーの位置が大切!)
  • 英語キーボードユーザである(記号キーの位置が大切!)
  • 日本語入力・変換にSKKを使っている(Shiftキー酷使!)
  • VimやBashで作業することが多い

っていうニッチな仕様で固められています。 自分で望んでそういうものを使い出しているので後悔はしていませんが、やっぱりハードウェア選びが不便なことが多々あります。

ラップトップPCは、ハナから英語キーボードが選べるモデルしか対象にしていません。問題は外出先で快適なコンピュータライフを送るためのモバイル端末です。

SHARP IS01

is01

IS01はそもそも日本語キーボードですらないので論外ですが、電話機として見ても、通話がしづらかったり、Android1.4と古くなっていたり、性能が遅くてSKK for Androidの変換すらタイピング速度に付いていけなかったりと問題が多々あって、結局普通の形状のスマートフォンに変更しました。

NEC LifeTouch NOTE

ltn

また、LifeTouch NOTEは手に入れた直後にDebian GNU/Linuxを入れて遊びましたが、他の人が活用しているポメラのようなモバイルワープロのような利用方法や簡単なネット端末としての使い方はしないうちに陳腐化しちゃいました。先日、ちょうど出張に持っていこうと数年ぶりに使ってみると、挙動がなにかおかしい…。リカバリをしてみると、今度はアプリが「あなたのAndroidは古過ぎて非対応」の続出。リカバリ直後はAndroid2.2だったかな。ESファイルエクスプローラや、Connect Bot、SKK for Androidが普通に導入できたので(DropboxやFirefoxなどはムリ…)、とりあえずはポメラ的な使い方+ターミナルとして出張に持っていこうといじりまわしていると、致命的なことにタッチパネルの接触がどんどん悪くなり、タッチしても反応しなくなりました。安く仕上げるためにタッチパネルはあまり良いものじゃないと聞いてましたが、散々時間をかけた挙句出張前夜に壊れるとは…。なお、HIDも非対応らしくUSB/bluetoothマウスも絶望的のようです。最低限の操作はキーボードで出来るかなと思いきや、標準の「ブラウザ」ではキャレット移動モードがついてないのでタップする以外にネットサーフィンができないようです。いろいろ惜しい。

既存のスマホ+α

結局、普段使っているスマートフォンにいろいろくっつけて快適な環境を構築するところに落ちつきました。

現在のスマートフォンはシャープのSHL22。2014年の2月に購入したもので、1年ちょっとが過ぎました。IS01を使っていた当時は、そもそも携帯を携帯したくなくなるほど重くてかさばったのであまり身につけていませんでしたが、SHL22になってようやく、普通の人のように携帯するようになりました。(それでも大きすぎるけど) このスマホ自体、他のメーカーのスマホに比べると映像出力であったりいろいろなところがちょっと「残念」なんですけど、HIDに対応しているAndroid4.2ってだけでも救いです。

構成は次のとおり。

DSC02365

ごちゃごちゃしてます、ええ。

スマホにUSB給電ができるY字ケーブルを差し、片方にモバイルバッテリー、もう片方にUSBハブを装着し、ハブにHappy Hacking KeyboardとMicrosoftのワイヤレスUSBマウスを装着しています。 左上の黒いのはモバイルWiFi端末です。auを含め大手キャリアの通信サービスは自分のようなたまにしか恩恵を受けないユーザにとって高すぎるので契約しておらず、代わりにIIJの格安SIMカードを契約しています。おかげで月々の通信費が通話と通信料合わせて2400円程度で運用できています。モバイルWiFi端末自身、バッテリーを内蔵しているのでモバイルバッテリーに接続しなくても利用することができます。右上の白い箱は予備のバッテリーです。

構成図

network

当初、Y字ケーブルとモバイルバッテリーを抜いて、スマホに直接USBハブ(とキーボード+マウス)を装着していたところ、思いのほかスマホのバッテリーを消費していました。キーボードもマウスも意外とバッテリーを食うようです。感覚としては、スマホでワンセグ放送を受信したり、Nasneの録画ストリーミングを再生したりする以上にバッテリーが削れていました。(10分で4〜5%とか)ということで、途中にダウンストリーム給電用のY字ケーブルとモバイルバッテリーを装着しています。

当初の構成

network2

SHL22の仕様かケーブル側の仕様かは分かりませんが、モバイルバッテリーから見てアップストリーム、つまりスマホ側には給電されません。なので、あくまでもこの構成で利用する際にモバイルバッテリーで動かしているのはキーボードとマウスのみです。スマホ側にも同時に給電できれば心強いんですが、キーボードとマウスが消費していた電力が削られなくなるだけでも結構長い時間、作業できるようになりました。

また、Happy Hacking KeyboardにはUSBハブ機能があるのでキーボードの上流側にUSBハブを付けたくなかったのですが、このハブを噛ませないとスマホ側が上手く認識しませんでした。Y字ケーブルあり・なしに関わらずそのような状況です。

この構成の利点は、用途や行き先によって不要なパーツは家に置いていくことができるところです。フルセットを旅先に持っていって宿泊先でガリガリコーディング、宿泊先から外出する際にはスマホだけ持って外出、という具合に、ラップトップPCにはない魅力があります。最近のラップトップは画面だけを取り外してタブレットPCとして使えるものもありますが、あれ自体でけえよ!って思ってしまう自分にぴったりの構成になりました。ウレシイ。

Androidもバージョン3だか、そのくらいからまともにハードウェアキーボードをサポートし始めているので、やっとちゃんとしたキーボードでの作業ができるようになりました。IS01やLifeTouch NOTEでは独自にキーボードをサポートしていたので、記号や特殊キーを多用するvim・bashで作業ができたもんじゃなかったです。

モバイルバッテリーの部分も強いです。ラップトップPCに比べれば専用のバッテリーである必要はないため、劣化したらリプレイスが楽ちんですし、USBコンセントにすれば安定した給電も可能です。ラップトップPCのACアダプター付きケーブルを持ち運ぶのに比べれば、同じ重さでもモバイルバッテリーとUSBコンセントの組み合わせの方が使い勝手も格段に良いと思います。

ラップトップに対するデメリットと言えば、やはり見てのとおり、ごちゃごちゃしているところでしょうか。電車などで移動中、さっと膝の上に展開できるようなモノではありません。テーブル必須です。また、前述のとおりスマホ本体のバッテリーもモバイルバッテリーの恩恵を受けられないということです。

このデメリットを考えたとしても、やはりバラバラであることの利点は大きいと思います。スマホが変わってもマウスが変わっても、とりあえずこの構成は維持できそうです。

DSC02364

使い慣れたキーボードで、vimを使ってC++コーディングができる喜び…!

ガリガリコーディングするのに十分な環境は整いましたが、仕事の出張では三次元CADを客先に見せないといけないので、まだまだ出番はないかもしれません。ううむ…。

鎮守府史跡探訪〜佐世保軍港クルーズ〜

ゴールデンウィーク中、知人の船に乗せてもらい佐世保港からハウステンボスの見える波止場まで行き、バーベキューをしてきました。

はりきって写真を撮ったんですが自分のスキルでは全然上手く撮れませんでした。でもやっぱり貼りつけておこうと思います。撮影スキルもがんばるぞい!

DSC04928

昼下がり、鯨瀬埠頭に泊めた船に乗船。対岸に見えているのは米軍施設です。休みの日はよく対岸から米兵やその家族の叫び声が聞こえてきます。佐世保の街中にはアメリカ人がたくさんいますが、日本人では考えられない音量で会話してます。声がでかいのがアメリカ人。

DSC04934

出港するとすぐに左舷側に鯨瀬ターミナルが見えてきます。ここから五島行きなどのフェリーが出ています。マンガ「トッキュー」の第1巻で乗用車が海に転落したのは、ちょうど写真に写っている岸壁です。

DSC04939

鯨瀬埠頭の反対側、右舷側を見ると米軍佐世保基地にくっついている立神2号桟橋に、護衛艦「しまかぜ」が停泊していました。米軍基地エリアの奥深くにある桟橋部分だけが海上自衛隊のものです。佐世保港の敷地っていうのはなかなか複雑で、民間の佐世保重工業(SSK、旧佐世保海軍工廠)、アメリカ海軍佐世保基地、海上自衛隊佐世保基地、さらに一般人にとって大切な朝市や貨客船ターミナルがある万津・新港町などなど、たくさんのエリアに分割されています。

101021ganpeki2

佐世保市議会議員のサイトに良い地図があったので拝借しました。地図は少し古い2010年時点のようで、埋め立てして出来た土地にさせぼ五番街を作った新港町がまだ海の底です。平瀬係船池にある点線・斜線部分も埋め立てられているようです。昨年も返還のニュースが流れてましたが、SSKと米軍が共同で利用している立神岸壁ではいろいろとあるようですね。

なお、水陸機動団で話題となった陸上自衛隊佐世保基地は相浦地区にあり、地図では向かって左手の方になります。

DSC04947

船は進み、さらに左舷側を見ると今度は海上自衛隊倉島岸壁が見えます。ここが毎回一般公開でお世話になっている岸壁です。長崎三菱造船所建造の護衛艦「あきづき」が係留されています。

DSC04964

その後には、右手から護衛艦「あさゆき」、「さわぎり」、「じんつう」が係留中です。赤煉瓦風の海自厚生センターがまぶしいですね。

DSC04982

海から見た倉島岸壁の位置はこんな感じです。写真に写っている海岸線の一番左に佐世保駅が小さく見えています。

DSC05006

DSC05012

DSC05029-2

倉島岸壁を過ぎると、今度は米軍弾薬補給所が見えてきます。さらに、補給所の先には、崎辺にある海上自衛隊佐世保教育隊・警備隊の基地が見えます。崎辺の岬には戦前、佐世保海軍航空隊の滑走路がありました。

2

5

埋立地の崎辺では地盤が弱く、滑走路に不向きという理由から佐世保海軍航空隊は大村基地に拠点を移したそうです。写真は佐世保地方隊のページから拝借しています。(崎辺に関する詳しい記事があります)

滑走路といえば平地が少ない佐世保では、今でも佐世保湾内に水上機用の滑走路エリアが設けられているようです。

sbm

湾内のほとんどの場所から外海が見えないくらい岬や入江が複雑な海岸線を構成している佐世保です。 その日の天候にもよるとは思いますが、実際に船に乗って湾内を航行しても驚くほど波がありません。 素人目に見ても着水しやすいんだろうなあ、と思いました。上の地図でいうと「D」と書かれたエリアです。

DSC05032

さて、その水上滑走路付近に一隻の艦が停泊していました。どう見ても商船ではなさそうです。

DSC05047

近づいて見ると、海上自衛隊の補給艦「おうみ」でした。旧ユニバーサル造船建造、2005年就役の比較的新しい艦です。全長220メートルで、さきほどの「あさゆき」は130メートル、旧海軍の重巡洋艦「高雄」でも203メートルなので艦船の中ではかなり大型のほうです。陸からだとこんなに間近に見れない艦をぐるりと見てまわることができるのもクルーズの醍醐味って感じですね!

また、造船システムの開発関係者として見ると「船型のあんなところにナックルがー」と困惑してしまいました。補給艦として容積を稼ぎたい一方で、軍艦として速力を上げるための船型なんでしょうか。ともかく仕事ってこわい。

さあ、どんどん南下していきます。

DSC05102

針尾島に近づくと針尾無線送信所の電波塔が見えました。旧海軍が造った大正時代から立っている軍用電波塔です。周りには森と畑しかないのでスケール感がよく分からなくなりますがなかなか大きいです。明治の産業遺産を世界遺産に申請して盛り上がってますが、佐世保も教会群だけじゃなくてこういう巨大遺構をもっと観光資源にすればいいのに…と思ってみたり。

新海誠監督の「雲のむこう、約束の場所」に出てくる「ユニオンの塔」のようです。近くで見ると威圧感というか、一種の不気味ささえ感じられる塔です。

DSC05122

針尾島の南端には西海橋があります。前述の「トッキュー」では遊覧船が沈没していた、渦潮の名所でもあります。この日は通った時間帯のせいもあってか、全然渦潮がありませんでした。水色の方が新西海橋、赤い方が旧西海橋です。

DSC05143

旧の方は建造当時、アーチ式鉄橋としては日本一の長さ(世界では3位)だったらしいです。そのせいか、昭和31年公開の怪獣映画の怪獣「ラドン」によって見事に破壊されてます。

DSC05176

西海橋を過ぎ、大村湾に入ると左舷側にハウステンボスが見えてきます。オランダの都市をモチーフにしたテーマパークですが、横から見ると山の起伏が激しくて、海抜0メートル地帯で有名なオランダの沿岸部とは似ても似つかない地形に…。横から見ると小規模に見えますが、敷地面積は東京ディズニーランドよりも大きく、ディズニーシーを合わせたのと同じくらいの面積はあるそうです。山の起伏が激しくて海岸付近まで山がせまっているのは佐世保の特徴で、軍港になった理由の一つでもあります。山が海岸まで来ているということは遠浅ではないので、比較的大型の艦船も入港しやすい地形だと言えるのです。

ちなみに、ハウステンボスがある土地は終戦直後の復員事業の際、検疫所があった場所です。

DSC05196

ハウステンボスの対岸にある小さな波止場に上陸し、バーベキュー開始。

DSC05203

ワンピースに登場するサウザントサニー号のクルーズ船がいったりきたりしていました。後から知った話ですが、2015年5月6日で終了し、愛知県にある「ラグーナテンボス」に移されたとのこと。撮影日は5月2日です。ちなみに、ラグーナテンボスの存在もさっき知りました。

DSC05329

DSC05345

DSC05383

まわりに光源が何もない地域なので、花火はより一層綺麗に見えました。

DSC05412

帰りに撮影した補給艦「おうみ」です。来た時とは艦首の方向が違っていました。写真はとも側から見たおうみの船尾部です。潮の流れに向かって動いているようです。ライトアップしてて綺麗ですね。

DSC05451

最後に倉島岸壁です。楽しかったな〜。

鎮守府史跡探訪〜堺木峠減圧井〜

先日、豚トロを食べようと雪平鍋に油をひいて加熱している途中、誤って鍋をひっくり返してしまいました。 結果、足に全治2週間の火傷を負いました。情けない・・・。

火傷した日からちょうど2週間が過ぎた日、通院のため自転車に乗っていると堺木付近に「堺木峠減圧井(げんあつせい)」というものを見つけました。

DSC02296-2

減圧井とは送水管の破裂を防ぐため、水圧の調整を行う施設らしいです。鎮守府があった市街地から大野方面に行く際、堺木付近はもっとも高さがある場所に当たります。山間部から集めた水をここで一旦減圧してから、下方にある鎮守府まで送水していたみたいですね。以前から目にしていたものの、明治時代の旧跡であることは知りませんでした。

DSC02295-2

説明の板には、堺木峠減圧井の歴史が書いてあります。

旧海軍佐世保鎮守府は海軍専用水道の水源拡充のため、当時の北松浦郡皆瀬村(現在の十文野町)にあった湧水の溜池を改良することを計画し、岡本貯水池を明治32年3月に起工、同33年5月に竣工しました。時を前後して、同貯水池の原水を浄化するための施設(旧矢岳浄水場)を明治31年10月に着工し両方を8インチ(20cm強)鉄管で結びました。 しかし、両方の高低差が146メートルにもあり水圧が高くなりすぎることから、調整を行う減圧井を「堺木」と「野中」に設けました。 この建物は、赤煉瓦造りで屋根は日本瓦葺、和洋折衷の当時としては大変モダンな水道施設で、旧矢岳浄水場が竣工した明治34年頃完成したものと思われます。 現在は使用されていませんが、当時を偲ぶ貴重な施設です。 平成5年7月 佐世保市水道局

なお、堺木峠減圧井は通りに面しているため、Google ストリートビューでも見ることができます。

ImageMagickを使ったハミング距離による画像の同一性チェック

画像認識に用いられるライブラリといえば OpenCV が一般的ですが、毎回 face detect のデモを動かしてみて安心してしまい、結果的にいつも本腰を入れて使ってみることがありませんでした。(やりたいなぁとは思いつつ、特に目的がない…)

今回、知人と OpenCV の話題が出たのをきっかけに ruby-opencv を使ってみようとしたけど挫折。OpenCV 本体のソースコードを clone してきて 3 時間近くもビルドを走らせて、環境作りにえらく時間がかかっちゃいました。もう少し根気があればいいんですが…。

さて、高機能な画像認識は必要がないような例、例えば、かなりゆるめの画像の同一性チェックなどでは、OpenCV のような本格的なライブラリを用意しなくても既存の環境でなんとかしたくなってしまいます。おっと、挫折したからって逃げではないですよ!ほんとですよ!

ということで、みんな大好き ImageMagick の convert コマンドに丸投げする形で、Ruby で書いていきたいと思います。 こちらの記事によると、縮小した画像を様々な視点からハッシュ化して、その値を比較することで類似度を算出しています。

今回は単純に明度同士の比較用いて、類似度を計算したいと思います。

手順

  1. ImageMagick を使って、比較対象の画像をそれぞれ 16×16 ピクセルの小さな画像に変換。言うなれば、モザイクのように色の平均値のパッチの集合となる。
  2. それぞれを2値化して、XBM で保存。XBM で保存するのは、Ruby 側から大掛かりな画像ライブラリを介すことなく、簡単に各々のピクセルの色情報を取得するため。
  3. 各々の XBM に含まれるピクセルデータをビット列に変換。
  4. 2つのビット列を比較し、類似性スコアを算出。

こういうのを「ハミング距離」を用いた判定と言うらしいです。

スクリプト

入力画像

試しに、次の2つの画像を入力として与えます。256×256 と 512×512 の大きさの違うレナさんです。

lenna256

lenna512

2値化した XBM として出力されるのは、それぞれ次のとおり。

lenna1

lenna2

似ていますが、入力のソースが若干違うために2値化結果にも差異が出ています。

この画像をビット列に変換し、スコア値を印字すると 0.9375 と表示されました。

面白い傾向として、最初に小さな画像にサンプリングする際の解像度を上げれば、より精度の高い類似性検出ができるのかと思いがちですが、実際にはその逆のパターンが多く見受けられました。

出力されるスコア値は 0.0 から 1.0 の値を取り、1.0 に近くなればなるほど類似度が高くなります。また、0.0 に近くなればなるほど、比較対象の明度が元画像に対して反転している可能性が高くなります。

この例では明度を2値化しているので、例えばほとんどのピクセルの明度が閾値以下(または、以上)になるような画像同士の比較には向いていません。また、部分マッチやトランスフォーメーション(回転・移動)に対する類似性を検出もできません。高度な検出を可能にするならば、やはり OpenCV を使うべきですが、明度だけではなく彩度やレベル・トーンカーブなど色々な側面を数列化して比較するとコストをかけずに検出精度を上げることも可能だと思われます。

HTML5+WebGLシーンがブラウザで簡単に作れる「Goo」を試してみた

siren で船型を作成し、Maya で艤装を作成して、Blender に持っていって Unity 向けに出力した FBX 形式の駆逐艦「島風」のモデルを試しに読み込ませてみると、難なく使うことができました。

上の画面内でマウスをドラッグすることにより、視点を変更することができます。また、Android の Firefox や Chrome でも、こちらの URL に直にアクセスすることにより、3D 表示&フリックによる視点回転とズームができました。

簡単な操船や海戦ゲームくらい作れそうですね!