.NET 4.x Получение спектра изображения используя БПФ - C#
Формулировка задачи:
Вообщем есть изображение, нужно вывести спектр этого изображения используя Быстрое преобразование фурье, если у кого есть код или готовая прога поделитесь пожалуйста, а то нужна для диплома, а время поджимает и не успеваю самостоятельно сделать.
Буду ОЧЕНЬ благодарен если кто то поделится кодом)
Заранее Спасибо.
Решение задачи: «.NET 4.x Получение спектра изображения используя БПФ»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Math;
using AForge.Imaging;
namespace FFT
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(openFileDialog1.FileName);
}
pictureBox1.Image = (Bitmap)Bitmap.FromFile(openFileDialog1.FileName);
}
public enum Direction
{
Forward = 1,
// Backward = -1
};
public void FFT(Complex[] data, Direction direction)
{
int n = data.Length;
int m = Tools.Log2(n);
// reorder data first
ReorderData(data);
// compute FFT
int tn = 1, tm;
for (int k = 1; k <= m; k++)
{
Complex[] rotation = GetComplexRotation(k, direction);
tm = tn;
tn <<= 1;
for (int i = 0; i < tm; i++)
{
Complex t = rotation[i];
for (int even = i; even < n; even += tn)
{
int odd = even + tm;
Complex ce = data[even];
Complex co = data[odd];
double tr = co.Re * t.Re - co.Im * t.Im;
double ti = co.Re * t.Im + co.Im * t.Re;
data[even].Re += tr;
data[even].Im += ti;
data[odd].Re = ce.Re - tr;
data[odd].Im = ce.Im - ti;
}
}
}
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
}
public void FFT2(Complex[,] data, Direction direction)
{
Bitmap In = new Bitmap(pictureBox1.Image);
Bitmap Out = new Bitmap(pictureBox1.Image);
int k = In.Width;
int n = In.Height;
k = data.GetLength(0);//row
n = data.GetLength(1);//column
// check data size
if (
(!Tools.IsPowerOf2(k)) ||
(!Tools.IsPowerOf2(n)) ||
(k < minLength) || (k > maxLength) ||
(n < minLength) || (n > maxLength)
)
{
throw new ArgumentException("Incorrect data length.");
}
// process rows
Complex[] row = new Complex[n];
for (int i = 0; i < k; i++)
{
// copy row
for (int j = 0; j < n; j++)
row[j] = data[i, j];
// transform it
FFT(row, direction);
// copy back
for (int j = 0; j < n; j++)
data[i, j] = row[j];
}
// process columns
Complex[] col = new Complex[k];
for (int j = 0; j < n; j++)
{
// copy column
for (int i = 0; i < k; i++)
col[i] = data[i, j];
// transform it
FFT(col, direction);
// copy back
for (int i = 0; i < k; i++)
data[i, j] = col[i];
}
row = Out.Width;
col = Out.Height;
pictureBox2.Image = Out;
}
#region Private Region
private const int minLength = 2;
private const int maxLength = 16384;
private const int minBits = 1;
private const int maxBits = 14;
private static int[][] reversedBits = new int[maxBits][];
private static Complex[,][] complexRotation = new Complex[maxBits, 2][];
// Get array, indicating which data members should be swapped before FFT
private static int[] GetReversedBits(int numberOfBits)
{
if ((numberOfBits < minBits) || (numberOfBits > maxBits))
throw new ArgumentOutOfRangeException();
// check if the array is already calculated
if (reversedBits[numberOfBits - 1] == null)
{
int n = Tools.Pow2(numberOfBits);
int[] rBits = new int[n];
// calculate the array
for (int i = 0; i < n; i++)
{
int oldBits = i;
int newBits = 0;
for (int j = 0; j < numberOfBits; j++)
{
newBits = (newBits << 1) | (oldBits & 1);
oldBits = (oldBits >> 1);
}
rBits[i] = newBits;
}
reversedBits[numberOfBits - 1] = rBits;
}
return reversedBits[numberOfBits - 1];
}
// Get rotation of complex number
private static Complex[] GetComplexRotation(int numberOfBits, Direction direction)
{
int directionIndex = (direction == Direction.Forward) ? 0 : 1;
// check if the array is already calculated
if (complexRotation[numberOfBits - 1, directionIndex] == null)
{
int n = 1 << (numberOfBits - 1);
double uR = 1.0;
double uI = 0.0;
double angle = System.Math.PI / n * (int)direction;
double wR = System.Math.Cos(angle);
double wI = System.Math.Sin(angle);
double t;
Complex[] rotation = new Complex[n];
for (int i = 0; i < n; i++)
{
rotation[i] = new Complex(uR, uI);
t = uR * wI + uI * wR;
uR = uR * wR - uI * wI;
uI = t;
}
complexRotation[numberOfBits - 1, directionIndex] = rotation;
}
return complexRotation[numberOfBits - 1, directionIndex];
}
// Reorder data for FFT using
private static void ReorderData(Complex[] data)
{
int len = data.Length;
// check data length
if ((len < minLength) || (len > maxLength) || (!Tools.IsPowerOf2(len)))
throw new ArgumentException("Incorrect data length.");
int[] rBits = GetReversedBits(Tools.Log2(len));
for (int i = 0; i < len; i++)
{
int s = rBits[i];
if (s > i)
{
Complex t = data[i];
data[i] = data[s];
data[s] = t;
}
}
}
#endregion
private void button2_Click(object sender, EventArgs e)
{
}
}
}