今天看啥  ›  专栏  ›  @一头雾水@

图像处理 傅里叶滤波

@一头雾水@  · CSDN  ·  · 2019-11-17 12:15

在文章的最下面有详细代码。

原图:

一、傅里叶变换。

1、介绍。

可以查看我的关于傅里叶变换的代码。

2、代码。

    public static void main(String[] args) {
        //均值滤波
        String sourcePath = "G:\\xiaojie-java-test\\img\\阿卡丽.jpg";
        String targetPath = "G:\\xiaojie-java-test\\img\\滤波\\傅里叶滤波\\阿卡丽\\";
        getSpectrum(sourcePath, targetPath + "频谱图.jpg", 0, FourierUtils.Type_Filter_Low);
    }

    private static void getSpectrum(String sourcePath, String targetPath, int percent, int type) {
        try {
            //获取原图像对象,并获取原图像的二维数组
            BufferedImage image = ImageIO.read(new File(sourcePath));
            int[][] imgArrays = ImageUtils.getBytes(image);
            //生成新图像的二维数组
            Complex[][] complexArray = FourierUtils.getFft(imgArrays);
            int[][] spectrumArray = FourierUtils.getSpectrum(complexArray, percent, type);
            //生成新图片对象,填充像素
            BufferedImage newImage = new BufferedImage(spectrumArray.length, spectrumArray.length, BufferedImage.TYPE_BYTE_GRAY);
            ImageUtils.setInts(newImage, spectrumArray);
            //生成图片文件
            ImageIO.write(newImage, "JPEG", new File(targetPath));
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取频谱值,并中心化 |F(k)|=Math.sqrt(实数的平方 + 虚数的平方)
     *
     * @param complexArray FFT之后的 complexArray[][]
     * @param percent      过滤半径的百分比
     * @param type         高频过滤、低频过滤
     */
    public static int[][] getSpectrum(Complex[][] complexArray, int percent, int type) {
        int length = complexArray.length;
        //
        int[][] array = new int[length][length];
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                double real = complexArray[i][j].getReal();
                double image = complexArray[i][j].getImage();
                int a = (int) Math.sqrt(real * real + image * image);
                array[i][j] = a;
            }
        }
        return array;
    }

3、结果。

二、将低频部分移到中间。

1、介绍。

将低频部分移到中间,就是将矩阵的第一象限和第三象限对调,第二象限和第四象限对调。

2、代码。

/**
 * 获取频谱值,并中心化 |F(k)|=Math.sqrt(实数的平方 + 虚数的平方)
 *
 * @param complexArray FFT之后的 complexArray[][]
 * @param percent      过滤半径的百分比
 * @param type         高频过滤、低频过滤
 */
public static int[][] getSpectrum(Complex[][] complexArray, int percent, int type) {
    int length = complexArray.length;
    int middle = length / 2;
    int iShift, jShift;
    int filterLength = (int) (length / 200.0 * percent);
    double centerIndex = (length - 1) / 2.0;
    //
    int[][] array = new int[length][length];
    for (int i = 0; i < length; i++) {
        for (int j = 0; j < length; j++) {
            double real = complexArray[i][j].getReal();
            double image = complexArray[i][j].getImage();
            int a = (int) Math.sqrt(real * real + image * image);
            //将矩阵分成四块,第一象限和第三象限对调,第二象限和第四象限对调
            iShift = i < middle ? i + middle : i - middle;
            jShift = j < middle ? j + middle : j - middle;
            //
            if (filterLength > NumberUtils.getDistance(iShift, jShift, centerIndex, centerIndex)) {//圆内
                array[iShift][jShift] = type == Type_Filter_High ? a : 0;
            } else {//圆外
                array[iShift][jShift] = type == Type_Filter_Low ? a : 0;
            }
        }
    }
    return array;
}

3、结果。

三、高频率和低频滤波。

1、介绍。

低频滤波,将频谱图中间的保留住,会使原图像变模糊。高频滤波,将频谱图中间的去除,会保留原图像的边缘。

2、主流程代码(FourierTest .java)。

package com.zxj.reptile.test.image.filter;

import com.zxj.reptile.utils.image.FourierUtils;
import com.zxj.reptile.utils.image.ImageUtils;
import com.zxj.reptile.utils.number.Complex;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * 傅里叶滤波
 */
public class FourierTest {
    public static void main(String[] args) {
        String sourcePath = "G:\\xiaojie-java-test\\img\\阿卡丽.jpg";
        String targetPath = "G:\\xiaojie-java-test\\img\\滤波\\傅里叶滤波\\阿卡丽\\";

        //当type=Type_Filter_Low时,percent=0时,或者当type=Type_Filter_High时,percent=100时,IFFT之后会是原图
        getSpectrum(sourcePath, targetPath + "频谱图.jpg", 0, FourierUtils.Type_Filter_High);

        getSpectrum(sourcePath, targetPath + "high_1.jpg", 1, FourierUtils.Type_Filter_High);
        getSpectrum(sourcePath, targetPath + "high_2.jpg", 2, FourierUtils.Type_Filter_High);
        getSpectrum(sourcePath, targetPath + "high_3.jpg", 3, FourierUtils.Type_Filter_High);
        getSpectrum(sourcePath, targetPath + "low_10.jpg", 10, FourierUtils.Type_Filter_Low);
        getSpectrum(sourcePath, targetPath + "low_20.jpg", 20, FourierUtils.Type_Filter_Low);
        getSpectrum(sourcePath, targetPath + "low_30.jpg", 30, FourierUtils.Type_Filter_Low);
    }

    private static void getSpectrum(String sourcePath, String targetPath, int percent, int type) {
        try {
            //获取原图像对象,并获取原图像的二维数组
            BufferedImage image = ImageIO.read(new File(sourcePath));
            int[][] imgArrays = ImageUtils.getBytes(image);

            //频谱图
            //生成新图像的二维数组
            Complex[][] complexArray = FourierUtils.getFft(imgArrays);
            int[][] spectrumArray = FourierUtils.getSpectrum(complexArray, percent, type);
            //生成新图片对象,填充像素
            BufferedImage newImage = new BufferedImage(spectrumArray.length, spectrumArray.length, BufferedImage.TYPE_BYTE_GRAY);
            ImageUtils.setInts(newImage, spectrumArray);
            //生成图片文件
            ImageIO.write(newImage, "JPEG", new File(targetPath));
            Thread.sleep(1);

            //原图
            //生成新图像的二维数组
            FourierUtils.getFilter(complexArray, spectrumArray);
            int[][] newImgArrays = FourierUtils.getInverseFft(complexArray, imgArrays.length, imgArrays[0].length);
            //生成新图片对象,填充像素
            newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
            ImageUtils.setIntsForGray(newImage, newImgArrays);
            //生成图片文件
            targetPath = targetPath.split("\\.")[0] + "_原图." + targetPath.split("\\.")[1];
            ImageIO.write(newImage, "JPEG", new File(targetPath));
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、原图。

4、高频,半径1。

5、高频,半径2.

6、高频,半径3。

7、低频,半径10。

8、低频,半径20。

9、低频,半径30。

四、详细代码

1、ImageUtils.java。

package com.zxj.reptile.utils.image;

import java.awt.image.BufferedImage;

/**
 * 要用int,不能使用byte,因为byte最大值为128
 */
public class ImageUtils {
    //灰度处理的方法
    public static final byte Gray_Type_Min = 1;//最大值法
    public static final byte Gray_Type_Max = 2;//最小值法
    public static final byte Gray_Type_Average = 3;//平均值法
    public static final byte Gray_Type_Weight = 4;//加权法
    public static final byte Gray_Type_Red = 5;//红色值法
    public static final byte Gray_Type_Green = 6;//绿色值法
    public static final byte Gray_Type_Blue = 7;//蓝色值法
    public static final byte Gray_Type_Default = Gray_Type_Average;//默认加权法

    /**
     * 灰度化处理,彩色int[][] 转 灰度int[][]
     *
     * @param imgArrays 图像二维数组
     * @param grayType  灰度化方法
     */
    public static int[][] getGrayImg(int[][] imgArrays, int grayType) throws Exception {
        int[][] newImgArrays = new int[imgArrays.length][imgArrays[0].length];
        for (int h = 0; h < imgArrays.length; h++)
            for (int w = 0; w < imgArrays[0].length; w++)
                newImgArrays[h][w] = getGray(getRgb(imgArrays[h][w]), grayType);
        return newImgArrays;
    }

    /**
     * 根据像素,返回r、g、b 的 int[]
     *
     * @param pixel 像素值
     */
    private static int[] getRgb(int pixel) {
        int[] rgb = new int[3];
        rgb[0] = ((pixel >> 16) & 0xff);
        rgb[1] = ((pixel >> 8) & 0xff);
        rgb[2] = (pixel & 0xff);
        return rgb;
    }

    /**
     * 根据r、g、b 的 int[],返回灰度值
     *
     * @param rgb      r、g、b颜色通道的值
     * @param grayType 不同灰度处理的方法
     */
    private static int getGray(int[] rgb, int grayType) throws Exception {
        if (grayType == Gray_Type_Average) {
            return ((rgb[0] + rgb[1] + rgb[2]) / 3);   //rgb之和除以3
        } else if (grayType == Gray_Type_Weight) {
            return (int) (0.3 * rgb[0] + 0.59 * rgb[1] + 0.11 * rgb[2]);
        } else if (grayType == Gray_Type_Red) {
            return rgb[0];//取红色值
        } else if (grayType == Gray_Type_Green) {
            return rgb[1];//取绿色值
        } else if (grayType == Gray_Type_Blue) {
            return rgb[2];//取蓝色值
        }
        //比较三个数的大小
        int gray = rgb[0];
        for (int i = 1; i < rgb.length; i++) {
            if (grayType == Gray_Type_Min) {
                if (gray > rgb[i]) {
                    gray = rgb[i];//取最小值
                }
            } else if (grayType == Gray_Type_Max) {
                if (gray < rgb[i]) {
                    gray = rgb[i];//取最大值
                }
            } else {
                throw new Exception("grayType出错");
            }
        }
        return gray;
    }

    /**
     * 获取图像像素 int[][]
     *
     * @param image BufferedImage图像对象
     */
    public static int[][] getInts(BufferedImage image) {
        int[][] imgArrays = new int[image.getHeight()][image.getWidth()];
        for (int i = 0; i < image.getHeight(); i++)
            for (int j = 0; j < image.getWidth(); j++)
                imgArrays[i][j] = image.getRGB(j, i);
        return imgArrays;
    }

    /**
     * 获取图像像素 int[][]
     *
     * @param image BufferedImage图像对象
     */
    public static int[][] getBytes(BufferedImage image) throws Exception {
        return getGrayImg(getInts(image), Gray_Type_Default);
    }

    /**
     * 图像像素填充 byte[][]
     *
     * @param image     BufferedImage图像对象
     * @param imgArrays 二维像素
     */
    public static void setBytes(BufferedImage image, int[][] imgArrays) {
        for (int i = 0; i < image.getHeight(); i++)
            for (int j = 0; j < image.getWidth(); j++)
                image.setRGB(j, i, (byte) imgArrays[i][j]);
    }

    /**
     * 图像像素填充 int[][]
     *
     * @param image     BufferedImage图像对象
     * @param imgArrays 二维像素
     */
    public static void setInts(BufferedImage image, int[][] imgArrays) {
        for (int i = 0; i < image.getHeight(); i++)
            for (int j = 0; j < image.getWidth(); j++)
                image.setRGB(j, i, imgArrays[i][j]);
    }

    /**
     * 图像像素填充 将 byte[][] 变为 int[][] 进行填充
     *
     * @param image     BufferedImage图像对象
     * @param imgArrays 二维像素
     */
    public static void setIntsForGray(BufferedImage image, int[][] imgArrays) {
        for (int i = 0; i < image.getHeight(); i++)
            for (int j = 0; j < image.getWidth(); j++)
                image.setRGB(j, i, imgArrays[i][j] + (imgArrays[i][j] << 8) + (imgArrays[i][j] << 16));
    }
}

2、FourierUtils.java。

package com.zxj.reptile.utils.image;

import com.zxj.reptile.utils.number.Complex;
import com.zxj.reptile.utils.number.NumberUtils;

public class FourierUtils {

    /**
     * 一维FFT 和 一维IFFT 处理过程
     *
     * @param complexArray      一维复数数组
     * @param eulerComplexArray 欧拉数组
     */
    private static Complex[] fftProgress(Complex[] complexArray, Complex[] eulerComplexArray) {
        int length = complexArray.length;
        if (length == 2) {
            //F(0)=f(0)+f(1),F(1)=f(0)-f(1)
            return new Complex[]{
                    complexArray[0].add(complexArray[1]),
                    complexArray[0].sub(complexArray[1]),};
        } else if (length == 1) {
            return complexArray;
        }
        int middle = length / 2;
        //
        Complex[] a = new Complex[middle];//a(x)=f(2x)
        Complex[] b = new Complex[middle];//b(x)=f(2x+1)
        for (int i = 0; i < middle; i++) {
            a[i] = complexArray[2 * i];
            b[i] = complexArray[2 * i + 1];
        }
        //
        Complex[] complexesA = fftProgress(a, eulerComplexArray);//计算G(k)
        Complex[] complexesB = fftProgress(b, eulerComplexArray);//计算P(k)
        Complex[] resultArray = new Complex[length];//F(k)
        int multiple = eulerComplexArray.length / middle;
        for (int i = 0; i < middle; i++) {
            //e^(2Pi*k/N)
            Complex complex = eulerComplexArray[multiple * i].mul(complexesB[i]);
            //F(k)=G(k)+(e^(2Pi*k/N))*P(k)
            resultArray[i] = complexesA[i].add(complex);
            //F(k+(N/2))=G(k)+(e^(2Pi*(k+(N/2))/N))*P(k+(N/2))
            resultArray[i + middle] = complexesA[i].sub(complex);
        }
        return resultArray;
    }

    /**
     * 二维FFT
     *
     * @param arrays 二维数组
     */
    public static Complex[][] getFft(int[][] arrays) {
        //实际的行列
        int row = arrays.length;
        int column = arrays[0].length;
        //调节过的长度
        int variableLength = (int) NumberUtils.getVariablePow(row > column ? row : column, 2);
        Complex[][] variableArray = new Complex[variableLength][variableLength];
        for (int i = 0; i < variableLength; i++)
            for (int j = 0; j < variableLength; j++)
                variableArray[i][j] = (i < row && j < column) ? new Complex(arrays[i][j]) : new Complex();
        return fftProgress(variableArray, getEulerComplex(variableLength, -1));
    }

    /**
     * 二维IFFT
     *
     * @param complexArrays 二维复数数组
     */
    public static int[][] getInverseFft(Complex[][] complexArrays, int realRow, int realColumn) {
        int length = complexArrays.length;
        complexArrays = fftProgress(complexArrays, getEulerComplex(length, 1));
        int[][] arrays = new int[realRow][realColumn];
        for (int i = 0; i < realRow; i++)
            for (int j = 0; j < realColumn; j++)
                arrays[i][j] = (int) Math.round(complexArrays[i][j].getReal() / (length * length));
        return arrays;
    }

    /**
     * 二维FFT 和 二维IFFT 处理过程
     *
     * @param complexArrays     二维复数数组
     * @param eulerComplexArray 欧拉数组
     */
    private static Complex[][] fftProgress(Complex[][] complexArrays, Complex[] eulerComplexArray) {
        int length = complexArrays.length;
        //对每行进行一维DFT
        for (int i = 0; i < length; i++) {
            complexArrays[i] = fftProgress(complexArrays[i], eulerComplexArray);
        }
        //倒置,即行和列互换
        complexArrays = Complex.transform(complexArrays);
        length = complexArrays.length;
        //对每行进行一维DFT,实际上是对没倒置前数组的列做一维DFT
        for (int i = 0; i < length; i++) {
            complexArrays[i] = fftProgress(complexArrays[i], eulerComplexArray);
        }
        //倒置回来
        complexArrays = Complex.transform(complexArrays);
        return complexArrays;
    }

    /**
     * 关于欧拉计算的数组
     *
     * @param variableLength 数组大小
     */
    private static Complex[] getEulerComplex(int variableLength, int minus) {
        int middle = variableLength / 2;
        double flag = 2 * Math.PI / variableLength;//2Pi / N
        Complex[] eulerComplexArray = new Complex[middle];
        for (int i = 0; i < middle; i++) {
            eulerComplexArray[i] = Complex.euler(minus * flag * i);
        }
        return eulerComplexArray;
    }

    public static final int Type_Filter_High = 1;
    public static final int Type_Filter_Low = 2;

    /**
     * 获取频谱值,并中心化 |F(k)|=Math.sqrt(实数的平方 + 虚数的平方)
     *
     * @param complexArray FFT之后的 complexArray[][]
     * @param percent      过滤半径的百分比
     * @param type         高频过滤、低频过滤
     */
    public static int[][] getSpectrum(Complex[][] complexArray, int percent, int type) {
        int length = complexArray.length;
        int middle = length / 2;
        int iShift, jShift;
        int filterLength = (int) (length / 200.0 * percent);
        double centerIndex = (length - 1) / 2.0;
        //
        int[][] array = new int[length][length];
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                double real = complexArray[i][j].getReal();
                double image = complexArray[i][j].getImage();
                int a = (int) Math.sqrt(real * real + image * image);
                //将矩阵分成四块,第一象限和第三象限对调,第二象限和第四象限对调
                iShift = i < middle ? i + middle : i - middle;
                jShift = j < middle ? j + middle : j - middle;
                //
                if (filterLength > NumberUtils.getDistance(iShift, jShift, centerIndex, centerIndex)) {//圆内
                    array[iShift][jShift] = type == Type_Filter_Low ? a : 0;
                } else {//圆外
                    array[iShift][jShift] = type == Type_Filter_High ? a : 0;
                }
            }
        }
        return array;
    }

    /**
     * 傅里叶过滤
     *
     * @param spectrumArray 频谱 int[][]
     */
    public static void getFilter(Complex[][] complexArray, int[][] spectrumArray) {
        int length = spectrumArray.length;
        int middle = length / 2;
        int iShift, jShift;
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                if (spectrumArray[i][j] == 0) {
                    //将矩阵分成四块,第一象限和第三象限对调,第二象限和第四象限对调
                    iShift = i < middle ? i + middle : i - middle;
                    jShift = j < middle ? j + middle : j - middle;
                    complexArray[iShift][jShift].setImage(0);
                    complexArray[iShift][jShift].setReal(0);
                }
            }
        }
    }
}

3、NumberUtils.java。

package com.zxj.reptile.utils.number;

public class NumberUtils {
    /**
     * 返回 length = Math.sqrt( (x1-x2)^2 + (y1-y2) )
     */
    public static double getDistance(double x1, double y1, double x2, double y2) {
        double xDistance = x1 - x2;
        double yDistance = y1 - y2;
        return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
    }

    /**
     * 将byte数组转为一个十进制整数
     *
     * @param bytes 8位的字节数组   1B=8bit
     */
    public static int getTenHex(byte[] bytes) {
        int result = 0;
        for (int i = 0; i < bytes.length; i++) {
            int move = bytes.length - i - 1;
            int value = (bytes[i] & 255) << (8 * move);
            result += value;
        }
        return result;
    }

    /**
     * 指定小数精度的四舍五入
     *
     * @param value         值
     * @param decimalLength 精度值
     */
    public static double getRound(double value, int decimalLength) {
        double flag = Math.pow(10, decimalLength);
        int a = (int) Math.round(value * flag);
        return a / flag;
    }

    /**
     * 返回幂,而幂大于或者等于power
     *
     * @param power 幂
     * @param base  底数
     */
    public static double getVariablePow(int power, int base) {
        int variableIndex = 0;
        double index = NumberUtils.getIndex(power, base);
        if (index > (int) index) {
            variableIndex = (int) index + 1;
        } else {
            variableIndex = (int) index;
        }
        return Math.pow(base, variableIndex);
    }

    /**
     * 返回指数
     *
     * @param power 幂
     * @param base  底数
     * @return 返回指数
     */
    public static double getIndex(int power, int base) {
        return Math.log10(power) / Math.log10(base);
    }

    /**
     * 返回是否为整数
     *
     * @param a 数字a
     * @return 返回数字a是否为整数
     */
    public static boolean isInteger(double a) {
        return (a - (int) a == 0);
    }

    /**
     * 10进制,数的长度
     *
     * @param number 数
     */
    public static int getNumberSize(long number) {
        return getNumberSize(number, 10);
    }

    /**
     * 指定进制,数的长度
     *
     * @param number 数
     * @param radix  进制
     */
    public static int getNumberSize(long number, int radix) {
        if (number == 0) {
            return 1;
        }
        int size = 0;
        while (number > 0) {
            number /= radix;
            size++;
        }
        return size;
    }
}

4、Complex.java。

package com.zxj.reptile.utils.number;

/**
 * 复数的基本操作
 */
public class Complex {
    private double real;//实数
    private double image;//虚数

    public Complex() {
        real = 0;
        image = 0;
    }

    public Complex(double real) {
        this.real = real;
        this.image = 0;
    }

    public Complex(double real, double image) {
        this.real = real;
        this.image = image;
    }

    //加:(a+bi)+(c+di)=(a+c)+(b+d)i
    public Complex add(Complex complex) {
        double real = complex.getReal();
        double image = complex.getImage();
        double newReal = this.real + real;
        double newImage = this.image + image;
        return new Complex(newReal, newImage);
    }

    //减:(a+bi)-(c+di)=(a-c)+(b-d)i
    public Complex sub(Complex complex) {
        double real = complex.getReal();
        double image = complex.getImage();
        double newReal = this.real - real;
        double newImage = this.image - image;
        return new Complex(newReal, newImage);
    }

    //乘:(a+bi)(c+di)=(ac-bd)+(bc+ad)i
    public Complex mul(Complex complex) {
        double real = complex.getReal();
        double image = complex.getImage();
        double newReal = this.real * real - this.image * image;
        double newImage = this.image * real + this.real * image;
        return new Complex(newReal, newImage);
    }

    //乘:a(c+di)=ac+adi
    public Complex mul(double multiplier) {
        return mul(new Complex(multiplier));
    }

    //除:(a+bi)/(c+di)=(ac+bd)/(c^2+d^2) +((bc-ad)/(c^2+d^2))i
    public Complex div(Complex complex) {
        double real = complex.getReal();
        double image = complex.getImage();
        double denominator = real * real + image * image;
        double newReal = (this.real * real + this.image * image) / denominator;
        double newImage = (this.image * real - this.real * image) / denominator;
        return new Complex(newReal, newImage);
    }

    public double getReal() {
        return real;
    }

    public void setReal(double real) {
        this.real = real;
    }

    public double getImage() {
        return image;
    }

    public void setImage(double image) {
        this.image = image;
    }

    @Override
    public String toString() {
        String str = "";
        if (real != 0) {
            str += real;
        } else {
            str += "0";
        }
        if (image < 0) {
            str += image + "i";
        } else if (image > 0) {
            str += "+" + image + "i";
        }
        return str;
    }

    /**
     * 欧拉公式 e^(ix)=cosx+isinx
     *
     * @param x 相当于角度
     */
    public static Complex euler(double x) {
        double newReal = Math.cos(x);
        double newImage = Math.sin(x);
        return new Complex(newReal, newImage);
    }

    /**
     * Complex 和 Complex 比较
     *
     * @param a 复数a
     * @param b 复数b
     */
    public static boolean equals(Complex a, Complex b) {
        return NumberUtils.getRound(a.getImage(), 4) == NumberUtils.getRound(b.getImage(), 4) &&
                NumberUtils.getRound(a.getReal(), 4) == NumberUtils.getRound(b.getReal(), 4);
    }

    /**
     * Complex[] 和 Complex[] 比较
     *
     * @param a 复数数组a
     * @param b 复数数组b
     */
    public static boolean equals(Complex[] a, Complex[] b) {
        if (a.length != b.length) {
            return false;
        }
        for (int i = 0; i < a.length; i++) {
            if (!equals(a[i], b[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * Complex[][] 和 Complex[][] 比较
     *
     * @param a 二维复数数组a
     * @param b 二维复数数组b
     */
    public static boolean equals(Complex[][] a, Complex[][] b) {
        if (a.length != b.length) {
            return false;
        }
        for (int i = 0; i < a.length; i++) {
            if (!equals(a[i], b[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * double[] --> Complex[]
     *
     * @param array double数组
     */
    public static Complex[] getComplexArray(int[] array) {
        Complex[] complexArray = new Complex[array.length];
        for (int i = 0; i < array.length; i++) {
            complexArray[i] = new Complex(array[i]);
        }
        return complexArray;
    }

    /**
     * double[][] --> Complex[][]
     *
     * @param array double二维数组
     */
    public static Complex[][] getComplexArray(int[][] array) {
        int length = array.length;
        Complex[][] complexArray = new Complex[length][];
        for (int i = 0; i < length; i++) {
            complexArray[i] = getComplexArray(array[i]);
        }
        return complexArray;
    }

    /**
     * Complex.real[] --> int[]
     *
     * @param complexArray 复数数组
     */
    public static int[] getRealArray(Complex[] complexArray) {
        int length = complexArray.length;
        int[] array = new int[length];
        for (int i = 0; i < length; i++) {
            array[i] = (int) Math.round(complexArray[i].getReal());
        }
        return array;
    }

    /**
     * Complex.real[][] --> int[][]
     *
     * @param complexArray 二维复数数
     */
    public static int[][] getRealArray(Complex[][] complexArray) {
        int length = complexArray.length;
        int[][] array = new int[length][];
        for (int i = 0; i < length; i++) {
            array[i] = getRealArray(complexArray[i]);
        }
        return array;
    }

    /**
     * Complex.image[] --> int[]
     *
     * @param complexArray 复数数组
     */
    public static int[] getImageArray(Complex[] complexArray) {
        int length = complexArray.length;
        int[] array = new int[length];
        for (int i = 0; i < length; i++) {
            array[i] = (int) Math.round(complexArray[i].getImage());
        }
        return array;
    }

    /**
     * Complex.image[][] --> int[][]
     *
     * @param complexArray 二维复数数
     */
    public static int[][] getImageArray(Complex[][] complexArray) {
        int length = complexArray.length;
        int[][] array = new int[length][];
        for (int i = 0; i < length; i++) {
            array[i] = getImageArray(complexArray[i]);
        }
        return array;
    }

    /**
     * 二维复数数组转置
     *
     * @param a 二维复数数组
     */
    public static Complex[][] transform(Complex[][] a) {
        int row = a.length;
        int column = a[0].length;
        Complex[][] result = new Complex[column][row];
        for (int i = 0; i < column; i++)
            for (int j = 0; j < row; j++)
                result[i][j] = a[j][i];
        return result;
    }

    public static void print(Complex[] complexArray) {
        for (Complex complex : complexArray)
            System.out.print(complex + "  ");
        System.out.println();
    }

    public static void print(Complex[][] complexArray) {
        for (Complex[] complexes : complexArray)
            print(complexes);
    }
}




原文地址:访问原文地址
快照地址: 访问文章快照