600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 图像的傅里叶变换 java_java使用傅里叶变换 得到变换之后的傅里叶频谱图像。...

图像的傅里叶变换 java_java使用傅里叶变换 得到变换之后的傅里叶频谱图像。...

时间:2022-12-01 09:40:42

相关推荐

图像的傅里叶变换 java_java使用傅里叶变换 得到变换之后的傅里叶频谱图像。...

使用傅里叶变换来处理图像,可以滤波,去噪。 但是网络上java实现很少,可以运行的就更少,我总结了一些代码,并加以调试,

保证速度的情况下得以运行成功。 这些代码仅对灰度图验证通过。学习之用。

调用结果可以用http://cns-alumni.bu.edu/~slehar/fourier/fourier.html#filtering 网站的图片验证:

输入图像:ff8.bmp 输出图像fft_result.bmp

输入图像:ff8.bmp 输出图像fft_result.bmp

所有FFT变换都已经验证通过。 但是傅里叶逆变换没有成功。 有高手可以指点一下。 如何使逆变换的图片显示出来。

FFT 类负责一维变换:

package app.fourier;

public class FFT {

//double r_data[] = null;

//double i_data[] = null;

// compute the FFT of x[], assuming its length is a power of 2

public static void fft(Complex[] src, int row, int width, Complex[] dest) {

Complex[] temp = new Complex[width];

for (int k = 0; k < width; k++) {

temp[k] = src[row * width + k];

}

temp = fft(temp);

//set output

for (int k = 0; k < width; k++) {

dest[row * width + k] = temp[k];

}

}

public static Complex[] fft(Complex[] x) {

int N = x.length;

// base case

if (N == 1)

return new Complex[] { x[0] };

// radix 2 Cooley-Tukey FFT

if (N % 2 != 0) {

throw new RuntimeException("N is not a power of 2");

}

// fft of even terms

Complex[] even = new Complex[N / 2];

for (int k = 0; k < N / 2; k++) {

even[k] = x[2 * k];

}

Complex[] q = fft(even);

// fft of odd terms

Complex[] odd = even; // reuse the array

for (int k = 0; k < N / 2; k++) {

odd[k] = x[2 * k + 1];

}

Complex[] r = fft(odd);

// combine

Complex[] y = new Complex[N];

for (int k = 0; k < N / 2; k++) {

double kth = -2 * k * Math.PI / N;

Complex wk = new Complex(Math.cos(kth), Math.sin(kth));

y[k] = q[k].plus(wk.times(r[k]));

y[k + N / 2] = q[k].minus(wk.times(r[k]));

}

return y;

}

}

Complex类是复数类:

public class Complex {

public double re; // the real part

public double im; // the imaginary part

public Complex() {

re = 0;

im = 0;

}

// create a new object with the given real and imaginary parts

public Complex(double real, double imag) {

re = real;

im = imag;

}

// return a string representation of the invoking Complex object

public String toString() {

if (im == 0) return re + "";

if (re == 0) return im + "i";

if (im < 0) return re + " - " + (-im) + "i";

return re + " + " + im + "i";

}

// return abs/modulus/magnitude and angle/phase/argument

public double abs() { return Math.hypot(re, im); } // Math.sqrt(re*re + im*im)

public double phase() { return Math.atan2(im, re); } // between -pi and pi

// return a new Complex object whose value is (this + b)

public Complex plus(Complex b) {

Complex a = this; // invoking object

double real = a.re + b.re;

double imag = a.im + b.im;

return new Complex(real, imag);

}

// return a new Complex object whose value is (this - b)

public Complex minus(Complex b) {

Complex a = this;

double real = a.re - b.re;

double imag = a.im - b.im;

return new Complex(real, imag);

}

// return a new Complex object whose value is (this * b)

public Complex times(Complex b) {

Complex a = this;

double real = a.re * b.re - a.im * b.im;

double imag = a.re * b.im + a.im * b.re;

return new Complex(real, imag);

}

// scalar multiplication

// return a new object whose value is (this * alpha)

public Complex times(double alpha) {

return new Complex(alpha * re, alpha * im);

}

// return a new Complex object whose value is the conjugate of this

public Complex conjugate() { return new Complex(re, -im); }

// return a new Complex object whose value is the reciprocal of this

public Complex reciprocal() {

double scale = re*re + im*im;

return new Complex(re / scale, -im / scale);

}

// return the real or imaginary part

public double re() { return re; }

public double im() { return im; }

// return a / b

public Complex divides(Complex b) {

Complex a = this;

return a.times(b.reciprocal());

}

// return a new Complex object whose value is the complex exponential of this

public Complex exp() {

return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im));

}

// return a new Complex object whose value is the complex sine of this

public Complex sin() {

return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im));

}

// return a new Complex object whose value is the complex cosine of this

public Complex cos() {

return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im));

}

// return a new Complex object whose value is the complex tangent of this

public Complex tan() {

return sin().divides(cos());

}

// a static version of plus

public static Complex plus(Complex a, Complex b) {

double real = a.re + b.re;

double imag = a.im + b.im;

Complex sum = new Complex(real, imag);

return sum;

}

}

FourierTransformer 为主调类:

import java.awt.Graphics;

import java.awt.Image;

import java.awt.image.BufferedImage;

import java.awt.image.ColorModel;

import java.awt.image.PixelGrabber;

import java.awt.image.WritableRaster;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

@SuppressWarnings("serial")

public class FourierTransformer extends JFrame{

Image im;

BufferedImage imageAuth = null;

int iw;

int ih;

int[] pixels;

int[] newPixels;

public FourierTransformer() {

try {

this.im = ImageIO.read(getClass().getResource("fft8.bmp"));

} catch (IOException e1) {

e1.printStackTrace();

}

this.iw = im.getWidth(null);

this.ih = im.getHeight(null);

pixels = new int[iw * ih];

try {

PixelGrabber pg = new PixelGrabber(im, 0, 0, iw, ih, pixels, 0, iw);

pg.grabPixels();

} catch (InterruptedException e3) {

e3.printStackTrace();

}

}

public void paint(Graphics g) {

super.paint(g);

g.drawImage(this.im, 0, 100, this.iw, this.ih, this);

if(imageAuth != null)

g.drawImage(imageAuth, 250, 100, imageAuth.getWidth(), imageAuth.getHeight(), this);

}

public static void main(String[] args){

FourierTransformer frame = new FourierTransformer();

frame.setSize(600, 500);

frame.setTitle("ImageMenu");

frame.setName("hello my dongjing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

frame.convert(frame.getGraphics());

}

public Image convert(Graphics g) {

// 赋初值

int w = 1;

int h = 1;

// 计算进行付立叶变换的宽度和高度(2的整数次方)

while (w * 2 <= iw) {

w *= 2;

}

while (h * 2 <= ih) {

h *= 2;

}

// 分配内存

Complex[] src = new Complex[h * w];

Complex[] dest = new Complex[h * w];

newPixels = new int[h * w];

// 初始化newPixels

for (int i = 0; i < h; i++) {

for (int j = 0; j < w; j++) {

newPixels[i * w + j] = pixels[i * iw + j] & 0xff;

}

}

// 初始化src,dest

for (int i = 0; i < h; i++) {

for (int j = 0; j < w; j++) {

dest[i * w + j] = new Complex();

src[i * w + j] = new Complex(newPixels[i * w + j], 0);

}

}

// 在y方向上进行快速傅立叶变换

for (int i = 0; i < h; i++) {

FFT.fft(src, i, w, dest);

}

/**

* 以下一定要进行转换,高手指点一下原因 (^ - ^)

*/

for (int i = 0; i < h; i++) {

for (int j = 0; j < w; j++) {

src[j * h + i] = dest[i * w + j];

//System.out.println("dest " + j*h+i + ", src " + i*w+j);

}

}

// 对x方向进行傅立叶变换

for (int i = 0; i < w; i++) {

FFT.fft(src, i, h, dest);

}

/**

* 将图像看做二维函数,图像灰度值为函数在相应XY处的函数值,对其进行二维快速傅里叶变换,

* 得到一个复数矩阵,将此矩阵水平循环移动半宽,垂直循环移动半高。

*/

for (int i = 0; i < h; i++) {

for (int j = 0; j < w; j++) {

double re = dest[j * h + i].re;

double im = dest[j * h + i].im;

int ii = 0, jj = 0;

int temp = (int) (Math.sqrt(re * re + im * im) / 100);

if (temp > 255) {

temp = 255;

}

if (i < h / 2) {

ii = i + h / 2;

} else {

ii = i - h / 2;

}

if (j < w / 2) {

jj = j + w / 2;

} else {

jj = j - w / 2;

}

newPixels[ii * w + jj] = temp;

}

}

imageAuth = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);

ColorModel colorModel = imageAuth.getColorModel();

WritableRaster raster = colorModel.createCompatibleWritableRaster(w, h);

raster.setPixels(0, 0, w, h, newPixels);

imageAuth.setData(raster);

try {

ImageIO.write(imageAuth, "bmp", new File("fft_result.bmp"));

} catch (IOException e) {

e.printStackTrace();

}

this.update(g);

return imageAuth;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。