2014年3月17日月曜日

C言語との連携 ctypes


pythonは高機能で大変便利ですが、処理が遅いので困る場合があります。
そういう場合は、いろいろと工夫して高速化する方法があります。

ctypesによるDLLの利用はその高速化手法の一つです。
つまり、C言語(など)でDLLを作成して、pythonから読み込みます。
そのDLLを呼びだすためのライブラリがctypesです。

import ctypes

d = ctypes.cdll.LoadLibrary("libx.dll")


C言語と言いましたが、実際C++で作成しても構いません。
但し、呼びだす関数部分はC言語の方式で書かなければなりません。

つまり裏側ではC++のclass定義やインスタンスを生成しても構いませんが、
pythonから呼び出す部分は

extern "C"

などとしてC言語方式で、関数にしなければならないということです。




2014年3月13日木曜日

グラフ

グラフはプレゼンするうえでは必須で、見やすいグラフをどうやって作るかは重要な課題です。
Excelは最近のバージョンで少し見やすくなりましたが、昔はかなりひどいものでした。

これまでMATLABを使ったりRを使ったりしていましたが、
現在は
pythonのグラフ描画ライブラリであるmatplotlibを使っています。
結構グラフがきれいに描画できるのでお勧めです。

import matplotlib.pyplot as ppl
import numpy

t = numpy.arange(100)
ppl.plot( t, numpy.sin( t ) )

ppl.show()




こんな感じで簡単にグラフが描画できます。
行列の値に応じて色分けして表示する場合は、
a = numpy.random.randn(10,15)
ppl.pcolor( a )
とすると表示できます。




2014年3月12日水曜日

並列処理

pythonによるプロセスベースの並列処理に関するメモです。
ライブラリのmultiprocessingを使います。



import multiprocessing as mul

def getLL( d ):
    return -d*d/2

pool = mul.Pool( processes=2 )

data = [ 0.5, 0.2, 0.1 ]
res = pool.map( getLL, data )



getLLは自分で定義した関数です。
dataはリストで、この中身が一つずつgetLLに渡されます。
ここでこの関数は
プロセス毎に実行されます。
ただし、一度に流れるプロセスは最初に決めた値(processes=2)です。

これで簡単に並列計算することができます。
関数への引数は一つしか受け付けないようです。


2014年3月10日月曜日

OpenCV3: WEBカメラ画像の取得

pythonでOpenCVライブラリを利用し、画像処理をします。
今回は単純にWEBカメラ画像を取得して表示するプログラムを書いてみます。


import cv2

cv2.namedWindow('CAMERA')
v = cv2.VideoCapture(0)
v.grab()
im = v.read()
cv2.imshow( 'CAMERA', im[1] )
key = cv2.waitKey(0)


以上で終了です。
C言語などに比べると驚くほど短いです。

これを実行すると、WEBカメラから取得した画像をウィンドウに表示します。
ウィンドウ上でエンターキー入力するとウィンドウが消えてプログラムが終了します。


継続的にカメラ画像を取得して表示したい場合はgrabからwaitKeyまでをループさせてください。
waitKey命令を入れないと画面が更新されません。
waitKeyの引数はキーの入力待ち時間[msec]です。
ループさせると、カメラ画像を継続的に取得表示します。
つまりカメラの映像を、そのまま表示する事ができます。

ソースコードは

import cv2

cv2.namedWindow('CAMERA')
v = cv2.VideoCapture(0)
key = 0
while key != 32:
  v.grab()
  im = v.read()
  cv2.imshow( 'CAMERA', im[1] )
  key = cv2.waitKey(1000)


こんな感じです。
今度はスペースキーで終了します。

スペースキーに32という番号が振られているので、key=32になったらループから抜け出すようになっています。


実行すると
指定したCAMERAと言う名前のウィンドウが出てきます。







2014年3月5日水曜日

コマンドライン1行でpythonのコマンドを実行する方法

これもたまにしか使わないので、書いておかないとよく忘れてしまいます。

linuxなどの端末(terminal)で、スクリプトファイルを作るまでもない些細なことで、
スクリプトなら簡単にできる処理がしたいとします。
且つ、linuxコマンドだけでは複雑すぎて面倒な処理などに、1行スクリプトが効果を発揮します。

例をお見せします。

python -c 'print "\n".join([ "mv %d %d.jpg" % ( i, i ) for i in range(5) ])'

以前紹介したリスト内包表記を使っています。
これを実行すると下のように出力表示されます。

mv 0 0.jpg
mv 1 1.jpg
mv 2 2.jpg
mv 3 3.jpg
mv 4 4.jpg

こうしてコマンド文字列を生成することができます。
文字列がうまくできていることを確認できたら今度は

python -c 'print "\n".join([ "mv %d %d.jpg" % ( i, i ) for i in range(5) ])' | bash

などとして、bashの標準入力に流し、実際に実行できます。
こうしてpythonの機能を使って、効率よく処理できます。
挙げた例でいうと、順番に番号が付けられたファイルをいっぺんに名前を変更するときなどに便利です。


python を-cというオプションで実行するとそのあとの文字列が実行されます。
細かいことはググればヘルプなども出てきます。
実はこれはpearlやrubyなど他のスクリプト言語でも似たようなことが出来ますが、
pythonは文法が少し違うので、慣れが必要です。




2014年3月4日火曜日

OpenCV2 画像の変換


pythonはライブラリが豊富ですが、ライブラリ間のフォーマットは同じであるとは限りません。
画像処理ライブラリに関しても主なものでOpenCVとPILというライブラリがあります。
その間の変換方法について解説します。
この機能、実際使う人がどのくらいいるのかは不明ですが、自分の備忘録も兼ねています。
もし、お役にたつならどうぞ。


CVからPIL
pim = Image.fromarray( cv2.cvtColor( cvim, cv2.cv.CV_BGR2RGB ) )


CVにおけるHSVとRGB,BGRの変換
xx = cv2.cvtColor( x, cv2.cv.RGB2HSV )

実際のところ、画像はnumpy.arrayとして表現されているので、
numpyのスライス機能を使えば同様の処理が可能なことがあります。
たとえば、RGBとBGRの変換では1層目と3層目を入れ替えるので、


tmp = x[:,:,0]
x[:,:,0] = x[:,:,2]
x[:,:,2] = tmp


とします。

反転もnumpy.arrayなら簡単にできます。
y = x[:,range(x.shape[1]-1,0,-1),:]
とすると左右反転します。
スライス機能を使うとなぜかうまくいかなかったのでrange関数使いました。

あと、ロボット用ソフトウェアのためにOpenRTミドルウェアというものを使っています。
pythonでロボットのモジュールが記述できます。
そのなかで使用する画像形式への変換方法についても載せておきます。


RTC.CameraImageからCVへの変更
## ci : cameraImage
### x : numpy.array


ci = RTC.CameraImage( tm, .... )
x = numpy.fromstring( ci.pixels, dtype=numpy.uint8 ).reshape( ci.height, ci.width, -1 )

CVからRTC.CameraImageへの変換
ci.pixels = x.tostring()
ci.width = x.shape[1]
ci.height = x.shape[0]

RTC.CameraImageからPILへの変換cam = RTC.CameraImage(...)
cvim = nmp.fromstring( cam.pixels, dtype=nmp.uint8 ).reshape( cam.height, cam.width, 3 )
pim = Image.fromarray( cv2.cvtColor( cvim, cv2.cv.CV_BGR2RGB ) )

2014年3月3日月曜日

OpenCV 1



pythonにはPILとOpenCVという画像関連ライブラリがあります。

GUIとしてはWxやTkがあり、グラフなどに特化したmatplotlibがあります。

ここでは、OpenCVを中心に説明します。




OpenCV

OpenCVはオープンソースで開発される画像処理ライブラリです。

従来はC++のみであったが、最近C#やPythonにも対応しています。

画像データの形式はnumpyのarray型を使用しています。

numpyは数値計算用のライブラリでいくつも便利な関数が定義されています。

なので、実際C++版よりも使いやすいです。




まだ、windowsインストーラのみでは完全にインストールはされないので、

インストール後手動でcv2.pyd(ダイナミックリンクライブラリ)をコピーする必要があります。

python2.6なら

c:\Python26\lib\site-packages\にコピー

python2.7なら

c:\Python27\lib\site-packages

という具合です。