ssh接続できない問題

sshでX転送がうまく行ってなかったのを修正したのでメモ.

xhost +したり,/etc/ssh/sshd_configでX11Forwarding yesしたり-Xオプションつけたり-Yオプションつけたりしても,接続先で環境変数のDISPLAYに値が入らなかったので調べてみると,ipv6が悪いっぽいことがわかった.
解決策は, /etc/ssh/sshd_config に以下の設定を追加.

AddressFamily inet

そしてsshdを再起動.

sudo service sshd restart

これで無事sshでXを飛ばせるようになった.

Power8上のLinuxでzshコンパイル

ソースコードを落としてきて普通に
./configure
make
make install

しようとすると,
configure: error: cannot guess build type; you must specify one
と表示されて ./configure の段階で失敗する.

この場合,ビルド先のアーキテクチャがわかってないのが原因なので,
./configure --build=ppc64-linux
という風に指定するとうまくいく.

Fedora 20素晴らしい

先日メインマシンをFedora 19から20へアップグレードしたが,また新たに別マシンにFedoraをインストールすることになった.

インストールも非常に簡単.DVDを入れて起動するとGUIでLive DVDとして起動するかインストールするかを聞かれ,インストールを選択すると,インストールが始まる.

インストール時にやることといえば,言語の選択,パーティションの選択と,ユーザ作成ぐらい.あとは勝手に進む.最後に再起動してDVDを取り出せばOK.

画像処理の研究をやっているとOpenCVをよく使うが,開発環境のインストールも非常に簡単.

yum groupinstall "C 開発ツールとライブラリー"
yum install opencv-devel

でOK.これでmakeとかgccとか必要なツールと,OpenCVを使った開発に必要なライブラリがインストールされる.しかも,gccのバージョンはかなり新しい4.8.2で,OpenCVのバージョンも2.4.7(最新版は2.4.8)と嬉しい.また,Pythonも2.7.5が入っている.

CentOSで開発しようとすると,gccもOpenCVも古くて,まずgccをソースコードからコンパイルして入れ,さらにOpenCVをコンパイルしていたが,Fedora 20やっぱり素晴らしい.

LinuxでOpenCV使った開発はFedora 20がとても良いと思う.

grepでマッチしたファイル名一覧を取り出す

vimで,「特定の文字列を含むファイルだけを開く」といったことをやりたいとする.
実際,例えば関数getHoge()を呼び出している関数を含むファイルだけをvimで編集したいというようなことがある.

まず、grepして、探したい文字列を検索して、該当するファイルを開けばいい.
ここで使うのが grep の -l オプション.普通 grep はマッチした部分と、そのファイル名を画面に出力するけど、この -l オプションをつけると、マッチした部分は表示されず、ファイル名の一覧が表示される。これを xarg を使って vim 等に渡せばいい。
結果的に

grep -l "getHoge()" *.cpp | xarg vim

でOK.

Fedora19 -> Fedora 20 のアップグレード

Fedora20がリリースされ,rpmfusionもFedora20用のが出ていたので,アップデートに踏み切った.

やり方はここを見ればわかるとおり,とても簡単.以下の操作はすべてrootユーザで行なう.

fedupというコマンドを使うので,まずそれをインストールする.

# yum install fedup

ついでにfedora-releaseも更新しておく.

# yum update fedora-release

あとは,fedupを使ってFedora 20へ更新.

# fedup --network 20

これで,ネットワーク越しにFedora20へ更新ができる.
僕の環境では6000個以上のパッケージをダウンロードして更新が行われたので,とても時間がかかった.

処理が終わったら再起動.
すると,起動オプションにfedupが追加されていて,そこからアップグレードが開始される.

3Dの素人がBundlerでVLFeatを使ってみた

この記事について

この記事はComputer Vision Advent Calendar 2012の12月10日分の記事として書いています.(一部はスタバにて,Mac Book Proで書いています.内容のBundler利用はLinux (Fedora 17) で行なっています.)

さて,今回の内容は,Bundlerを動かすこと,そしてその中で出てくるプログラムの一部にVLFeatというプログラムを利用する,という内容です.

Bundlerとは

Bundlerとは,Rubyのパッケージを管理するgemのラッパーで…ではなく,画像から3次元モデルを作るStructure from Motion (SfM)をするためのツールです.
オフィシャルのサイトにも

Bundler is a structure-from-motion (SfM) system for unordered image collections (for instance, images from the Internet) written in C and C++. An earlier version of this SfM system was used in the Photo Tourism project.

とあり,C/C++で実装されており,Photo Tourismというプロジェクトでも利用されていました.
で,なぜBundlerという名前かというと,このStructure from Motionの一連の処理の中でBundle Adjustmentという3次元と2次元の対応関係を計算する処理(ここがメイン?)があり,そこから名付けられているのだと思います.

基本的な処理の流れは,

  1. 特徴点を抽出する
  2. 複数の画像間で対応する特徴点を探索する
  3. 対応づいた特徴点をもとにBundle Adjustmentを実行する

となっています.
Bundlerのページからダウンロードできるコード(ver. 0.4)では,RunBundler.shというスクリプトにより,この一連の処理を行なっており,特にステップ1,2に対してはSIFT特徴を使って検出と対応関係の獲得を行なっています.

Bundlerの使い方自体は,満上師匠先生による解説が参考になります(2017.06.01リンク張り替え).
また,Bundle Adjustment自体の計算等については,岡谷先生のチュートリアル(もしくはコンピュータビジョン最先端ガイド)が参考になります.

オリジナルのBundlerの1,2のSIFTは,SIFT特徴を発明したD.Lowe先生の実装が利用されていますが,満上さんの話によるとR.Hess氏の実装(OpenSIFT)も簡単に利用できるとのことです.
今回,さらに別のSIFT実装であるVLFeatを利用してみようという話です.

ちなみに,Bundlerをコンパイルする時,新しいコンパイラでは基底クラスのコンストラクタ呼び出しの仕方でエラーが出ます.
src/BundlerApp.h の 620行目を消し,619行目に基底クラスのコンストラクタ呼び出しを追加してください.

VLFeatとは

VLFeatは様々な特徴量やアルゴリズムが実装されたライブラリです.

The VLFeat open source library implements popular computer vision algorithms including HOG,SIFTMSERk-meanshierarchical k-meansagglomerative information bottleneckSLIC superpixels, and quick shift. It is written in C for efficiency and compatibility, with interfaces in MATLAB for ease of use, and detailed documentation throughout. It supports WindowsMac OS X, and Linux. The latest version of VLFeat is 0.9.16.

HOGとかSIFTとかMSERとか色んな特徴量が実装されています.
(あれ…「OpenCVでええやん」という声が 聞こえてきた…)
まぁこれをダウンロードしてきてコンパイルすると,D.Lowe先生のSIFT実装の実行プログラムとほぼ同じ入出力のsiftという実行プログラムができます.

今回,このVLFeatで実装されているsiftプログラムをBundlerで使ってみます.

BundlerでVLFeatのsiftを使う

bundlerを展開したディレクトリ内のbinディレクトリにD.Lowe's siftの代わりにVLFeatのsiftを置くだけで済む…かと思いきや….

D.Lowe's siftとVLFeatのsiftの微妙な出力の違いでど嵌りしました.

だいぶ戦った結果,ステップ1で一旦出力するsift特徴量を記述したファイル(hoge.jpgが入力ならばhoge.key.gz)の形式が微妙に違うことがわかりました.

hoge.sift.gzをgunzipしてできたhoge.siftを見てみると,VLFeatに入っているsiftプログラムの出力は各行に

x y scale orientation 128次元がスペース区切り

が出力されていますが,D.Lowe's siftの出力には,先頭行に

特徴点数 次元数

の行があります.さらに,残りの各行は

20次元がスペース区切り
20次元がスペース区切り
20次元がスペース区切り
20次元がスペース区切り
20次元がスペース区切り
20次元がスペース区切り
8次元がスペース区切り

の形になっています.
Bundlerではこのファイルを開き,まず特徴点数を読み込んでから特徴点の配列を確保する仕様になっているので, VLFeatの入出力を少しいじる必要があります.
(Bundler側の読み込みコードを修正するという手もあるが,コードがあまりにもクソアレだったのでおすすめできない.)

sift入力の修正

D.Lowe's siftの場合,入力としては標準入力からpgmフォーマットの画像を読み込み,特徴量を標準出力へ出力する仕様になっているのに対し,VLFeatのsiftは,第1引数で与えられたhige/hoge.pgmを読み込み,hoge.keyをカレントディレクトリに出力する仕様になっている.

そのため,Bundlerのbin/ToSift.shファイルの36行目を次のように修正する.

修正前

echo "mogrify -format pgm $IMAGE_DIR/$d; $SIFT < $pgm_file > $key_file; rm $pgm_file; gzip -f $key_file"

修正後

echo sift_file=`echo $d | sed 's/jpg$/sift/'`
echo "mogrify -format pgm $IMAGE_DIR/$d; $SIFT $pgm_file; mv $sift_file $key_file; rm $pgm_file; gzip -f $key_file"

sift出力結果の修正

変換の修正ですが,特徴量ファイルはgz形式で圧縮されているので(ホントは上のToSift.shでgzipしなければ良いだけだけれど),

  1. gunzipで解凍
  2. 特徴量ファイルを修正(先頭行に特徴点数と次元数を追記)
  3. 各行を20次元ずつに分割
  4. gzipで圧縮

という手順になります.
まず,ステップ2,3の部分をpythonで書いてみると

#!/usr/bin/env python
import sys

i=0
buf=[]
for line in sys.stdin:
    i+=1
    l=line.split(" ")
    buf.append(" ".join(l[0:4]))
    l=l[4:]
    for j in range(6):
        buf.append(" ".join(l[j*20:(j+1)*20]))
    buf.append(" ".join(l[120:128]))

print i,"128"
print "\n".join(buf)

となります.
これをbundlerのbinディレクトリに,vlfeat2lowe.py として保存し,実行権限を与えます.

あとは,これに解凍/圧縮と,各ファイルに対して処理できるように ループを回して,

for img in `ls -1 $IMAGE_DIR | egrep ".jpg"`
do
        echo $img
        name=`basename $img .jpg`
        gunzip $IMAGE_DIR/${name}.key.gz
        $BASE_PATH/bin/vlfeat2lowe.py < $IMAGE_DIR/${name}.key > tmp.key
        mv tmp.key $IMAGE_DIR/${name}.key
        gzip -f $IMAGE_DIR/${name}.key
done

このコードをRunBundler.shの66行目あたりに突っ込めば動くようになるはずです.
ホントはもうちょっとスマートに書きたいが…ひとまず突貫工事ということで.
スマートに書きなおすには大工事が必要そうだったので.

結果の比較

D.Lowe's siftとVLFeatのsiftでBundlerを実行した結果の比較として,両手法で推定した3次元推定結果を以下に示す.
ただし,Bundlerの後処理として,密な3次元点群を得るために古川氏PMVS2を実行している.
可視化にはmeshlabを利用し,スクリーンショットを撮った.

まず入力画像はこちら

まずはD.Lowe's siftを用いた結果.
こっちのほうが圧倒的に処理は速かった.
結果の画像はこちら.

次にVLFeatのsiftを用いた結果.
検出されるキーポイント数が全然違う…閾値が違うのかな?
結果の画像はこちら.

違いが分からん…pmvs2するべきではなかった.
pmvs2前の頂点数を比較すると,D.Lowe's sift版では1459点に対してVLFeat版では1907点でした.
SIFTの検出キーポイント数が多い分,対応付けも多くとれたのかな.

終わりに

あーあ,完全にネタかぶっているブログを見つけてしまった….
zcatなんてコマンドがあったのか…

次やるときはもうちょっとスマートに書きたい.

apt-getでOpenCV

10月にリリースされた、Ubuntu 12.10を入れてみた。
毎回のことだが、OpenCVインストールなどの開発環境を整える作業。

sudo apt-get install libopencv- でTabキーを押したら、
libopencv-calib3d-dev libopencv-flann-dev libopencv-legacy2.3 libopencv-calib3d2.3 libopencv-flann2.3 libopencv-ml-dev
libopencv-contrib-dev libopencv-gpu-dev libopencv-ml2.3
libopencv-contrib2.3 libopencv-gpu2.3 libopencv-objdetect-dev
libopencv-core-dev libopencv-highgui-dev libopencv-objdetect2.3
libopencv-core2.3 libopencv-highgui2.3 libopencv-video-dev
libopencv-dev libopencv-imgproc-dev libopencv-video2.3
libopencv-features2d-dev libopencv-imgproc2.3
libopencv-features2d2.3 libopencv-legacy-dev

と表示された。libopencv-gpu-devとかも入ってる!?なので、

sudo apt-get install "libopencv-.*-dev"

で一発インストール。

Ubuntu上のphpでcURLを使う

curlは指定したURLからデータを取ってくるコマンドですが,それをphp5から利用する場合,php5-curlが必要になります.

コマンドライン上で

sudo apt-get install php5-curl

を実行することでphp5のcurlモジュールをインストールすることができ,利用できます.

何に使うかというと…wordpressにSimple Tweetというプラグインを入れたのですが,

Twitter OAuth は PHP5 以降でのみ利用できます。

というエラーメッセージが出て使えなかったからです.
このエラーメッセージはそのサーバのPHPでcurlが使えないときにも出るようです.

[shogun 1] shogunを使ってみよう

最近Shogun - A Large Scale Machine Learning Toolbox という機械学習のツールボックスを使い始めたので,shogunについて紹介します.

まず紹介ページの英語を適当に日本語に訳してみます.

SHOGUNは大規模なカーネル法と特にサポートベクタマシン(Support Vector Machine: SVM)[1]に重点を置いている機械学習ツールボックスである.いろいろなSVM実装(OCAS [21], Liblinear [20], LibSVM [2], SVMLight, [3] SVMLin [4] and GPDT [5])に対するインターフェースになる汎用的なSVMオブジェクトを提供する.SVMは様々なカーネルと組み合わせることができる.このツールボクスは線形カーネル,多項式カーネル,ガウシアンカーネル,シグモイドカーネルだけでなく,Locality Improved [6], Fischer [7], TOP [8], Spectrum [9], Weighted Degree Kernel (with shifts) [10] [11] [12]なども提供する.また効率的なLINADD [12]最適化法も実装している.線形SVMに対して,COFFIN framework [22][23]は疎行列,密行列他様々なデータタイプの混合に対してもオンデマンドで処理ができる.さらにSHOGUNは様々なpre-computedなカーネルで動くようになっている.重要なものとしては,サブカーネルの重み付き線形和による結合カーネルがある.この各サブカーネルは必ずしも同じドメインである必要はない.最適なサブカーネルの重みはMultiple Kernel Learning (MKL) [13][14][18][19]で学習できる.現在SVMは,1クラス,2クラス,多クラス分類,回帰問題を扱える.SHOGUNは線形判別分析(Linear Discriminant Analysis: LDA),線形計画マシン(Linear Programming Machine: LPM),パーセプトロン((Kernel) Perceptrons),隠れマルコフモデル(Hidden Markov Model)も実装されている.入力データは様々な型の疎・密行列を利用することができる.平均を引くなどの一連の前処理を各入力データに適用することもできる.
SHOGUNはC++で実装されており,Matlab, R, Octave, Python, Java, Ruby向けのインタフェースが用意されており,機械学習のオープンソースソフトウェアとして公開されている.

長々と書きましたが,重要なのは以下のポイントになります.

  • 様々なSVM実装が利用できる
  • 様々なカーネルを使える
  • SVM以外にもLDAとかHMMとかいろいろ使える
  • C++/Matlab/R/Octave/Python/Ruby/Javaなどで使える
  • オープンソースソフトウェアである

関西CV・PRML勉強会で紹介した時のスライドはこちらにあります.

僕はこのツールボックスを,Pythonから利用しはじめました.スライド中ではapt-getやMacPortsでインストールできると言っていますが,サンプルコードなどを入手したい場合は,gitを使ってソースコードをダウンロードし,コンパイルしてインストールするのがお勧めです.

gitがインストールされているならば

git clone git://github.com/shogun-toolbox/shogun.git
git clone git://github.com/shogun-toolbox/shogun-data.git

のコマンドで,shogunディレクトリとshogun-dataディレクトリができます.shogunディレクトリにはshogunのソースコードとサンプルコードが,shogun-dataディレクトリにはサンプルのデータが入っています.

ソースコードをダウンロードしたら,

cd shogun/src
./configure
make

し,管理者権限で

make install

することでインストールすることができます.
./configureの前に,swigがインストールされていないとpythonなどからの利用ができないので,先にインストールしておく必要があります.これはapt-getやMacPortsなどでインストールすることができます.

サンプルコードを動かすためには,サンプルデータのディレクトリの設定をする必要があります.shogunディレクトリ中で

rmdir data
ln -s ../shogun-data data

としてリンクを張っておく,もしくはshogun-dataの中身をshogun/dataへ移動すると完了です.

次のエントリではPython版のサンプルコードを動かすためのノウハウについて書きます.

seq コマンド

seqコマンドという便利なLinuxコマンドがあったのでメモ.ちなみに僕はシェルはzshを使っています.

seqコマンドは基本的には開始と終了を指定すれば,開始から終了までの数列を出力してくれるコマンド.使い方は以下のとおり.

seq -f "%03g" 0 100

これで 000~100までの数値が作れる.ここで -f "%03g" は,C言語等でもおなじみprintfのフォーマットと同じで,3桁になるように0で埋めるという意味です.別にかならず必要というわけではなく,これがないと,0~9,10~99,100という感じに出力されます.実は0で埋めるだけだったら,-wというオプションでもOK.

seq -w 0 100

これで0で整えられた文字列が出力される.ところで,普通にseqコマンドを実行すると指定した数字が改行区切りで出力されるけど,-sオプションを使えば区切り文字も変更できる.

seq -w -s , 5 15

この場合,05,06,07,08,09,10,11,12,13,14,15 という文字列が出力されるはず.

使用例:forループと組み合わせたりして

for x in `seq -f "%03g" 0 100`; echo $x

こんな感じ.でもforループで使うなら,

for x in {000..100}; echo $x

のほうが簡単。まぁでもstepも設定できるのは便利。

for x in `seq -f "%03g" 0 5 100`; echo $x

この場合だと,000から100まで5飛びで000 005 010 015 … 100が出力される.