画像に対するフーリエ変換の物理的意味を考える

対象 説明
信号 縦軸を振幅、横軸を時間とした波形情報を周波数の分布に変換する
画像 縦軸を1ピクセルあたりの画素強度、横軸を座標として、ピクセル間の強度値変化を周波数分布に変換する

画像に対するフーリエ変換のピクセルあたりの画素強度の例として、1×7サイズのグレースケール画像を考える。例えば下記のようなもの(ここでは視認性のため、拡大した画像で表示)。

2dfft_row_column

画素強度値は明るいほど値が大きい。つまりグレースケールの255階調で考えれば、白い箇所は255、黒い箇所は0の値となる。先ほどの画像にピクセル毎に強度値を重ねて表示すると下記のような値を持つ。

2dfft_row_column

上記画像の強度値を、縦軸を1ピクセルあたりの画素強度、横軸を座標として表しなおしたグラフが下記。画像に対するフーリエ変換はこのグラフに対して行っていることになる
pixel peak

ただし通常画像はもっと大きなサイズであり、1ピクセル高ということはない。そのため、実際には各ピクセル行に対してフーリエ変換を行う。各行へのフーリエ変換の実施後はデータを転置し、転置後のデータに対して再度各行に対してフーリエ変換を実施する。その後再度転置を行いデータの向きを元に戻す作業を行う。これで画像に対する2次元フーリエ変換となる。
2dfft_row_column

ここまでの内容をpythonコードにしたものが下記。

2dfft_row_column

numpyとopenCVを使った画像のフーリエ変換と逆変換

openCVを使い画像読み込み、fftで周波数データに変換。その後逆変換で元の画像に戻すテスト。

入力に使用する画像は↓。サイズは360×240。
input data to fft

まず画像入力、グレースケールで取り込む。

実行すると元の画像がグレースケールで表示される。
imreadは引数2つ、1つ目は読み込みファイル、2つ目は読み込みオプションで以下3つ(1,0,-1でも指定可)。

  cv2.IMREAD_COLOR (or 1)
  cv2.IMREAD_GRAYSCALE (or 0)
  cv2.IMREAD_UNCHANGED (or -1)

続けてFFT実施

np.fft.fft2()は2次元FFT。
実行結果が下記。入力が360×240画像だったので、360×240のnumpy arrayで返ってくる。

変換結果をパワースペクトルで確認してみる。確認に使用したコードが下記。

実行結果下記
input data to fft

最後に逆変換で元の画像に戻すコード。注意として変換後の結果には複素数成分が含まれているので、実部を取り出す処理が必要。またグレースケールで表示するために0-255階調への値調整が必要になる。

実行結果が下記グレースケールでもとの画像に戻ってきた。
results fft and inv fft

Read images using openCV, convert to frequency data with fft. And then back to the original image with reverse transformation.
Code 1 is reading image by gray scale.
Code 2 is 2D fft by numpy. Frequency distribution is returned.
Code 3 is checking Power spectrum.
Code 4 is invers Fourie by numpy.

pythonのmultiprocessingを使いクーロン力の並列計算をするテスト

前回クーロン力計算部分の高速化を検討した。結果としてはシンプルに2重ループを使った計算。今回はこのクーロン力計算部分をmultiprocessingを使ったマルチプロセスによる並列化で高速化を試してみる。

作成したコードが下記。結果は2.09[sec]。使用coreは4スレッド仕様なので、4プロセスでの処理を行った。前回の処理時間が約8秒であったのを考えると、理想どおり4分の1になる結果が得られた。

■結果 [Results summary]

code type 時間[sec]
multiprocessing (4core) 2.09 <-(new)
itertools使用 (no1) 8.18
range記述 (no2) 7.93
xrange記述 (no3) 7.89
ループ内周でnumpy使用 (no4) 78.46

We examined the speedup of the previous Coulomb force calculation part. As a result, more fast results calculation was using a simple double loop. In this time, I will try speeding up by multiprocessing parallel processing of this Coulomb force calculation part.

The code you created is below. The result is 2.09 [sec]. Since core used is 4 thread specification, processing in 4 processes was done. Considering that the last processing time was about 8 seconds, the result was 1/4 as ideal.

クーロン力計算の高速化検討

前回イオントラップシミュレーションにて、分子動力学のopenGLを使った可視化を行った。この処理にかかるほぼすべての時間はクーロン力計算の箇所であり、各粒子同士の計算が必要となる。粒子数をN個とすると、計算量は1ステップあたりNC2回が必要となる。特に今回のイオントラップの様な、閉じた系の中では周期境界条件が存在しないため、Ewald methodの様な高速化の方法も用いることができない。

今回はこのイオントラップにおけるクーロン力計算の高速化を検討してみたいと思う。まず高速化対象のコードだけを抜き出してきたのが下記。

上記コードの処理時間は手元の環境で約8.18[sec](10回実行した平均)
このコードのfind_pair関数内のitertools箇所を下記の様にシンプルにforループを2重で処理する様書き替えた場合が下記。

上記コードの処理時間は約7.93[sec](10回実行した平均)。
itertoolsを使った方が高速になるのかなと思ってたけど、シンプルにforの2重ループの方が高速な結果になった。

次に、forループ範囲をrangeコマンドで作っているのを、xrangeに変更してみる。rangeは内部でリストを生成してから要素参照するのに対して、xrangeはリストを作らず要素参照するらしい。

上記コードで約7.89[sec](10回実行した平均)。
気持ち速くなった程度だった。今回は粒子数15^3個で試しているが、数を増やしたら効果が出てくるかもしれない。

最後、numpyを使ってみる。どうしても上手い使い方が思い浮かばず、forループの中の演算を無理矢理numpyを使った処理に書き替えた。

上記コードで約78.46[sec](10回実行した平均)。
全然駄目だった。多重ループの内周で、何度も実行されるような場所にnumpyの処理を配置するととんでもなく遅くなる。遅くなるとは思っていたが予想以上の重さ。

■結果 [Results summary]

code type 時間[sec]
itertools使用 (no1) 8.18
range記述 (no2) 7.93
xrange記述 (no3) 7.89
ループ内周でnumpy使用 (no4) 78.46

あと考えられる手法はスレッド化。これはまた今度試してみたいと思う。

We performed visualization using openGL of molecular dynamics in the previous ion trap simulation. Almost all the time required for this process is the location of the Coulomb force calculation and it is necessary to calculate each particle. Assuming that the number of particles is N, the amount of calculation needs NC2 Times per step. Especially in the closed system such as the ion trap of this time there is no periodic boundary condition, so speeding method like Ewald method can not be used.

In this time I would like to examine how to speed up the calculation of the Coulomb force in this ion trap.

First, Code No1 that it has been extracted only the code of speeding up the subject. Results time is 8.18sec.

Code No.2 is when the itertools location in the above find_pair function is rewritten with a double for loop.Results time is 7.93sec.

Code No 3 changes range to xrange.Results time is 7.89sec.

Last Code No4 use numpy.But, Since it is used many times on the inner periphery, slow processing can be expected.Results time is 78.46sec.

Another possible method is threading. I want to try this again next time.

numpy/opencv 2次元FFT

離散フーリエ変換(DFT)の高速化版アルゴリズムFFTをnumpyで試す。

■結果
input.png
FFT input img
result.png
FFT results img

numpy 行列の積

行列の積の計算サンプル

■実行結果
c= [[-2 -2]
[ 7 8]]

※計算内容はこちらをつかわせてもらいました。。