赞
踩
目录
该项目由三部分构成。第一部分将实现傅里叶变换二维曲线的绘制,通过输入自定义的信号来进行傅里叶变换,并可以选择增加受零均值随机噪声,最终输出混合信号的傅里叶分析。
第二部分将产生一随机矩阵,对该矩阵进行数据统计(求最大值、最小值、求和、求标准方差)
第三部分将在界面上实现通过GUI控件对图形进行修饰,通过下拉框实现对图形形式的修改,通过按钮对曲线在指定的坐标添加文本标注,并在轴中增加右键快捷菜单功能
界面总体分为两大部分,左边部分将实现求任意输入信号的傅里叶变换,并对自定义坐标进行标注,右半部分实现随机矩阵的生成与数据统计。
共使用了2个轴控件,4个可编辑文本框,20个静态文本框,3个按钮,两个弹出式菜单
有丰富的互动功能:在轴中设置右键快捷键,设置弹出式菜单进行颜色线型的变换,通过按钮清除左图,通过文本框输入时间t,输入函数x,自定义标注坐标等。
左边在使用时需要输入时间t的范围与输入函数x,可以输入t0来进行坐标的标注,可以通过点击单选按钮决定是否加随机噪声,右边在使用时只需点击“产生随机矩阵”即可。
输出示例:
加入随机噪声前:
加入随机噪声后:
目的是实现对输入函数的傅里叶变换,于是先用可编辑文本框接收时间t的范围与输入函数x,设置两个轴用来显示变换前与变换后函数图像,设置一个按钮用来控制图像的显示,设置单项选择来决定是否加入随机噪声,设置两个弹出式菜单来改变函数的线型,最后设置两个文本框来接收自定义的标注坐标与标注。
具体实现:
按钮部分:只有点击按钮才会发生一切的图像生成与变换
运行逻辑是先判断两个可编辑文本框中是否都有值,然后判断单选按钮的Value,判断出Value为0且文本框都有值后,从可编辑文本框edit2中接收时间t的范围,从edit1中接收输入函数x,都用eval函数使之运行,然后以t为x轴,以x为y轴在axes1上画图,这是变换前的,
接下来进行傅里叶变换,用F=fft(x)函数求得傅里叶变换,然后求频谱密度,用Fs求得时间间隔的倒数,用frequencies =0:Fs/length(F):Fs-Fs/length(F);求得频谱密度,以频谱密度为x轴,以F为y轴在axes2中画傅里叶变换的图像。
若Value为1则定义一个y用于接收加了随机噪声的x函数,然后将y作为绘图的变量。
接着判断edit3与edit4中是否有值,有值则将edit3赋给t,此时t即为要标注的点,将t代入函数x得到对应的值,这样标注的坐标即可求得,然后接收edit4中标注的内容,用text函数将其在两个轴中标注出来并设置标注的样式,接下来我想要把标注坐标对应的点特别表示出来,于是用了plot函数将这个坐标用×标志表示出来,然后又觉得标志与标注间离得太近,于是加了一个\leftarrow来生成左箭头
- axes(handles.axes1);
-
- hold on;
-
- if ~(isempty(get(handles.edit1))||isempty(get(handles.edit2)))
-
- eval(get(handles.edit2,'String'));
-
- eval(get(handles.edit1,'String'));
-
- plot(t,x);
-
- axes(handles.axes2);
-
- hold on;
-
- F=fft(x);
-
- Fs = 1 / (t(2) - t(1));
-
- frequencies = 0:Fs/length(F):Fs-Fs/length(F);
-
- plot(frequencies,abs(F));
-
- end
-
- if ~(isempty(get(handles.edit3))||isempty(get(handles.edit4)))
-
- axes(handles.axes1);
-
- hold on;
-
- t=str2num(get(handles.edit3,'String'));
-
- eval(get(handles.edit1,'String'));
-
- p=strcat('\leftarrow ', get(handles.edit4,'String'))
-
- h=text(t,x,p,'color','red');
-
- plot(t,x,'rx');
-
- axes(handles.axes2);
-
- hold on;
-
- t=str2num(get(handles.edit3,'String'));
-
- eval(get(handles.edit1,'String'));
-
- F=fft(x);
-
- f=2*pi*t;
-
- plot(f,abs(F),'r*');
-
- p=strcat('\leftarrow ', get(handles.edit4,'String'))
-
- text(f,abs(F),p,'color','red');
-
- end
思路很简单,就是根据value的不同取值来set线的属性。
颜色部分
- b=get(handles.popupmenu1,'Value');
-
- line1 = findobj(handles.axes1, 'Type', 'line');
-
- line2 = findobj(handles.axes2, 'Type', 'line');
-
- switch b
-
- case 2
-
- set(line1, 'Color', 'r');
-
- set(line2, 'Color', 'r');
-
- case 3
-
- set(line1, 'Color', 'm');
-
- set(line2, 'Color', 'm');
-
- case 4
-
- set(line1, 'Color', 'g');
-
- set(line2, 'Color', 'g');
-
- case 5
-
- set(line1, 'Color', 'c');
-
- set(line2, 'Color', 'c');
-
- case 6
-
- set(line1, 'Color', 'b');
-
- set(line2, 'Color', 'b');
-
- end
-
- 线型部分
-
- c=get(handles.popupmenu2,'Value');
-
- sty1 = findobj(handles.axes1, 'Type', 'line');
-
- sty2 = findobj(handles.axes2, 'Type', 'line');
-
- switch c
-
- case 2
-
- set(sty1, 'LineStyle', '-');
-
- set(sty2, 'LineStyle', '-');
-
- case 3
-
- set(sty1, 'LineStyle', ':');
-
- set(sty2, 'LineStyle', ':');
-
- case 4
-
- set(sty1, 'LineStyle', '-.');
-
- set(sty2, 'LineStyle', '-.');
-
- case 5
-
- set(sty1, 'LineStyle', '--');
-
- set(sty2, 'LineStyle', '--');
-
- end
-
- 单选按钮部分:
- 思路首先是清除轴上的图形,然后设置一个函数y用来接收函数x与随机噪声的混合,然后在第一个轴中打出来,然后对y进行傅里叶变换,傅里叶变换的过程前文已有,不再赘述。然后就是标注部分,变换前的标注与之前操作一样,变换后的函数标注需要先求出t0所对应的索引,这里用k表示,然后用F(k)来表示t0所对应的频域谱中的y轴坐标。
-
- 回调函数:
-
- axes(handles.axes1);
-
- cla;
-
- axes(handles.axes2);
-
- cla;
-
- eval(get(handles.edit2,'String'));
-
- axes(handles.axes1);
-
- if get(handles.radiobutton1,'Value')
-
- eval(get(handles.edit1,'String'));
-
- y=x+randn(size(t));
-
- plot(t,y);
-
- axes(handles.axes2);
-
- F=fft(y);
-
- Fs = 1 / (t(2) - t(1));
-
- frequencies = 0:Fs/length(F):Fs-Fs/length(F);
-
- plot(frequencies,abs(F));
-
- if ~(isempty(get(handles.edit3))||isempty(get(handles.edit4)))
-
- axes(handles.axes1);
-
- hold on;
-
- t=str2num(get(handles.edit3,'String'));
-
- p=strcat('\leftarrow ', get(handles.edit4,'String'))
-
- eval(get(handles.edit1,'String'));
-
- y=x+randn(size(t));
-
- text(t,y,p,'color','red');
-
- plot(t,y,'rx');
-
- axes(handles.axes2);
-
- df=Fs/16;
-
- hold on;
-
- f=2*pi*t;
-
- k = round(f / df) + 1;
-
- plot(f,F(k),'r*');
-
- p=strcat('\leftarrow ', get(handles.edit4,'String'))
-
- text(f,F(k),p,'color','red');
-
- end
-
- else
-
- axes(handles.axes1);
-
- cla;
-
- axes(handles.axes2);
-
- cla;
-
- axes(handles.axes1);
-
- eval(get(handles.edit1,'String'));
-
- plot(t,x);
-
- axes(handles.axes2);
-
- F=fft(x);
-
- Fs = 1 / (t(2) - t(1));
-
- frequencies = 0:Fs/length(F):Fs-Fs/length(F);
-
- plot(frequencies,abs(F));
-
- end
没什么可说的,就是定义一个按钮,按下按钮产生随机矩阵,在text9中显示出来,并且进行数学统计,在下面几个文本框中显示出来。
回调函数:
A = round(10*randn(4));
B=mean(A(:));
C=var(A(:));
D=max(A(:));
E=min(A(:));
set(handles.text9, 'String', num2str(A));
set(handles.text17, 'String', num2str(B));
set(handles.text18, 'String', num2str(C));
set(handles.text15, 'String', num2str(D));
set(handles.text16, 'String', num2str(E));
1)在设计这一部分的时候,我首先的思路是在轴中的回调函数中调用可编辑文本框中的内容来完成绘图。但是运行出错,错误原因应该是此时文本框中无内容,而轴会自动调用回调函数导致出错。而我的目的是使点击按钮后轴再调用文本框中的内容,所以想到在轴中去获取此时按钮的value值,为1则执行自己的回调函数,但使用button_value = get(handles.pushbutton1, 'Value');时程序报错,显示‘尝试引用非结构体数组的字段’。于是最终采用在按钮的回调函数中直接axes(handles.axes1)后plot的方法实现按下按钮后在axes中画出图形。
2)在按钮的回调函数中完成傅里叶变换的函数后,我添加了一个“加入受零均值随机噪声”的单选按钮,目的是按下后加入随机噪声。一开始我直接在单选按钮中写了加入随机噪声的回调函数,但是没有实现“按一次执行操作,按两次返回原来的图”的功能,于是我在回调函数中加了一个if语句,根据它此时的value值来执行操作。但是在具体实现时发现再次点击会出现之前的与现在的两个图形相叠加,于是在单选按钮中加了cla函数,用于清除之前的图形。
3)困扰我最久的问题是标注的问题,一开始直接用text(x,y,p,’Color’,’r’)发现不行,查了查matlab官方文档发现是text(x,y,p,’Color’,’red’),然后又发现这只能改变标注的形式,不能改变标记点的样式,于是想到用plot在标记点处再打一个点,但是在获取标记的坐标时又遇到问题,在进行傅里叶变换后t0得进行变换才能求出其对应的w0,然后如何求傅里叶变换后的y坐标呢?又找了很久,发现得先确定采样频率Fs与信号长度N,然后通过df=Fs/N来求得频率分辨率,然后在频率向量中找到对应的索引位置k,然后代入傅里叶变换后的函数求得此时的y坐标。
4)然后是单选按钮的问题,一开始我认为单选按钮按下后执行操作,然后再次按下会返回原来的图,但后来发现不能返回,于是加了一个if来判断value的值,为0则执行原来的绘图操作。然后还要获取给定坐标t0的值,再进行标注,在变换后的加了噪声的函数中寻找y轴坐标又费了很大力气,最后通过求索引的方式确定了这一点对应的y轴坐标。
矩阵部分没有遇到什么问题。
1)在这一部分,我设置了两个弹出式菜单用于改变曲线的样式,一开始想通过改变axes中的某一属性来改变曲线的样式,但是发现axes中并没有关于曲线的颜色等属性,于是使用findobj函数来获取曲线的句柄,设置一个变量来存储弹出式菜单的value值,用switch case语句来进行操作。曲线线型的改变同理可得。
2)接下来要完成的是“按下按钮,对给的坐标进行标注”,一开始想的是弹出一个可编辑文本框,然后输入坐标与标注,点确定即可,但是后续实现的时候发现实现难度太大,于是改用静态的可编辑文本框,在其中输入坐标与标注。但是在输入坐标时碰见一个问题,就是如何输入坐标的问题,于是采用输入时加x=,y=来解决这个问题。在标注的时候也遇到很多问题,比如一开始不知道text函数怎么对标记点进行样式的修改,之后学会了先使用 text 函数添加了一个带有指定属性的标注点,然后用plot把这个点打出来,但是发现一个图只能plot一次,于是加上hold on,就可以在一张图上多次plot了。然后用text函数打印出标注即完成任务。
在本学期的学习中,我学会了如何通过matlab进行各种运算,如向量的变换与矩阵的各种运算,元素的提取与替换,求统计量。并且学会了通过matlab进行各种绘图操作,包括三维,二维的各种绘图操作。学会了脚本文件与函数文件的定义与调用,包括程序的控制结构与调试。学会了如何进行数据处理,如对数据进行插值,进行傅里叶变换,进行多项式的计算与求导。最后学会了如何通过matlab图形用户界面开发图形程序,学会了如何使用控件与回调函数来设计自己想要的图形程序。
学习这门课的心得体会:
我认为要学好这门课一定要多多查阅matlab官方文档和利用网络资源,在课堂教学中,一次课就是三个小时,有时候听了一个小时就听不下去了,而且每个人的节奏都不一样所以老师讲的很慢很细致,但是对于我来说课就很无聊,通常是听了一会,然后在下面玩一会,然后临做题了看一看前面的PPT就能把题写出来。所以我有一半时间都是在网上通过看博客,看官方文档的方式学习的,很多问题都是通过查阅官方文档来解决的,我认为matlab函数不需要去背输入的参数,只需要记住这个函数是什么功能即可,比如text函数有很多重载,很多参数类型,但只需要记住这个函数有标注的功能即可,使用时只需传入x,y,String即可,到用到更多参数时可以通过查询官方文档来使用
在学这门课的时候,我认为matlab是一款非常好的软件,它入门简单,上手非常容易。语法与数学表达式相似,并且有丰富的内置函数和工具箱,可以快速实现各种数学和科学计算。并且在各个方面有广泛的应用,在工程、科学、金融等领域都具有广泛的应用。通过 MATLAB,我可以进行数据分析、图像处理、信号处理、模拟仿真等任务,并且matlab提供了丰富的工具箱和函数库,方便我们进行各种领域的研究和开发。而且交互性非常强,它可以直接在命令窗口中输入和执行代码,并立即看到结果。这种交互性使得调试和测试代码变得非常方便,同时也能够快速验证想法和算法的正确性。可视化功能强大,MATLAB 提供了丰富的绘图和可视化功能,可以轻松生成各种类型的图形和图表。这对于数据分析、结果展示和报告撰写非常有帮助,能够直观地展示数据和结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。