• 締切済み

2次元データの複素フーリエ変換するコードの作成

数値計算等の2次元や3次元の空間データ(実数)をFFTによって複素フーリエ変換する実際のプログラム化についてお尋ねします。プログラムの実装ということなので実際的な質問で長文になっています。すみません。 まず、手持ちに1次元のFFTプログラムがあるということを前提とします(逆フーリエ変換すると、元の実数の系列が出ることは確認済のコード)。そして2次元配列の実数のデータがあるとします。この2次元のデータを2次元の複素フーリエ成分に変換することが目的です。(私の分野では波数空間への展開ということになり、複素数ですから位相情報も含まれることになります。) 例えば、x,y方向に16x16のデータあるとすると、 do j=1,16 ここでjを固定してi:1~16の実数データについて1次元のFFTをかける。 このとき、FFTにかける16個の実数データを複素数の実部に入れて、虚部はゼロとする。 FFTの出力も複素数となっている。 ここで出てくる複素フーリエ変換の結果は実部・虚部で前半(0~7)であり、後半(8~15)はその対称とか点対称(符号が逆)とかになっている(虚部をゼロとしているから)。それを複素数の2次元配列として保存する。 enddo 次いで、 do i=1,16 iを固定してj方向にFFTをかける。このとき、FFTに放り込むデータは上記の複素フーリエ変換の出力結果である2次元データを使う。具体的には複素数の2次元データをj方向の1次元の複素数配列にコピーしてFFTをかけて、その出力結果を新たな2次元配列の複素数に保存する。 enddo この結果、得られた2次元の複素数のデータが、私の所望のデータである、ということです。 式が指し示すとおりのことをすればいいのだ、ということに尽きるのだろうと思いますが、アルゴリズム的にアンバランスのように見えてこれでいいのかなと思えてしまいます。最初に虚部をゼロにするというようなこととかです。そのため確信が持てません。また、結果を見てもわかりにくい面があります。 このような考え方で実装するということいいのでしょうか。全く間違っているでしょうか。もしその場合、考え方の間違いを指摘して頂けると助かりますが(根本的な間違いだったら指摘しようがないということにもなりますが。) また、例えば、始めから実数の2次元配列をすぐに2次元複素数の実部に入れて、虚部をゼロとしてそこからコード方がすっきりするのかなと思いますが。 この辺が確定すると、3次元は同じことということになります。 サンプルコードがネットに出ているという面もありますが、自分でやる方が組み込みやすいのでお尋ねしました。 長文で申し訳ありませんが、よろしくお願いします。

みんなの回答

回答No.1

そのやり方で良いと思いますよ。 ただ、もしかしたら最後にx方向とy方向の転置が必要かも知れません。 私がやってみると、そういうことになってしまったので(私のミスかも知れませんが)。 「また、例えば、始めから実数の2次元配列をすぐに2次元複素数の実部に入れて、虚部をゼロとしてそこからコード方がすっきりするのかなと思いますが。」については私はそういうのを知りません。専門家のご登場待ちとなります。

skmsk1941093
質問者

お礼

回答ありがとうございます。お礼が遅れてすみません。”最後に転置”というところをもう少し詳しく教えて頂ければと思います。最後の出力結果(複素数の2次元配列)の加工ということでしょうか。 また、実験された結果で気がつかれたということだろうと思います。どのように実験されたのでしょうか。例えば、スペクトル情報を先に与えて、それからなんらかの方法で空間データを作成し、その2次元のフーリエ変換の結果が最初に与えたスペクトル情報と合致することの確認かなと思います。その”なんらかの方法”がフーリエ逆変換というわけにはいかないと思います。その妥当性をチェックしようとしているからですが。いかがでしょうか。

関連するQ&A

  • 2次元データのフーリエ変換とデータ形式について

    画像やエクセルシートのように平面2次元的に広がっているデータがあります。このデータについて2回(2方向)のフーリエ変換を取るのですが、1回(1方向)のフーリエ変換プログラムを2回(2方向)することになると思います。 複素フーリエなので、1回目は複素数型の配列の実部に解析したいデータ系列、虚部はゼロとしてフーリエ変換します。この場合の出力値(複素数配列)で意味があるのは、実部、虚部の配列の前半だけであり、後半は前半の対称とか点対称になっています(前半が分かれば後半がわかるのだから情報量としてはゼロ)。 1回目の出力結果を2回目の変換に渡すわけですが、1回目の出力としての複素数配列のデータはその意味のないところも含めてフーリエ変換に渡すのでしょうか。 フーリエ逆変換で元に戻すときは、”無意味”な対称・点対称成分も含めて逆変換するわけですからその部分も必要ということでしょうか。その方がプログラムとしてはラクではあります。何もしないということなので。 説明がヘタだなと思いますが、主旨を汲み取り頂いて回答して頂けると助かります。 よろしくお願いします。

  • フーリエ変換のデータ点数を増やしたい

    現在はエクセルでフーリエ変換・逆フーリエ変換を行っていますが、最大で4096点までしか扱えないそうです。 都合上、16384点のデータをフーリエ変換・逆フーリエ変換を行いたいと思っています。そこで、フリーソフトのFFT君を試してみたのですが、逆フーリエ変換の際に1つのデータしか変換できないみたいです。つまり、複素数の実部・虚部の2つのデータを一度に逆フーリエ変換したいということです。 何かよい方法がありましたら教えていただけないでしょうか。よろしくお願いします。

  • 画像の離散フーリエ変換

    現在画像の離散フーリエ変換をしており、 「c言語で学ぶ実践画像処理」という本には、 水平方向に1次元の離散フーリエ変換をした後、垂直方向に1次元の離散フーリエ変換をすれば良いと書いてあるのですが、 疑問があります。 最初に実部用の配列と虚部用の配列を用意します。 原画像を水平方向に離散フーリエ変換します。 そうすると、初めに用意した実部、虚部用の配列に値が入ります。 ここからさらに垂直方向の離散フーリエ変換をすると、 実部の垂直方向の離散フーリエ変換から実部と虚部が出て、 虚部の垂直方向の離散フーリエ変換から実部と虚部が出て、最終的には実部用の配列が2個、虚部用の配列が2個必要で、 ここからどうやって離散逆フーリエ変換や、振幅スペクトルを求められるのだろうかと混乱しております。 水平方向に1次元の離散フーリエ変換をした後、垂直方向に1次元の離散フーリエ変換はどのようにすれば良いのでしょうか? よろしくお願いいたします。

  • 複素数と実数が混在するように見える式について

    時系列解析で、自己相関係数のフーリエ変換がパワースペクトルになるというウィナーキンチンの関係というものがあります。その式では複素数が含まれているので、実数を入力として複素数が含まれている式で計算された出力結果は普通は複素数ということになります。しかし、自己相関係数は実数の系列で、パワースペクトルも実数になると思います(実部と虚部の2乗和なので)。実数に複素数を絡ませて変換して出てきたものが実数になるということになってしまいます。ここが理解できないのですが、どのように考えていくのでしょうか。絶対に虚部がゼロになるから、ということなのでしょうか。 一般にFFTによるスペクトル変換では実数列は複素数の実部にあてて変換する(例えば虚部はゼロにしておくとか)ので複素数から複素数を入出力するということで理解できます。 実際にプログラムでの処理を考えているので概念的な説明だけでは実装することできません。 なお、私は常に標準的なFFTでフーリエ変換しているので複素数での入出力ということなので実数となる系列では先に進めないという感じなのですが。もし出力が実数ということになったとき実部がそれ、虚部がそれ、実部と虚部の2乗和がそれ、というのならわかるのですが。 よろしくお願いします。

  • 複素フーリエ変換の位相について

    画像のとおり位相0度から始まるA列の正弦波を複素フーリエ変換しました。 その実部、虚部のグラフがReal、Imagです。 虚数のみ正弦波の周波数のところにピークがあって、実部は0です。つまりこれは位相が90度又は-90度という事になります。 試しに45度から始まる正弦波を複素フーリエ変換すると、上記は-45度になりました。 フーリエ変換の位相というのはそれぞれの周波数成分を正弦波として開始時の位相を求めるものと思っていましたが、実は余弦波だとしているという事なのでしょうか?

  • 音の逆フーリエ変換

    音のデータをFFTし、目的の周波数帯を削ってRFTするソフトを作っています。しかし、実部の削り方は分かっても、虚部のどこを削ると、目的の周波数帯を削ることができるのか分かりません。あるいは虚部には触れなくてよいのでしょうか。実部だけ目的の部分を削ってRFTすると、意外な音が聞こえてきました。 音声加工、(逆)フーリエ変換について教えてください!

  • 2次元FFTとFFTについて

    FFT結果は実部と虚部に分かれています。 ってよくあるのですが、2次元FFTの結果も実部と虚部に分かれているのですか? でも、調べてみると2次元FFTの結果は、実部だけとあります。 FFTは、実部と虚部の絶対の2乗、2次元FFTは、実部だけ?矛盾しているような? もし、2次元FFTの結果が実部だけでしたら、虚部はどのようにすればいいのですか? 実部と虚部とは、なんですか?正弦波をFFTすると実部と虚部をどのように分かれるのですか? ご指導の方、よろしくお願いします。

  • 画像の2次元フーリエ変換の結果の表示の仕方について

    現在、C言語で画像に2次元離散フーリエ変換を施し、高速フーリエ変換と比較しろという課題に取り組んでいます。 以下の様なプロセスで2次元フーリエ離散変換を施し、結果を表示しようと思っています。 ・画像を読み込み、float型配列に入れる。 (画像は一番左上が原点とします。256×256のサイズです) ・上記のfloat型配列の、第1象限と第3象限、第2象限と第4象限を各々入れ替える。 ・各行ごと、つまり、f[0][0]~f[0][255]、f[1][0]~f[1][255]、と順々)に1次元離散フーリエ変換を施す。 ・上記のフーリエ変換の結果を各列ごと、つまり、f[0][0]~f[255][0],f[1][1]~f[255][1]という風に1次元離散フーリエ変換を施す。 ・フーリエ変換の結果の、第1象限と第3象限、第2象限と第4象限を各々入れ替える。 ・f[][]のパワースペクトル(実部の2乗+虚部の2乗の、自然対数をとったもの)を計算する。 ・そのパワースペクトルとをfloat型なので、char型に置き換えて画像として出力する。 正規化等の少し細かいところは省略しました。 結果として、参考書等で見かけるもの(真ん中が直流成分で、含まれる周波数を濃淡で表したもの)になればいいのですが、上記のプロセスで大丈夫ですか? パワースペクトルを計算した後に、何らかの移動の処理(つまり、画像の真ん中が直流成分となるような処理)を施す必要がなく、 フーリエ変換の計算の前と後に象限の入れ替えを施すだけで、直流成分が出力画像の真ん中に来るということですか? フーリエ変換の前と後で、象限を入れ替えるだけで周波数空間では原点が真ん中になることが納得できないです。 ややこしい質問ですが、「プロセスのここが間違ってるよ」等を教えていただけると助かります。特にパワースペクトルの部分等。 よろしくお願いします。

  • 2次元離散フーリエ変換について

    2次元離散フーリエ変換の2次元FFTを用いて、縦256×横256 縦1024×横1024の場合の画像を大きさを求めてもらいたいです。 2次元フーリエ変換について調べたのですが理解することが出来ませんでした。 お手数ですが回答お願いします

  • 多次元高速フーリエ変換について

    高速フーリエ変換fftによって、計算量のオーダーが n^2 からnlogn まで落とせるんですよね? それで、3次元のフーリエ変換って、 1次元のフーリエ変換を3回やれば n^2*nlogn=n^3lognのオーダーでできると思うのですが、 これ以上速いオーダーではできませんか?