python编程实现fft数据直角坐标和极坐标的相互转换

直角坐标和极坐标的相互转换

  • 主要功能
  • 一 直角坐标转极坐标
    • 程序
    • 查看帮助文档
    • 运行
  • 二 极坐标转直角坐标
    • 程序
    • 查看帮助文档
    • 运行
  • 附件

主要功能

主要实现了直角坐标和极坐标的相互转换,直角坐标的数据来源为我的博客python编程实现分帧数据的fft变换对分帧语音数据经fft变换之后的数据,数据为复数。将fft数据从直角坐标转为极坐标,同时也可以将极坐标数据转换为原始的直角坐标数据。

说明:本文程序使用pycharm编辑运行,均采用命令行方式运行,输入输出数据均保存在txt文件中

一 直角坐标转极坐标

直角坐标转为极坐标,就是求幅度和相位,幅度通过复数的实部和虚部的平方和,再开方得到。相位为复数的虚部除以实部再求反正切,求出来的为幅度,需要转为角度的话,就乘以180/pi

极坐标:

幅度:
A m p l i t u d e = r e a l 2 + i m a g 2 Amplitude=\sqrt{real^{2}+imag^{2}} Amplitude=real2+imag2
相位:
θ = arctan ⁡ i m a g r e a l \theta =\arctan \frac{imag}{real} θ=arctanrealimag

程序

程序中设计了极坐标幅值和相位之间以"@"间隔和以空格间隔,需要手动调整。如下:

#Amplitude_and_angle = str(Amplitude) + '@' + str(angle) + '\n'  #将幅度和相位数据中间加空格和@符号
 Amplitude_and_angle = str(Amplitude) + ' ' + str(angle) + '\n'  # 将幅度和相位数据中间加空格

主程序:

#对经fft变换的复数数据转换为极坐标形式
import numpy as np
import getopt
import sys

def main(argv):
    try:
         opts, args = getopt.getopt(sys.argv[1:], "-i:-o:-h", ["input=", "output=","help"])
    except getopt.GetoptError:
        print('将经过fft变换的音频数据,转换到极坐标')
        print('python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar.txt')
        sys.exit()

    # 处理 返回值options是以元组为元素的列表。
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print("将经过fft变换的音频数据,转换到极坐标")
            print('输入格式为:')
            print('python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar.txt')
            print('此时幅度和相位以"@"间隔')
            print('python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar1.txt')
            print('此时幅度和相位以空格间隔')
            sys.exit()
        elif opt in ("-i", "--input"):
            input = arg
        elif opt in ("-o", "--output"):
            output = arg

            fft_data = np.loadtxt(input, dtype=np.complex)  #加载数据文件,读入数据
            fft_data_len = len(fft_data)  # 输入数据长度
            file = open(output, 'w+')  #打开输出文件

            for i in range(fft_data_len):
                #复数实部和虚部的平方和,再开方就是极坐标的幅度
                #Amplitude = np.abs(fft_data)  # 调包求模,即幅度
                #angle = np.rad2deg(np.angle(fft_data))  # 调包求相位,np.angle是求弧度,np.rad2deg将弧度转化为角度
                data_real = np.real(fft_data[i])  #取复数的实部
                data_imag = np.imag(fft_data[i])  #取复数的虚部
                Amplitude = np.sqrt(data_real ** 2 + data_imag ** 2) #求幅度,即模
                angle = np.arctan(data_imag / data_real )* (180 / np.pi)  # 求相位,此时为角度
                #Amplitude_and_angle = str(Amplitude) + '@' + str(angle) + '\n'  #将幅度和相位数据中间加空格和@符号
                Amplitude_and_angle = str(Amplitude) + ' ' + str(angle) + '\n'  # 将幅度和相位数据中间加空格
                file.write(Amplitude_and_angle)  #将每行数据写入文件
            file.close()


if __name__ == "__main__":
    main(sys.argv)  #调用函数


#python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar.txt
#python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar1.txt

查看帮助文档

python ffttxtpolar.py -h

结果:

将经过fft变换的音频数据,转换到极坐标
输入格式为:
python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar1.txt
此时幅度和相位以"@"间隔
python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar.txt
此时幅度和相位以空格间隔

运行

极坐标幅度和相位以"@"间隔

运行:

python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar1.txt

运行结果:

python编程实现fft数据直角坐标和极坐标的相互转换_第1张图片

极坐标幅度和相位以空格间隔

运行:

python ffttxtpolar.py -i fft_test1.txt -o fft_test1_polar1.txt

运行结果:

python编程实现fft数据直角坐标和极坐标的相互转换_第2张图片

原始fft数据:

python编程实现fft数据直角坐标和极坐标的相互转换_第3张图片

通过上面所述公式验算,结果正确。

二 极坐标转直角坐标

极坐标转直角坐标,复数的实部就是用极坐标的幅度乘以cos(相位),复数的虚部就是用极坐标的幅度乘以sin(相位)。

复数的实部
c o m p l e x r e a l = ρ cos ⁡ θ complexreal=\rho \cos \theta complexreal=ρcosθ
复数的虚部
c o m p l e x i m a g = ρ sin ⁡ θ compleximag=\rho \sin \theta compleximag=ρsinθ

说明:极坐标转直角坐标的数据格式为幅度和相位之间以空格隔开,方便读取数据,数据格式如下:

python编程实现fft数据直角坐标和极坐标的相互转换_第4张图片

程序

#将极坐标数据,转换到直角坐标,还原为fft原始数据
import numpy as np
import getopt
import sys

def main(argv):
    try:
         opts, args = getopt.getopt(sys.argv[1:], "-i:-o:-h", ["input=", "output=","help"])#sys.argv[1:]为取命令行参数,从第二个参数开始取,因为第一个参数为程序名称
    except getopt.GetoptError:
        print('将极坐标数据,转换到直角坐标,还原为fft原始数据')
        print('python polartxtfft.py -i fft_test1_polar.txt -o polar_test1_fft.txt')
        sys.exit()

    # 处理 返回值options是以元组为元素的列表。
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print("将极坐标数据,转换到直角坐标,还原为fft原始数据")
            print('输入格式为:')
            print('python polartxtfft.py -i fft_test1_polar.txt -o polar_test1_fft.txt')
            sys.exit()
        elif opt in ("-i", "--input"):
            input = arg
        elif opt in ("-o", "--output"):
            output = arg

            polar_data = np.loadtxt(input, dtype=np.float)  #加载数据文件,读入数据,数据类型为float,不能为short
            polar_data_len = len(polar_data)  # 输入数据长度
            #m = (polar_data.T).ndim  #判断数据是一维还是多维(对数据取转置,再判断维度,即判断输入数据列数)
            file = open(output, 'w+')  #打开输出文件

            # 循环读取每行数据,将极坐标转为直角坐标,还原为fft原始数据
            for i in range(polar_data_len):
                Amplitude = polar_data[i,0]  #取极坐标的幅值,即模
                angle = polar_data[i,1]  #取极坐标的角度,即相位
                #print(Amplitude, angle)
                angle = angle*(np.pi/180)  #角度转弧度(因为下面cos函数计算时,是按照弧度计算的)
                data_real = Amplitude*np.cos(angle)  #计算实部
                data_imag = Amplitude*np.sin(angle)  #计算虚部
                #如下判断语句主要用于判断复数的虚部是否大于零,从而判断虚部前是否需要加"+"号,因为负数前面不需要加"+"号
                if(data_imag>0):   #复数的虚部大于零,则虚部前加"+"号
                    complex_data = str(data_real) + '+' + str(data_imag) + 'j' + '\n'  # 将幅度和相位数据中间加空格和@符号
                elif(data_imag<0):  #复数的虚部小于零,则虚部前不加"+"号
                    complex_data= str(data_real) + str(data_imag) + 'j' + '\n'  #将幅度和相位数据中间加空格和@符号
                else:    #复数的虚部等于零,取绝对值后再在虚部前加"+"号
                    complex_data = str(data_real)  + '+' + str(abs(data_imag)) + 'j' + '\n'  # 将幅度和相位数据中间加空格和@符号
                file.write(complex_data)  #将每行数据写入文件
            file.close()


if __name__ == "__main__":
    main(sys.argv)  #调用函数


#python polartxtfft.py -i fft_test1_polar.txt -o polar_test1_fft.txt

查看帮助文档

将极坐标数据,转换到直角坐标,还原为fft原始数据
输入格式为:
python polartxtfft.py -i fft_test1_polar.txt -o polar_test1_fft.txt

运行

输入数据文件为极坐标数据,输出数据文件为还原的直角坐标数据。

python polartxtfft.py -i fft_test1_polar.txt -o polar_test1_fft.txt

结果:

python编程实现fft数据直角坐标和极坐标的相互转换_第5张图片

原始fft数据:

python编程实现fft数据直角坐标和极坐标的相互转换_第6张图片

通过对比还原的fft数据,和原始fft数据,发现只有小数部分,后面最小位数处有误差,这是因为计算精度问题,但可以看出结果正确。

此时,直角坐标转极坐标和极坐标转直角坐标已全部实现,且结果正确。

附件

本文所有程序,文件下载:
链接:https://pan.baidu.com/s/1H09ZSMPHjWsEj8_tOn37pg
提取码:ma4r

你可能感兴趣的:(python编程)