JuliaImagesで画像の平行移動をする
Julia v0.5.1 + JuliaImages/ImageTransformations.jl v0.2.2で画像の平行移動を行う。
using Images using CoordinateTransformations img = Gray{Float64}[ 0.0 0.0 0.0 0.0 0.0; 0.0 0.5 0.5 0.5 0.0; 0.0 0.5 1.0 0.5 0.0; 0.0 0.5 0.5 0.5 0.0; 0.0 0.0 0.0 0.0 0.0;] tfm = recenter(Translation(2,0), center(img_pyramid)) translated_img = warp(img, tfm)
このとき、以下のように表示され、なんか移動してなくね?となる。
3:7×1:5 OffsetArray{Gray{Float64},2}: Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.5) Gray{Float64}(0.5) Gray{Float64}(0.5) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.5) Gray{Float64}(1.0) Gray{Float64}(0.5) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.5) Gray{Float64}(0.5) Gray{Float64}(0.5) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0) Gray{Float64}(0.0)
だが、この行列はOffsetArrayで表現されており、これでちゃんと平行移動している。
1行目の型情報にオフセットの情報が書いてあり、この値域の情報だけが下に表示されている。
ちなみにtranslated_img[1, 1]でアクセスするとBoundsErrorになるのでindicesなりで座標の値域をとってからアクセスする必要がある。
私がOffsetArrayに気付かず、テストコードやサンプルも回転移動のものしかないため少し詰まったのでメモ。
関係ないが、スーパーpre記法がjuliaに対応していた。
はてなブログ最高。
Ubuntu16.04でKinnect v1を動かす
本日ThinkPadが届き、これまで放置してしまっていたKinnectでViolin演奏中の姿勢の確認する奴作るかということでubuntu16.04でKinnect v1の動作を確認した。
とく難しいことをせず動いてしまったので、動いたよという報告だけになる。
参考にしたのは以下のスライドである。参考というかこのままである。
https://staff.aist.go.jp/kanezaki.asako/pdf/SSII2016_AsakoKanezaki_tutorial.pdf
ROSインストール
以下のマニュアルに従ってインストールする。*1
kinetic/Installation/Ubuntu - ROS Wiki
freenectインストール
Kinectを扱うためのコンポーネントをインストールする。。
sudo apt-get install ros-kinetic-freenect-launch
これをインストールすることでfreenect(ドライバ)もついでにインストールされるので予めfreenectを入れないと〜ということに悩まされない。
入るパッケージはros-kinetic-libfreenectのバージョンが0.5.1とubuntuのリポジトリ経由で入るlibfreenectの0.5.2より古い。
同じドライバが違うパッケージ名で競合してるの関わりたくない感じがしたので見なかったことにした。
動作
rvizでなんか写ってることを確認する。
点群だけ表示してもは???って感じなのでrvizでみたほうが良い。
ありがちなのだが、PointCloud2とか表示に加えないと左のメニューにも表示されない。
この手の、最初設定したらもう知らん系にちょいちょい悩む。
roslaunch freenect_launch freenect.launch rosrun rviz rviz
おわりに
前日OpenNI入れろとかNiTEを闇から入手しろみたいなブログばかり見まくって死ぬか思った。
インターネット怖い。
手順的には産総研のスライドと同じなのでこんな記事いらないのだが、16.04でもうごいたで!ありがとや!という気持ちを伝えたかっただけである。
Golearnとplotで散布図を書く
Go入門中です。
Goleanで読み込んだデータをgonum/plotでプロットします。
package main import ( "fmt" "image/color" "math/rand" "github.com/sjwhitworth/golearn/base" "github.com/gonum/plot" "github.com/gonum/plot/plotter" "github.com/gonum/plot/vg" ) func main() { rawData, err := base.ParseCSVToInstances("datasets/iris.csv", false) if err != nil { panic(err) } _, rows := rawData.Size() spal_length_attrs := rawData.AllAttributes()[0].(*base.FloatAttribute) spal_length_spec, _ := rawData.GetAttribute(spal_length_attrs) spal_width_attrs := rawData.AllAttributes()[1].(*base.FloatAttribute) spal_width_spec, _ := rawData.GetAttribute(spal_width_attrs) species_attrs := rawData.AllAttributes()[4].(*base.CategoricalAttribute) category_values := species_attrs.GetValues() category_num := len(category_values) fmt.Println(category_values) fmt.Println(category_num) class_attrs := rawData.AllClassAttributes()[0].(*base.CategoricalAttribute) class_spec, _ := rawData.GetAttribute(class_attrs) category_vs_raw_map := make(map[string]plotter.XYs) fmt.Println(category_vs_raw_map) // plot for i := 0; i < rows; i++ { // category category_bytes := rawData.Get(class_spec, i) category_name := class_attrs.GetStringFromSysVal(category_bytes) fmt.Println(category_name) _, isExist := category_vs_raw_map[category_name] if !isExist { fmt.Println("Add ") fmt.Println(category_name) category_vs_raw_map[category_name] = make(plotter.XYs, 0) } spal_length_bytes := rawData.Get(spal_length_spec, i) spal_length := spal_length_attrs.GetFloatFromSysVal(spal_length_bytes) spal_width_bytes := rawData.Get(spal_width_spec, i) spal_width := spal_width_attrs.GetFloatFromSysVal(spal_width_bytes) append_xy := plotter.XYs{{spal_length, spal_width}} pts := category_vs_raw_map[category_name] category_vs_raw_map[category_name] = append(pts, append_xy[0]) } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Iris Spal Length vs Width" p.X.Label.Text = "Length" p.Y.Label.Text = "Width" p.Add(plotter.NewGrid()) for name, xys := range category_vs_raw_map { fmt.Println(name) fmt.Println(xys) plot_data, _ := plotter.NewScatter(xys) r := uint8(rand.Float32() * 255) g := uint8(rand.Float32() * 255) b := uint8(rand.Float32() * 255) plot_data.GlyphStyle.Color = color.RGBA{R: r, G: g, B: b, A: 255} p.Add(plot_data) p.Legend.Add(name, plot_data) } // save pict p.Save(4*vg.Inch, 4*vg.Inch, "iris_spal.png") }
これで次のグラフがプロットされます。
Go、チュートリアル中なので微妙なところがあれば教えて欲しいです。
冪集合の空集合含まない奴は何ていうの?
プログラム書いていて冪集合なんだけど空集合はいらない。
できたら要素が多い順に出して欲しいって時は無いでしょうか。
私はさっきそう思いました。
空集合(power set)はitertoolsのレシピから
def powerset(iterable): "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
とかけます。
コード書く上で空集合が邪魔かつ要素が多い順に出して欲しい場合はこうかなと思います。
@staticmethod def _powerset(iterable): s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1, 0, -1))
で、空集合を含まない冪集合って何て言うんですかね…。
ありそうなもんですが。
What is shortest?
NetworkXでshortest_pathというメソッドがある。
shortest_path — NetworkX 1.10 documentation
weightのところを見るとweight=でweightを入れるとweight考慮しますと書いてある。
では
add_weighted_edges_from — NetworkX 1.10 documentation
を使って予めweightを設定した場合は?
少し試してみたが、weightは考慮されないようである。
shortest_pathの実装はshortest_path自体の引数がNoneか否かで呼び出すアリゴリズムを選択している。
https://github.com/networkx/networkx/blob/master/networkx/algorithms/shortest_paths/generic.py#L41
sourceとtargetのみ指定すると
bidirectional_shortest_pathが使用されるが、これがunweightedなモジュールの中に含まれている。
実装を見てもweightを自分で計算してそう。
まぁ、bidi rectional_dijkstraをshortest_pathの代わりに使用すればweightが考慮されるようになる。
こう、教訓としてはアルゴリズムは明示的に指定しましょうという。
まぁ、これくらいは見てくれてもいいんじゃないかな感はあるんですがどうなんですかね。
MacOSX Yosemiteでプロファイラを実行する
最近Mac上でC++を書いている。
プロファイラをかけようと思ったが意外に上手く行かなかったのでメモ。
上手くいった奴
上手く行かなかった奴
gperftools
g++ -lprofiler main.cpp
a.outが生成される。
a.profにプロファイル情報を吐くようにする。
CPUPROFILE=a.prof ./a.out
CPUPROFILE=a.profと./a.outを別々に実行するとa.profが生成されなかった。
このプロファイル結果をpprofでみるのだが、メソッド名が16進の文字列になる。
pprof a.out a.prof
原因はASLRにあるらしい。
コンパイル時に-Wl,-no_pieを追加。
これにより一部のメソッド名は正しく表示されるが大半は16進のまま。
そもそも呼んでないメソッド名が処理されていることになっているのでちょっとダメっぽい。
OS X Lion Heap profiling requires disabling Position Independent Executable · Issue #363 · gperftools/gperftools · GitHub
OS X requires disabling Position Independent Executable · Issue #565 · gperftools/gperftools · GitHub
ROS meets Docker
MacOS Yosemite上のDocker内のROSからArduinoにシリアル通信する。
ROSを使う時、apt-getとか使うとシステムがいっぱい汚れる。
辛みしかないのでDockerを使う。
ROSもpythonのvirtualenvみたいのあるよ!ってことなら教えて欲しいです。
Dockerをインストールする
基本的に公式に従う
Installation on Mac OS X
やることは下記からpkgを落としてきてインストールするだけ。
Release v1.5.0 · boot2docker/osx-installer · GitHub
boot2dockerのアイコンができるのでそれをクリックするとターミナルが立ち上がる。*1
VirtualBox上にboot2dockerという名前でLinuxが走るので、この上でゲストOSを走らせることになる。
USBの設定
このままではUSBが使えないので設定をする。
VirtualBox上からboot2dockerを終了させる
右クリック->閉じる->電源オフでいいと思います。
Extension Packをインストールする
下記からExtension Packをダウンロードしてきてインストールする。
Downloads – Oracle VM VirtualBox
boot2dockerの設定を変更する
VirtualBoxのGUI上にあるUSBの項目のチェックボックスを入れる。
右のプラスアイコンからフィルターの項目を追加できる。
このフィルターというのが認識させるUSBデバイスになるので認識させたいデバイスを追加する。
Docker imageを作成する
ubuntuのイメージの取得
ゲストOSとしてubuntuを使用したいためこのイメージをダウンロードする。
boot2dockerのアイコンをクリックする。
立ち上がったbashから下記でimageをダウンロードする。
docker pull ubuntu:trusty
imageの一覧は下記になるので、欲しいバージョンに合わせて書き換えて欲しい。
Docker Hub
以下でローカルのimageの一覧が見れる。
docker images
ROS用imageの作成
適当なディレクトリにDockerfileというファイルを作る。
ファイルの中身は下記のように、imageの作成にあたり実行して欲しいスクリプトを書く。
# install ROS indigo # based ubuntu 14.04 trusty FROM ubuntu:trusty # prepare install ROS RUN apt-get update -q \ && apt-get install -yq wget # install ROS RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list' RUN wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add - RUN apt-get update \ && apt-get install -y ros-indigo-desktop-full \ python-rosinstall RUN rosdep init # vnc RUN apt-get install -y x11vnc xvfb # create passwd after create working user # develop env RUN apt-get install -y byobu \ zsh \ git # create user RUN adduser --disabled-password --gecos '' --shell `which zsh` rosuser RUN adduser rosuser sudo RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers USER rosuser WORKDIR /home/rosuser # user indivisual developing env ## vnc RUN mkdir .vnc RUN x11vnc -storepasswd 1234 ~/.vnc/passwd # ros env RUN rosdep update RUN echo "source /opt/ros/indigo/setup.zsh" >> ~/.zshrc
このDockerfile内で全てやらないといけないかというとそうではなく、
docker commitしてもimageに反映されるのでそれだけで作っても良い。
ただ、秘伝のimageになるのを避けるため、なるべくDockerfileに書きましょう。
以下でhogeという名前のimageがDockerfileから作られる。
docker build -t hogeimage .
プロセスの作成
USBを使いたいのでboot2dockerがUSBをどこで認識してるか確認する。
下記でboot2dockerの中に入れる。
boot2docker ssh
適当にls /dev/tty*とかでそれっぽいのを探す。
今回は/dev/ttyACM0でした。
以下でプロセスを作成する。
vnc用にportとUSB用にdeviceを指定している。
これでゲストOS上で/dev/ttyUSB0にUSBがマウントされる。
docker run -it -p 5900 --device=/dev/ttyACM0:/dev/ttyUSB0:rwm --name hogeprocess hogeimage
実行するとゲストOSに入る。
rosuserでUSBを使いたいのでdeviceにchmodしておく。
chmod 666 /dev/ttyUSB0
ゲストOSから抜けるときはexitで抜けれる。
再度入りたいときでプロセスが生きている場合(docker ps -aして、まだいる場合)
下記で入れる。
docker start -i hogeprocess
Arudinoの準備
Arudino用のros_libを作成する。
rosserial_arduino/Tutorials/Arduino IDE Setup - ROS Wiki
docker cpでros_libをMacOSにコピー、Arudino IDEに読み込ませる。
ros_libの中にサンプルコードが入っているので、BlinkというのをArudinoに焼く。
通信
ほぼここに従う
rosserial_arduino/Tutorials/Blink - ROS Wiki
roscore
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0
ここでうまくいくとArudinoのRXとTXがチカチカし始める。
下記を実行するとNo13のLEDの付けたり消したりできる。
rostopic pub toggle_led std_msgs/Empty --once
この記事を書くためにboot2docker立ち上げたり落としてたりしたらプロセスに入れなくなった。
docker commitでイメージにしましょうという教訓を得た。