+ s% n) T Y! g1.2.3 数字图像处理的内容 : S' ~0 r* ^: f0 u1 f H 4 r. g$ u# W. [. l9 E: m( \9 j要有效解决众多的图像处理应用问题,必须研究出专门的图像处理方法,大致上可以将这些问题及其数字图像处理方式归纳为以下几类。8 `; N I8 u. m, l3 k5 z; ]' h! R
; H$ L9 r3 _$ L/ r5 y S' \1. 图像获取、表示和表现(Image Acquisition, Representation and Presentation) 4 e, g+ ~7 g1 ?5 [4 u6 H9 Z! v4 o$ H$ m) D) ~# ~9 q! L) B
该过程主要是把模拟图像信号转化为计算机所能接受的数字形式,以及把数字图像显示和表现出来。这一过程主要包括摄取图像、光电转换及数字化等几个步骤。 3 Q% L2 ~$ }4 y" W% G+ ^7 }2 O9 w
2. 图像增强(Image Enhancement) 5 m4 C( ?* R% R. d" Q! H7 m9 X8 T% D v% N& Y; E0 @" G, B- i* [
图像增强是用来强调图像的某些特征,以便于作进一步的分析或显示。当无法得知图像退化有关的定量信息时,可以使用图像增强技术较为主观地改善图像的质量。所以,图像增强技术是用于改善图像视感质量所采取的一种重要手段。它所完成的工作包括去除图像噪声,增强图像对比度等。例如,对比度的增强是用来使对比度低的图像更容易显现其特征,而低对比度的可能原因包括光线不足、图像感应器的动态范围不够以及在图像摄取时光圈设定错误等。图像增强的过程本身并没有增加原始资料所包含的信息,仅仅是把图像某些部分的特征更加强调罢了。图像增强的算法通常是交互式的,而且与所考虑的应用有着密切的联系。; Q* j J+ e, b# w, h! p4 c) _
0 O0 V; x6 E L% D6 p
3. 图像恢复(Image Restoration); S0 I4 M r0 ~/ r' p3 j; ^; \% A
: ?& h9 _# `' J/ T( ` }( m1 Z
图像恢复是指在图像退化(图像品质下降)的原因已知时,对图像进行校正,重新获得原始图像的过程。使图像降质的因素有很多,包括感应器或拍摄环境的干扰,感应器的非线性几何失真,没有对焦精确所造成的模糊,摄象机与物体之间相对运动所造成的模糊等。图像恢复最关键的是对每一种退化都需要建立一个合理的模型。退化模型和特定数据一起描述了图像的退化,因此恢复技术是基于模型和数据的图像恢复,其目的是试图将受污染或降质的图像带回到原本不受污染的状况下所应得的干净图像,产生一个等价于理想成像系统获得的图像。虽然图像恢复与图像增强都会造成视觉上较佳的感受,但后者更关心的是图像特征增强或抽取,而不是去除退化或污染。. A/ f1 @; j. |7 I
8 F6 H. v7 |3 W8 e8 d( S4. 图像重建(Image Reconstruction)# a' u. S1 @# }: ^* \5 @( E0 x
: F' b& P, ]8 H" t6 t9 x* M& R 图像重建的工作是由几个一维的图像投影来重建出更高维的物体图像。它与图像增强、图像恢复等不同。图像增强和图像恢复的输入都是图像,处理后输出的结果也是图像。而图像重建则是指从数据到图像的处理,即输入的是某种数据,经过处理后得到的结果是图像。一个图像的取得是以平行的X光或者其他的放射穿透光束照射物体,并在物体的背面接收此投影,接着在同一平面上改变光束照射的角度以获得不同的投影,再以某些重建算法将这些投影组合成物体的一个横剖面图像。这种技术主要用于医学图像、雷达图像处理、天文学星象观测、地质研究及无损压缩等。 7 |: c# L3 T* i) s0 F ) W. R# F) _ m% M% l5 k- f# a9 p. F5. 图像压缩(Image Compression) ~0 [' F" P2 E0 a) u9 n: G+ ^$ w+ t5 G1 Q
图像压缩的目的是降低代表数字图像所需要的数据量,这样做的好处是可以减少图像传输时间以及存储空间。编码是实现图像压缩的重要手段。图像压缩编码主要是利用图像信号的统计特性以及人类视觉的生理学和心理学特性,对图像信号进行高效编码,即研究数据压缩技术,其目的是在保证图像质量的前提下压缩数据,以解决图像数据量大的矛盾。一般来说,图像编码的目的有三个:①减少数据存储量。②降低数据率以减少传输带宽。③压缩数据量,便于特征提取,为后续识别作准备。 9 \3 T' G( ]- C" ^ V- E4 T0 D9 E& P. l3 F4 X
从编码技术的发展来看,Kunt提出了第一代、第二代的编码概念。第一代编码是以去除冗余为基础的编码方法,如PCM、DPCM、ΔM、DCT、DFT、W-H变换编码以及以此为基础的混合编码法。第二代编码法多为20世纪80年代以后提出的,如Fractal编码法、金字塔编码法、小波变换编码法、模型基编码法、基于神经网络的编码法等等。这些编码方法有如下特点:①充分考虑人的视觉特性。②恰当地考虑对图像信号的分解与表述。③采用图像的合成与识别方案压缩数据。+ p4 [: F" c! n- l" F# `
" S' J v) ^: o* p- j! J& x; z6. 图像分割(Image Segmentation) 6 [ A8 _. d3 w% [% r9 b ( S! T* R7 t' C# _- W5 |' p 图像分割就是把图像分成区域的过程。这是从处理到分析的转变关键,也是图像自动分析的第一步。图像中通常包含多个对象,图像处理为达到识别和理解的目的,几乎都必须按照一定的规则将图像分割成区域,每个区域代表被成像的一个部分。图像自动分割是图像处理中最困难的问题之一。人类视觉系统能将所观察的复杂景物中的对象分开,并识别出每个物体,但对于计算机来说却是个难题。目前,大部分图像的自动分割还需要人工提供必须的信息来帮助识别,只有一部分领域开始使用。例如印刷字符自动识别(OCR),指纹识别等。; L* X2 G$ i/ y
0 a' {. a/ O! w6 ^1 i
7. 图像分析(Image Analysis) ) |7 p% J, }5 h, O' J* B0 r1 I% w% [
图像分析是试图从图像中分割、提取并描述某些特征,从而有利于计算机对图像的识别和理解,以产生有用的信息。图像处理应用的目标几乎都涉及到图像分析。要做图像分析,必须使计算机具有某种程度的智能。这些智能的特征包括:①能从含有许多不相干细节的背景中找到所需的信息。②能从范例中学习并将所学知识应用推广到其他状况中。③能从不完整的资料中推断出完整的信息。 + Y# K( R' s& J- M & H8 |1 B. r* c# h4 S( I1.3 图像工程$ ^* x, p0 w8 W# ~% {! _
- s' |- W; @. x9 \1.3.1 图像工程的内涵 # Y* ^7 Y2 f' j7 X , z4 [+ z! p) Q8 M图像技术在广义上来说是各种与图像有关的技术的总称。目前人们主要研究的是数字图像,主要应用的是计算机图像技术。这包括利用计算机和其它电子设备进行和完成的一系列工作,以及为完成各种功能而进行的硬件设计及制作等方面的技术。计算机图像技术的历史可以追溯到1946年世界上第一台电子计算机的诞生,但在20世纪50年代计算机主要还是用于数值计算。到20世纪60年代,第三代计算机的研制成功,以及快速傅立叶变换算法的发现和应用,使得对图像的某些计算得以实际实现。20世纪70年代,图像技术有了长足进步,而且第一本重要的图像处理专著(Rosenfeld 1976)也得以出版。进入20世纪80年代,各种硬件的发展使得人们开始处理3-D图像。3 _5 i$ w% }! k' \6 J
$ c% ]. |3 g# B( G; L3 M
由于图像技术得到了极大的重视和长足的发展,人们需要对它们进行综合研究和集成应用,由此出现了图像工程。图像工程的概念在1982年首先提出,当时主要包括有关图像的理论技术,对图像数据的分析管理以及各种应用。图像工程的内容非常丰富,根据抽象程度和研究方法等的不同,可分为图像处理、图像分析和图像理解三个层次。换句话说,图像工程是既有联系又有区别的图像处理、图像分析及图像理解三者的有机结合,另外还包括它们的工程应用。; G$ \8 y2 ~1 e N1 U3 h; X
; z, G0 q: @% H0 `
1. 图像处理3 ^8 ^9 Q# B0 Q! E( n9 `9 D, p
) S- W2 X( U+ t2 T! v3 l; a1 ~图像处理的重点是图像之间进行的变换。虽然人们常用图像处理泛指各种图像技术,但比较狭义的图像处理主要是对图像进行各种加工,以改善图像的视觉效果并为自动识别打基础,或对图像进行压缩编码以减少所需的存储空间。3 a' V% i: Z! R
" H) Z' Z$ l9 r" z1 o5 ^
2. 图像分析8 K; P6 }, S- u/ \8 ^- L
% R8 A0 i* a" B6 z
图像分析主要是对图像中感兴趣的目标进行检测和测量,以获得它们的客观信息,从而建立对图像的描述。如果说图像处理是一个从图像到图像的过程,则图像分析则是一个从图像到数据的过程。这里的数据可以是目标特征的测量结果,或是基于测量的符号表示,它们描述了目标的特点和性质。 I4 o( D' \* ]- ]" w$ W; f: k
1 A) S9 O, l- S+ N* t
3. 图像理解 7 D! _! Q2 @1 \ I" `/ h 8 R) c% ]1 K4 W6 R" F图像理解的重点是在图像分析的基础上,进一步研究图像中各目标的性质和它们之间的相互关系,并得出对图像内容含义的理解以及对原来客观场景的解释,从而指导决策。如果说图像分析主要是以观察者为中心来研究客观世界,那么图像理解在一定程度上就是以客观世界为中心,借助知识、经验等来把握整个客观世界。 7 K, H$ m7 V1 W6 M4 ^% g* {" n6 u# d
综上所述,图像处理、图像分析和图像理解是处在三个抽象程度和数据量各有特点的不同层次上。图像处理是比较低层次的操作,它主要在图像像素级上进行处理,处理的数据量非常大。图像分析则进入了中层,分割和特征提取把原来以像素描述的图像转变成比较简洁的非图像形式的描述。图像理解主要是高层操作,基本上是对从描述抽象出来的符号进行运算,其处理过程和方法与人类的思维推理有许多相似之处。 # z% j, {% \- {1 Z9 h # [+ F, U4 T2 @& y2 J. l1.3.2 相关学科和领域0 w7 r- G$ |& P: j, V
" ]" n- Y, `) A' l+ M图像工程是一门系统地研究各种图像理论、技术和应用的交叉学科。从它的研究方法来看,它可以与数字、物理学、生物学、心理学、电子学、计算机科学等许多学科相互借鉴。从它的研究范围来看,它与模式识别、计算机视觉、计算机图形学等多个专业相互交叉。图像工程的研究进展还与人工智能、神经网络、遗传算法、模糊逻辑等理论和技术有密切的联系。它的发展应用与医学、遥感、通信、文档处理和工业自动化等许多领域也是密不可分的。 $ O" p$ z; x% I; I/ E% }8 { ! I& ?) u! D; A/ w- ~! `$ }- [图像工程与计算机图形学(Computer Graphics)、计算机视觉(Computer Vision)、模式识别(Pattern Recognition)等有着密切的关系。图形学原本是指用图形、图表、绘图等形式来表达数据信息的科学。而计算机图形学研究的就是用计算机技术生成这些形式的理论、方法和技术,即由非图像形式的数据描述来生成逼真的图像。它既可以生成现实世界中已经存在的物体的图形,也可以生成虚拟物体的图形,它和图像分析的对象和输出结果正好对调。从狭义上讲,模式识别指的是把基于特征的多维模式空间分成不同类别的识别理论。特别是指不依赖于图形和图像,适用于其他一般的模式分类的理论。模式识别和图形分析比较相似,只是前者试图把图像分解成可用符号较抽象地描述的类别。计算机视觉主要强调用计算机实现人的视觉功能,要用到图像工程三个层次的许多技术,目前的研究内容主要与图像理解相结合。 3 ^2 A3 P e* z. M0 W N: [/ s8 v 1 @7 ^$ @* A9 S; Q* Y1.4 数字图像处理的应用9 |3 [; k8 v4 b5 N! P
0 g7 d# r- R& Q
概括的说,数字图像处理技术的主要应用领域如下: w: u" c' w8 T3 E9 H" R7 m
, V# h; F8 U# D
⑴通讯。包括图像传输、电视电话、电视会议等,主要是进行图像压缩甚至理解基础上的压缩。 3 f& C3 Y& S `; ?; O/ a _% F' ^9 j, {2 H6 X
⑵宇宙探测。由于太空技术的发展,需要用数字图像处理技术处理大量的星体照片。$ Q5 K3 h' o I( a( k
# j2 `/ j, Q% ]
⑶遥感。航空遥感和卫星遥感图像需要用数字技术加工处理,并提取有用的信息。主要用于地形地质分析,矿藏探勘,森林、海洋、水利、农业等资源调查,环境污染监测,自然灾害预测预报,气象卫星云图处理以及地面军事目标的识别等。由于数据量庞大,因此寻求处理及分析这些图像的自动方法,特别是图像对比度增强、分割及图像识别的技术显得极为重要。 5 |$ p9 e8 S% _+ W6 |& o8 V3 R% Z6 M
⑷生物医学领域中的应用。图像处理在这一领域的应用非常广泛,无论是临床诊断还是病理研究都大量采用图像处理技术。它的直观、无创伤、安全方便等优点备受青睐。图像处理首先应用于细胞分类、染色体分类和放射图像等。20世纪70年代数字图像处理在医学上的应用有了重大突破。1972年,X射线断层扫描CT得到实用;1977年,白血球自动分类仪问世;1980年,人们实现了CT的立体重建。医学图像的种类包括X光图像、同位素图像、核磁共振图像、超声波图像、红外线图像以及显微图像等。对这些图像作对比度增强或伪彩色等的处理可帮助医生诊断疫病。1 b% |) K0 L& U N3 K1 v. `
8 K0 K" U, i( ^) {⑸工业生产中的应用。在生产线中对产品及其部件进行无损检测是图像处理技术的一个重要应用领域。这一领域的应用从20世纪70年代起取得了迅猛的发展,主要有产品质量检测;生产过程的自动控制;CAD和CAM等。 [" D1 E- V3 C5 c% n" }- ?3 t) E" i0 a7 z o, T. I
⑹军事、公安等方面的应用。例如军事目标的侦察、制导和警戒系统、自动灭火器的控制及反伪装;公安部门的现场照片、指纹、手迹、人像等的处理和辨识;历史文字和图片档案的修复和管理等。 - z$ j( @7 B) T. a& l# B6 M& Q, V/ ?6 t1 T3 t/ }
⑺机器人视觉。机器视觉作为智能机器人的重要感觉器官,其主要任务是进行三维景物理解和识别。机器视觉主要用于军事侦察或处于危险环境的自主机器人;邮政、医院和家政服务的智能机器人;装配线工件识别、定位;太空机器人的自动操作等。 / D( U s/ i4 V3 z 4 s. d/ r& ]! S' f⑻科学可视化。图像处理和图形学的紧密结合,形成了科学研究领域新型的研究工具。例如考古学可用图像处理方法恢复模糊或其他降质状况的珍贵文物图像。, K M" h1 ~/ \
. G7 }: m2 Y$ _+ ^! x
⑼视频和多媒体系统。电视制作系统中广泛使用图像处理、变换、合成;多媒体系统中静止图像和动态图像的采集、压缩、处理、存储和传输等。4 y' a3 w, l6 m7 T) J
+ R u9 f: i* fD)TIFF格式。处理1、4、8、24位非压缩图像,1、4、8、24位 packbit 压缩图像,1位CCITT压缩图像等。文件内容包括:文件头、参数指针表与参数域、参数数据表和图像数据四部分。它是一种用途广泛的文件格式,其特点是可移植性好,几乎所有的扫描仪及在Windows、Macintosh平台上常用的版面设计软件都支持TIFF文件格式。以这种格式保存的图像文件结构比较复杂,在不压缩存放时文件比较大。# C2 i9 h. h. A$ P9 l. s
, u0 r( E$ V$ w% yDate Last Modified: 2001-01-30 . ?: z1 \/ G8 A6 P( S7 T% a 6 o4 k. R5 f H; S% H/ }8 n4 Y! ]Product: MATLAB 6.0 ==> Current Version `, T: S/ _1 V
% k" e$ R d4 WPlatform: Windows : n: ~0 k3 q9 L" x! k x: N* I! g& R9 \0 ?. e" Q
Problem Description. u' z: g6 `9 l y; L
6 r4 a# W: O% x/ |: O* s
Why do I encounter problems when running MATLAB 6.0 (R12) on Hebrew5 I- Z* k/ u8 _
+ o8 _/ {: A2 m+ A" q& N- Mor7 \3 ]' @: Z1 \6 b$ _% K
; @2 [* Z' K! P0 _- L3 K
Traditional Chinese (Taiwan) Windows? I try to start MATLAB but after & b6 A$ G, r8 p5 t+ k% F 6 h; p6 m l# T) I! @0 O" lthe splash screen disappears, MATLAB exits. . X% p- d- l6 y$ _4 Q; n( B) S }8 x, u; a) ~1 h7 V
PLEASE NOTE: This solution only applies to MATLAB 6.0. If you have a : y5 v$ I! M) A: p8 L 6 O: _! k) y* g& W% _similar problem with MATLAB 5.0 or the Student Edition of MATLAB 5.0,% E. D8 A @3 F
+ e4 u, ~: z4 ]% g! v, x$ ]- I; l; V$ rsee solution 7213. 5 c* B2 Q p1 s; x" k. e2 F6 ~; @$ M3 z" F+ G1 C8 |
Solution:! g0 k( C l k6 O1 V8 S3 ~, i X
7 F) P# p" C2 {6 B& }& r& F
This problem is caused by a bug in one of the font properties files we ship 6 l8 [! n u J1 F5 I+ Y( a) S! \. E4 A8 j, k
with MATLAB. The font.properties file is used by Java to map the standard* x7 F1 s) D+ v, n
9 H! `$ ?8 p/ B
Java font names to system fonts for a particular language operating system. $ v: s) G# ^$ R0 u/ K E7 E1 O: j+ T3 f- N. B- F
However, we made a few assumptions that do not hold for the Hebrew or: k, o2 s- k" G! W
N. z- g! a6 oTraditional Chinese Windows, causing this problem. 3 x# t/ O9 {+ j/ h4 o% h9 g6 V: A; I: h, e$ M
We have created a fixed version of the mwt.jar file that you can use to 8 `3 N4 M7 D( \' U$ d0 a2 H1 `% Z# Y9 H' F1 [7 [8 [; d
correct this. To use the fix, first rename your mwt.jar file as mwt.old.) A9 r3 W0 F) \0 @" r6 T% Q* m& F! ~$ C) p
: Q; _, u m; L; u
This file is found in the $MATLAB\java\jar directory, where $MATLAB is your7 y4 A& I& Z1 m8 z
0 k- ]- S# s3 q, Z2 B$ V1 \" I* FMATLAB root directory. Then download the newer mwt.jar file from:+ z$ I/ o! l! D
: t P% m; y e' X- hand place it in your $MATLAB\java\jar directrory. Then restart MATLAB;; V8 j" ]- k# J$ I
7 j5 @3 z* H+ v) h
this should correct the problem you're seeing.' X9 a* q& o3 T6 D/ G
l* S. q, h7 p则可以得到最小二乘意义上的拟合系数 2 l2 t% g8 o9 Z1 \4 D8 r & ^0 j4 o; t" z, L# S$ p7)Matlab中如何作圆回归?! J9 m- F, T( a3 K
$ Q2 Y2 g/ I, m! b4 D( o. D- i:#Peter Boettcher (boettcher@ll.mit.edu),2002/5/16, comp.soft-sys.matlab#+ M) ^) o3 Y {9 i: H% l1 q2 q/ B1 U
" o9 H4 x( ^* |5 W! R9 U! k
Q5.5: How can I fit a circle to a set of XY data?4 q+ H0 u! _3 ~5 Z6 {/ i* Q; S! U
# K8 s I e3 j z=================================================+ J% R* m2 Q. w5 u6 i9 c- B" E
) E) Y4 L" G( n+ IAn elegant chunk of code to perform least-squares circle fitting was/ @8 a5 `. w2 b/ Y! v# R# k1 E
. W# O6 z6 r" b6 Kwritten by Bucher Izhak and has been floating around the newgroup for : y7 \4 e. u* l. T" l4 @% x' B4 G' @0 ~9 R9 \
some time. The first reference to it that I can find is in:6 w; D- C4 F5 P# @. i Q, P5 B. T5 Y
7 `1 G7 g @( l. a8 H0 c7 Afunction [xc,yc,R,a] = circfit(x,y), [7 U0 q( C- ^; h; B+ ^$ Q
2 r( ] O4 M* t$ |8 j: ]
%CIRCFIT Fits a circle in x,y plane 6 K( P% a- Z6 u7 {% }5 E: ~ ( w% F }- f4 o% + j0 m0 \4 ~9 A+ m/ _# a/ d) X! ?: _) L9 N; R
% [XC, YC, R, A] = CIRCFIT(X,Y); N9 q+ T4 a' I& f& {2 m2 ~
- q* l# H) b- X0 [1 R
% Result is center point (yc,xc) and radius R.A is an optional " J; Z+ n# i1 E' J7 T' \6 N6 } j
% output describing the circle's equation: + n3 G# A6 U' L+ v( q v' I0 I$ N1 w! I
%/ T7 b( N1 q; c& R
0 G0 x& e8 r% i7 @: W7 Z- }* T
% x^2+y^2+a(1)*x+a(2)*y+a(3)=0 % k$ J) M( {5 k0 u9 u' a h0 Z+ b3 Z. {. k
% by Bucher izhak 25/oct/1991 ! t) R; W9 e2 C/ p* O1 n& j5 F0 V9 A : _( o. _) a1 b, r) hn=length(x); xx=x.*x; yy=y.*y; xy=x.*y; 8 G. P8 v/ ^- y" i' \1 E$ P/ q+ { , |/ `; j& T/ o: @5 x' XA=[sum(x) sum(y) n;sum(xy) sum(yy) sum(y);sum(xx) sum(xy) sum(x)];+ i( q& e9 [: A! w: H% v
c5 B! T9 z9 i- G19)Matlab中什么函数可以删除矩阵的某一行或列? . x! S+ c. m3 G 4 h# N/ C' m/ b& e- e% w:#FangQ(Qianqian.Fang@Dartmouth.Edu),2002/6/21,BigGreen/MathTools # : x( J* n$ O2 w, ^$ ~" B: w . N3 l `) @9 h5 hA(j,=[]; %删除A的第j行4 ]1 `) O1 x+ F8 p
- B9 v* @+ A, z# t8 r. [+ G. TA(:,i)=[]; %删除A的第i列 + u) U) ?0 E* J" R$ G$ [$ M" M+ Q
20)Matlab中能开的最大数组是由什么决定的? 4 H# l$ S* P: o" J, F, z4 Z/ I; v4 G$ ]$ W. W2 L9 T
:# chenft (mike),2002/6/1, SMTH/MathTools # ! e2 Q$ O6 L' j3 g7 O# A2 l3 i" ~) y
I have had similar problems. Below is an explanation I received from Ian0 \- b2 X& i2 P
- `$ x% u. b' M% U8 Q: Y
Boyd# G1 z' f o* z3 x" G6 \
, F1 J X, u1 ifrom Mathworks (just giving credit where credit is due) that explains " O ]8 S& I, {/ E2 r9 d" g) t6 o% {. |2 P4 g# L, K% x$ m F' I
what's happening. You solution is to run matlab with the -nojvm mode.6 k% A/ @$ z6 M0 S+ {
" {6 _& E7 I8 i0 c/ P"The heap memory system in J***A consists of data and handle elements.- B. g3 {) ^5 U2 Q4 U
9 V* H$ P) t( Y! S3 }5 [When you allocate a variable you get a handle and data. As long as data % F/ M( Q9 [( W, g - [+ T: x- }% b9 [+ U+ Jhas an 5 X4 m" N+ H3 r ' {) e8 D) ^: h8 ~, s; f$ Wassociated handle, the JVM considers it valid and will not clean it up.' O- R1 v' ^' {/ e# c; j
2 _4 F1 x1 q/ g3 [6 D
However, when you call the clear function in MATLAB, all handles are) y& ^, B' `% g" u: Q/ R/ O5 v- p' n
" J& y. s: A& zdestroyed, and the data associated is now invalid. This means that the" T3 q% f0 o/ y6 ^5 d( m& q
) i2 t3 I2 ]% W5 {/ Y, ]# g
J***A+ y6 r, N9 C! Y b& q( ~
- \8 p+ a$ l* }! a4 Q+ u0 ~
engine can free up that data (garbage collection), but does not mean' d& P$ a4 x$ V" Y& r2 L" V
' N8 O+ \7 V) Y
that it will clean it up at that moment. 2 V5 a- L+ P) L7 P, ]& g - D. G" m# I- W1 [$ DCalling the PACK command encourages J***A to run the garbage collector! V- s; m2 ^& o
& Y, }) Q! N# n3 f1 zand de-fragment the memory. But it does not force it to (This is part7 Z9 a$ }/ n+ J3 ~* p& N* [
1 o$ b2 q. f" o1 p: n! N
of the J***A design). Even though the memory is 'freed' on the heap, : C5 p! E3 a, _# }$ Y8 P ! `& g1 F5 @+ {# xit is not actually free to the OS, it is only free to the JVM. Here ' L* P9 o# x% ^8 G+ x( A V }" ?' l0 {" k$ m( Eis one way to think of it: ) \* Y' G1 _: e. v: I2 P5 n 5 a S+ e/ G2 l ?/ k& ~' O[MATLAB]' i& p' Q- B3 G6 d
# ]: C0 D- B% y1 w5 I5 t[J***A] 6 n' c8 a2 g6 ?* U: h( ^ / a" t$ u, ~5 k9 _[OS]5 M. M3 ^2 z: [) ]( b
* y: t( [# o# \" K+ w. z8 O- R. rMATLAB runs on J***A (virtual machine), and Java runs on the OS (physical 9 J/ _7 s9 h( S j6 q$ [. E- F0 E. Q8 d) ~3 H
machine). So when MATLAB is running in J***A mode memory allocations' W! q( i: c$ P$ y8 S" j+ V# @
% c! H: V. k$ m! K- `0 N8 Z9 uare requested from the JRE, not the OS. * g. g+ r( G. [* E( z 1 [2 f! f [3 O$ b7 |% nOne problem you may be running into is that the default maximum J***A heap3 K0 Y' l' E# Z- @4 o
- w0 s- g% d$ X- P/ l( h% u8 _. R2 psize is relatively low ( <= 64 M, so that is all the memory one session ' f; f% j' l9 s- |) g N, K" _0 f3 q( q# z
of MATLAB will ever get on your system. ) l3 s! P! @5 `8 L# Y 4 i4 K2 ]7 Z% SThe good news is that you can increase this value. You will need to create $ x/ C( o" h2 U* S1 _4 N! M9 z* C! w T- w) K+ h* w( |) y
a java.opts file in $MATLAB/bin/$ARCH (or in the current directory when/ D7 T, G) U5 R7 g
! r" @4 |/ `/ p* W& {* t$ q$ ]
you 2 H6 x& B) L( G6 _* l2 k9 O7 P: L! m6 I/ N" u; `; s5 w5 c
start MATLA and put the following command:; }9 I5 N& p+ S( G2 F
6 [+ x) M; a% I, O& C* V
%%%BEGIN CODE%%% . [0 v2 o& G" p3 x& f7 A * D* U' ^+ d/ b0 WmaxHeapSize = 2684354566 Q2 C( Y! m8 E0 N, F
) l. r# I: ]* ^" b% l% Z, i, k( I, u
%%%END CODE%%%6 D& x+ X# V: a# a
+ M5 `5 A& _5 p! \5 K, Y" y
This will give you 256MB of JVM memory and you can adjust the parameter# [2 b& E. C( v4 [
" W5 y2 {; ~( _% Nas needed.4 p* i5 S& S, K- A
2 ]- z3 b& n/ w6 ~/ K9 A9 xNote: $MATLAB is the root directory and $ARCH is your system 8 M3 m& |" g! N b8 G' K: z4 f5 }3 e$ y2 V% t
architecture. This solution works on Windows as well as Solaris, Linux, ' g( F5 C9 X3 B; b2 c: I ' p, X |& _/ R/ x+ L/ NAlpha, and SGI. A similar operation is possible on IBM and HPUX, but with8 _/ h+ l- L' y3 u6 w
" R2 \& [- u ?9 y! [9 Ea different syntax.8 w, ]3 E$ a! j& e' k1 C4 }
6 `* R. M3 h3 |- rFor the 1.1.8 JVM (Windows, Linux, Solaris, Alpha, SGI) our defaults are: # X3 J$ }, y- k: u- t4 ^: v' n. ~ y) }( y+ a; U
minHeapSize = 16000000 " p. U7 D# D2 [/ [8 ]1 p' x! A( i( D C0 P% a
maxHeapSize = 64000000 ) y/ `. F: h& D # G% s+ ?/ ?2 q2 V0 j I8 XThese are the structure field names in that correspond to -ms and , P5 O0 j& {1 D% w8 c+ l) _3 b5 C* z, P7 M+ Z' L, ?/ v* b2 c
-mx, and the settings above are roughly 16MB and 64MB. n- t+ m, i2 C) h, D; l7 Y$ @
) Y& P3 M$ O" u( A# G; F5 KTo investigate the Java heap a bit, ask via the following: 1 H% X; R& p4 y. U4 o 7 m V4 t% j* [, k* w>> java.lang.Runtime.getRuntime.totalMemory' B% k) b+ K, ^; `4 p" R, C- @
( P/ b1 P. v' L; w4 P% V$ F5 Y>> java.lang.Runtime.getRuntime.freeMemory& @6 O* {/ K( Z9 B( j! y0 @" _
& @4 P3 c) o% A. ]3 l4 e% }
When the free memory hits zero, Java will double the heap size (up to the" v H5 ~) _ N5 v+ n, Q) Z
2 w6 I- v& p9 v; b8 S1 l
maximum setting). + s4 I% ?! A# m9 ~ & i3 N$ T& G+ m# z3 DIf you choose to run without Java, you will remove the overhead of the 5 Q9 c c) `% \9 _( O% V" Q1 j8 x' u# m' ~& V, N9 P9 O/ o
middle man, but you will also lose some MATLAB functionality (mostly 7 n0 n9 w, ], E: Q! h/ A7 e 6 I/ X# [! Q; v( bgraphics and the Editor). You will still have most of the computational' {0 r5 f; D" h, Z6 C
3 E# C3 A* d2 D$ {. ~* f
power though. $ w) h! O% @$ I0 G4 E8 G/ C) G, h8 d* u
Without J***A, memory management will come directly from the OS, and a : F s# M) }" p, H- R1 p: `0 A$ W' i/ c8 _- s
CLEAR operation will result in memory being freed back to the OS. + ]+ b2 g& B% N+ h+ i6 S i3 G. I' w% a4 |
21)如何在Matlab中添加新的工具箱?- e4 t; H. t% \
: k4 u4 r- ?1 ?& O+ j4 a; T2 k) {:#FangQ(Qianqian.Fang@Dartmouth.Edu),2002/6/21,BigGreen/MathTools #: o, m/ U. b0 o
5 _/ [: m' V$ f0 ?. |如果是Matlab安装光盘上的工具箱,重新执行安装程序,选中即可。# ?; E/ N- G8 V; P) X, b7 Q+ n
9 e( n9 F; D- L) L$ M. T. E7 x
如果是单独下载的工具箱,一般情况下仅需要把新的工具箱解压到某, d# e2 D' u6 g
t( @: G0 v ?' Q$ p8 M个目录,然后用addpath(对于多个目录的使用genpath())或者pathtool添 & l' v5 E: f2 B, q) P' w V0 @1 K- n6 k加工具箱的路径,然后用which newtoolbox_command.m来检验是否可 , p) j, G( q. i2 s 4 l: d4 ]- u" l9 N4 r以访问。如果能够显示新设置的路径,则表明该工具箱可以使用了。 + _9 s& P4 Z+ I. f : k, K! o* N( x! a具体请看工具箱自己代的README文件。+ r( e! z1 J8 s- j4 U( F4 O( T
3 Y# v. q1 F# R6 a" d22)如何读写Matlab的.mat文件? & J# u' r, o5 X9 E7 ?9 N% @' w }/ g) c# t/ k
:#FangQ(Qianqian.Fang@Dartmouth.Edu),2002/6/21,BigGreen/MathTools #% x* B9 m$ ?; c4 q
$ o* ~# x0 H# o9 u, y
文件结构参见:' R. |" t! D' `* J; O
* F0 J. A& r$ f, A# R别有多大。搞大型数值计算的,没有好的工作站或者并行系统,就输8 d& o+ Y0 Q% d. E; J4 D
( b8 t3 c3 g! \在了起跑线上了。然后是程序的优化,看看变量是否占用太多内存,8 W- [" Q3 g+ g5 U; E
! ~: S% c7 f7 M& c' G: ]* A
看看是否有功能重复的模块或者计算,经常的是用牺牲内存来换取速7 L# D5 n; ~$ z4 T$ Q" o5 i
$ l& g6 O( k; R( l% z
度,具体取舍,具体需要来决定。用profile看看哪些语句占用时间最5 \1 C% l3 Y3 w+ K
: J% |7 ]3 Q9 U, q6 c- e5 t多,然后把核心部分进行优化。; b2 `! V2 Q. c' k1 Z
. ]# H, C/ l6 X" `# T9 J5 i* X
如果是使用Matlab,使用vectorization和矩阵整体操作的代码要比大量 5 L- W0 D) G, w! i$ P0 ^( l* ^/ x ; f) S8 k' _- y* V: L6 A( A; ?的for循环快很多,eval/inline函数如果出现在核心循环,也会让速度下 ! f" d( v8 v6 Q/ y; @( }# ]1 Y N& v, p6 P' `: o3 _( L
降几时倍的。. ~2 \: Y/ R1 F% T8 z- f
% S# a# @& j& t+ Y# i: r7 x+ J40).Matlab中如何作非线性回归? % W2 V N- ?. ?1 p6 W+ S6 P } 5 K% p$ K- X7 p$ L% ^2 I:#FangQ(Qianqian.Fang@Dartmouth.Edu), 2002/6/22. BigGreen/en_Matlab#* e0 [, H# D" z. m6 }
& r: [* N J( R6 Y6 h; F
请参考" h+ G& p. o4 _2 d0 g$ N
% J* H! {2 @% j1 V3 ^7 \ http://www.mathworks.com/support/solutions/data/10652.shtml ; u/ j% q6 o" U' V* s" I' q* {0 l* i2 n& y, I6 x5 E; T% B. k) ]8 W
matlab默认只提供了多项式拟合的函数polyfit,对于其他稍微简单 3 |9 f, V" D9 P & ~0 n$ x7 n' E+ w6 b一点的拟合,如标准的指数、对数、高阶多项式拟合,都有解析公式,参见: : A* p1 @, J Z- i, o T - T; R b4 T+ r# o) f8 @4 c2 Mhttp://mathworld.wolfram.com/LeastSquaresFitting.html 7 @. c5 i& M6 S: u' B ~" ^. R/ g( ^$ `/ O Z; g
对于更加复杂的非线性函数,建议使用Mathematica或者DataFit$ `( O. M% G4 ~; K3 d/ r
5 M" E7 P: z: n& \1 f. z0 dMathematica中提供了Fit[],以及 % }- S! v* D6 Y0 u0 c) O% x ~5 S* x. X. T0 E. U3 a" J
<< Statistics`NonlinearFit` 3 l C ~7 E4 h1 S6 { 6 ]- F% C" g! Q! R$ INonlinearFit[],NonlinearRegress[]* S" Y, G$ w6 W
+ ~% f, K0 ]7 x A. [可以拟合任意复杂的表达式。 1 r Z! o( a0 w* y! k0 O% i) T" j8 |. i0 c$ M( e) z# o
DataFit可以自定义拟合模型,适用于复杂系统的拟合。+ b Y% F4 |4 s9 R9 B& b1 g% i3 G8 o
3 R; l, \5 j: l( k1 Z" l# h* I% O
4 d8 X# P [! e; l1 N0 c
# d, @& d6 u `& f. S. g8 ^1 | ' _- } |. C- p" u # h4 `( V) Z X: z; M8 D' tVc++下利用Matlab工具箱进行数字信号处理 9 o2 @' n* O$ N2 U: q' N4 D! X( R- y% _$ e* Y5 ]$ v% w
8 d T5 @5 X, D. E5 I
' ]! k" p0 A+ E& `$ n/ U3 g/ t {Matlab的信号处理工具箱是信号算法文件的集合,它处理的基本对象是信号与系统,信号处理工具箱位于目录、Toolbox\Signal下,利用工具箱中的文件可以实现信号的变换、滤波、谱估计、滤波器设计等。在其它的环境如Vc下如果能调用Matlab工具箱中的文件,会大大地加快一些算法的实现,同时其可靠性也很高。! u! A5 Z+ Q+ C y
/ R# g8 x; T7 w3 g1 N' y+ w利用Matlab引擎' M6 i: t/ _! d5 X1 t! i$ _6 I8 y
0 Z0 |/ U' Q; I% N
Matlab引擎采用客户和服务器计算方式,在运用中,Vc的C语言或C++语言的程序作为前端客户机,它向Matlab引擎传递命令和数据信息,并从Matlab引擎接收数据信息,它提供了下列几个函数: engOpen, engGetArray, engPutArray, engEvaString,. ?& G# n5 }( v) l; L) N _: u
9 K/ K- D5 |* l3 X) H" Y
engOutputBuffer ,engClose与客户机进行交互。 : t7 D, {% x6 a' F' D! L% [4 b& G( ? 2 s; I& E' }1 U. V( X8 A下面例程是在Vc下建一个基于对话框的应用程序,在对话框中设置一个Button控件OnMatlabEngine.,在对话框 .cpp文件中加入”engine.h” 和“math.h” 头文件,下面给出部分程序清单。9 `+ J# k% I' {3 A1 Q+ k' Q
) V& i4 b' s* x9 V B0 `. Z9 \Void CtestmatlabDlg::OnMatlabEngine(){5 A, E/ |6 M2 i- |2 S* |7 H
* T' ?" O* G& r, j/ @
Engine *ep; 4 Y8 k6 p# ~$ ?% o* g, ~' W8 M4 K) h
mxArray* T=NULL,*result=NULL,*mFs=NULL,*mnfft= NULL; 5 P6 y% M f: t$ U8 x! O9 Q# Q3 P- C/ |" ~: ~
double datax[1024];! a1 |: e; G+ ?/ r% u* b
( g) a! b' F* z$ i
char buffer[1024]; 0 n' \# j+ a' x; |1 ` # C* h0 s8 z8 cfor(int j=0;j<1024;j++)//注:如通过采集卡采集数据可将采集的数据放在datax[]数组中,此循环就不需要 ! ~* T% m) x; K0 P% n I# s. _' W& k4 P1 c0 `8 E$ y) F4 r
{ . H' c1 G0 f% W5 P' ]9 R5 v$ [# |, z m* x6 z: D% |; A, T& k! _& ]
double samt=(double)(1.0/1024);8 W: l* r5 Y6 H, M6 H
9 w8 | }* _( M9 l: j$ W$ T# V3 Fdatax[j]=sin(2.0*63.0*samt*3.1415926+1.15*3.1415926);! f- [& Q$ _% n. s$ v6 n# }5 F1 L
8 E+ N& W' }$ B. q9 B. D
} ) B" D1 w4 l0 y+ q% b N" g2 K: f( r$ y3 tdouble *pPxx,*pFxx; j! {, S) p; B' \9 M3 N, n# X4 W
2 G# b9 {+ W1 z0 ]0 S5 `: M% |
if(!(ep=engOpen(" \0"))){//打开Matlab引擎,建立与本地Matlab的连接 S. |& C7 U6 H3 g! A" l0 H- w& J 1 G* X e4 z+ k' U4 Dfprintf(stderr,"\n Can't start MATLAB engine\n"); 8 ~+ k+ ?( ]5 B7 c, G8 k- R* Z* H3 t& z1 \) M6 [5 v
exit(-1);- d; s) C/ X) A/ K2 G
4 t' L h) ?# ]% R} * X# p* w% J6 p V+ u: W$ d+ ~ l9 H! _. R3 D' X% Edouble Fs[1]={1024};//因为Matlab所有参与运算的参数都是矩阵的形式,因而下列几行将参数转变 & p6 d. ?$ l$ k: x& t. h& y ' k3 G& o. p+ ndouble nfft[1]={1024};//成Matlab可接受的矩阵形式。 / `( ~8 i. F7 d. S; p+ ?) u. z5 I) t Z2 O3 k1 P5 H I& l! G. k
T=mxCreateDoubleMatrix(1,1024,mxREAL); 4 p; k1 V7 f; F' Y( r* }7 ]" H9 z * l4 B$ ^- [6 d+ G6 rmnfft=mxCreateDoubleMatrix(1,1,mxREAL); " N, B1 i: T% `9 q9 `, T % D+ V" y8 f( Q2 q! X `) V! z/ lmFs=mxCreateDoubleMatrix(1,1,mxREAL); ' r; A L+ ~0 p! g. P; w8 D6 i: n0 O$ v+ P _
mxSetName(T,"T");+ m% c$ Z4 W6 i' ?0 Q, P. n0 I9 S
# E' T& c+ V4 P/ m& h+ E* l
mxSetName(mnfft,"mnfft");6 }/ ]0 _7 Z6 D" {$ A' Q2 t% K! }" ~ C
, V. `# b5 C! n8 ^0 I* N
mxSetName(mFs,"mFs"); , t6 U+ K# W& I. G) }) R, t0 i4 W5 x0 A/ F" p7 F i1 l
memcpy((char*)mxGetPr(T),(char*)datax, 1024*sizeof(double));4 a) l4 W, [7 y P, V
7 x2 I ]+ t# w! _- Q+ X( |! ]! u1 G
memcpy((char*)mxGetPr(mnfft),(char*)nfft, sizeof(double)); , O+ D5 I) E0 f& z& m3 q5 d1 a6 [% m+ K, P4 u/ U8 U0 F
memcpy((char*)mxGetPr(mFs),(char*)Fs,1*sizeof(double));/ |$ j4 Y5 U( H& f1 x
v1 \- w/ }8 v7 XengPutArray(ep,T); //将转化的参数放入引擎中,此时可在Matlab command窗口下查看此参数7 O4 `5 Q2 O8 C
9 r- ]/ Z: M4 \4 n
engPutArray(ep,mnfft);, G2 V3 u* h. J7 N/ w* I; j6 f+ s
2 F% T; G- ^4 t5 Q2 P+ XengPutArray(ep,mFs);' O& E, B o: T
" }6 _% C6 ?* w9 zengEvalString(ep,"[pxx,fo]=psd(T,mnfft,mFs);"); //利用引擎执行工具箱中文件 ' S, g9 I( f- L5 y( O9 ]7 W 4 d( K- c, {; g( A5 D6 J X$ R4 lengOutputBuffer(ep,buffer,512); //如只想看显示图形,可将返回参数去掉,psd无返回参数缺省情况下会自动画图形 Q: A Y* D: M' u, p8 W: T
. H( W: N1 x3 j& h k# \$ \$ B
result=engGetArray(ep,"pxx");//取出引擎中的数据放在所指的区域中供后续处理" e P; p" x6 G# t: L. L7 U0 M
% W, R; W: @- w" z4 x, W
pPxx=mxGetPr(result); , R5 r7 X* V' t. D) p. M' ~' j1 \/ ]" w% S6 u! K
result=engGetArray(ep,"fo"); & I: l5 }: Q& o1 {" }+ |6 o. A' a" o
pFxx=mxGetPr(result); # h% n+ S3 q W8 G8 e) L' }$ W, B( P0 g" j9 e- z
engEvalString(ep,"plot(fo,10*log10(pxx));");//利用引擎画图 " ]/ h* v" Y# U+ J# E1 ?! P6 { d
engEvalString(ep,"title('功率谱分析');"); 7 E* t1 ]" |8 j2 l' ] 3 d) e* G) ]. m, PengEvalString(ep,"xlabel('Hz');"); - h# }9 y" B% }2 x1 ? w9 U+ B7 P) P! s2 A( cengEvalString(ep,"ylable('db');"); , f: Q3 |* L& n. L1 Z2 E . l' n7 H9 v: G/ ^* }3 \mxDestroyArray(T); //释放内存 ; E/ p6 v4 K: a* w4 n# @6 o3 J4 P& q$ I1 ~' L% P) }9 {
mxDestroyArray(mFs); 6 G6 e4 Y1 z" X6 d% @, J) @" K , K" \" e0 y) z$ e5 ]mxDestroyArray(mnfft); + [( Z$ F& W2 l. A3 m . A/ |: M* Y8 D) Y2 {1 pmxDestroyArray(result);3 V6 j' S! \* x) H9 S$ r/ r
9 y! v8 t9 F% C* k* ?. o
engEvalString(ep,"close;");/ L. ~0 Y& n/ M3 h+ t7 }7 @
: W% }( l# M! n$ `
engClose(ep); 4 ~, t, s- \; ^' S M2 r1 w; Q/ c* q. s% w" {0 V$ }
}7 J# r8 m3 b+ X. q- z
6 p0 u9 d }5 J. ]: L# q% Y上述程序在Vc下编译需要将 libeng.dll和libmx.dll两个动态库利用以下的命令:: D( V8 a. Z2 Q: g
/ _, R W1 g' Y: Q) F# ^
lib/def:<自己的Matlab的安装路径,下同>e:\ Matlab\extern\include\*.def /machine:ix86 /out:*.lib来生成程序所需的静态连接库libeng.lib和libmx.lib,将libeng.lib和libmx.lib所在的目录加入Vc++ project/link/object/library modules下即可。6 M; J) Q, ?/ n% H: Q
" j v$ W) b9 p2 Z! |4 v* H: ]; i
利用Matlab自身的编译器调用工具箱中的函数 # z3 N! D2 D/ F& @. f" f( m. J( M2 V
" f1 z/ L/ [( G# u
# Z; h5 d& Y; V5 v8 R8 P* M
Matlab的编译器可将Matlab的M文件转换为为C或C++的源代码以产生完全脱离Matlab运行环境的独立的运用程序,但Matlab本身的资料说明编译器如用来建立独立的运用程序,不能调用Matlab工具箱中的函数,这非常不利于搞一些特殊的算法。本人研究了一段时间发现,工具箱中的函数既然是M文件就一定可以用编译器来编译,以提供如Vc的调用函数,但是编译器只能编译一个独立的M文件,即这个 M文件不依赖于其他的M文件。如果M文件中又调用了其他的M文件,可将被调用的M文件拷贝到调用M文件的相应位置,作适当的改动就可以用于编译器编译。编译器不支持图形函数,所以M文件中如有图形函数需注释掉。 ! k X2 A! j4 K: }3 {& K ; F; z6 t. U& C0 z当Matlab的编译器mcc加入适当的参数-e(mcc –e *.*)或-p(mcc –p *.*)就可生成将输入的M文件转换为适用于特定运用的C或C++源代码。这样如果要在Vc下编译通过,还需连入以下几个库libmmfile.dll, libmatlb.dll, libmcc.dll, libmat.dll. libmx.dll. mibut.dll 以及Matlab C MATH库,建议采用前述的方法将动态连接改为静态连接。对于C/C++编译环境的设置,在Matlab command窗口下运行mex –setup 然后依提示操作,而对于C/C++连接环境的设置,运行mbuild –setup依提示操作即可。; r& I: S3 _, T7 n1 d$ N
0 | [. \/ r; T; v2 n _. w下面给出利用编译器将Matlab工具箱中psd.m文件生成可供Vc调用的函数。3 _' ]! ~9 h- \+ e1 i
" `* o& m# c4 q, p7 z% ~将psd.m文件拷贝一份至Matlab\bin目录下,改写相应调用的M文件如nargchk.m, hanning.m等。为生成的代码简洁,对于采集数据处理输入参数很明了的情况下可作大量的删减,最终使psd.m成为一个不依赖于其他M文件的独立的M文件,注意千万注释掉作图代码,最终改成如下形式,限于篇幅给出关键的几步: 5 t( M! m' y x) I $ Q' L# n+ W7 i3 n' B8 O1 vfunction [Pxx,f]=psd(Fs,nfft,noverlap,x)$ e9 ^' l8 a, l. i
' B8 X7 U3 u) x) K/ q ~& Fwindow=o,5*(1-cos(2*pi*(1:nfft)’/(nffft+1)));//hanning 窗# Y. R* F7 _' Y8 r0 O
n. C W- s& kdflag=’none’; 5 d2 L. X8 P$ r' Q1 S: T & i7 [! G9 m; V1 l9 T% Dwindow=window(;) o% e6 x5 E% T$ ^& `( }: g 7 g( P: [! ~1 k# I$ u…………………………………. " c& g* O9 D- j0 S0 l! U4 a, V( S7 S+ W5 E* a: ? t9 ?
以上只要稍懂Matlab语言和信号处理知识就可完成这项工作。 " {! L3 t/ W' g7 J2 x1 ]9 T. P7 i+ G4 V6 a0 \3 o L
假设上述代码重新存为testwin.m,在Matlab command 窗口下设置好环境参数运行mcc –e testwin,则可在Matlab\bin下生成testwin.c ,如运行mcc –p testwin 则生成testwin.cpp. - a, f$ m2 K* d. l. S1 L7 E! h; J. I4 a5 N! h( g9 m
Vc下建立一个基于对话框的文件,然后在对话框里加一个Button控件OnButtonPsd* u& P k- C+ X7 b
- i, f: M6 _) w* ]: u7 F5 h& @
将上述生成的.c文件的头文件加入到工程的.cpp中,且将#ifdef_cplusplus, |3 A& T% R5 R5 E2 U8 ^$ ]
E, P6 A' j! R1 @: Z* m. |; N
extern “c”{+ s) u. |4 c* Q
* v2 N2 i' X3 \: \4 \. w
#end if# U& N- v% b; C
' Q$ w7 M, N/ F1 |9 i4 _将#ifdef_cplusplus " b u, l. m. \" b( E. _: F7 h ' l6 P+ s/ V/ H} ; j8 n: e. v! o$ ~; y+ p% l% n# A% Z& q u) B) K
#end if加入.cpp文件未尾' C R) O# d' Q; b! c' [
* U& b$ S* L! O" f1 r5 g为了简洁且便于处理将生成的c函数稍改动,给出部分代码如下: r) C! Y1 o# G$ b
- d! g- ?( u" G7 _5 i- |
void CTestpsdwinDlg::OnButtonPsd(){( C9 A4 H( Y, Z
% H4 X: [" D# j5 [
mxArray* x_rhs_;//指向采集数据存放区% G+ G0 \: e: T! a% v5 B
; Z$ h1 V( Z9 w9 z K' E) E3 wFs=23510;//数据采集的频率 nfft=1024;//1024点的fft- ?( I9 K: Y6 y Y4 H0 w, m4 U, }% O
. ?% U/ N' @) u4 a* ~2 @double datax[1024]//采集的数据 8 Q& V8 U. G* ^, V2 }8 s# A1 t5 i ~' w) M! @$ d2 L! Qx_rhs_mxCreateDoubleMatrix(1,1024,mxReal);0 P; Z Z/ w/ j) K: n+ m
# S G/ d# {6 u X Jmemcpy(mxGetPr(x_rhs_),datax,1024*sizeof(double)); - M& D( _5 j# U/ e 2 C" g: A! @/ i5 F9 q0 Hnoverlap=512; 7 O, v4 w' [4 ?" i& R0 p; s* c& d6 b% y
………………. * A; ]1 @6 s( a$ [+ N8 i5 A& B; { B: G1 S) @
………………. 7 C. @8 C7 r- b W5 y' O& M( X; v' Y$ u) `9 K7 J" o. L
mccCopy(&Pxx,&Spec);% E0 g# g9 ^" X7 Q3 L4 J$ l
, f0 s/ m2 \+ ]" s3 D. [
mccCopy(&f,&frevgg_vector); * n8 x$ g3 x; u# g; L( o 4 b- f s! }5 ffor(int j=0;j<(int)(nfft/2+1);j++) & ]7 M& V& N- ]& ~$ t [3 y4 j) D, \) [1 b$ O! y4 u8 ]
{ ! ^4 X: ?& L4 |" ?- Y5 k, s/ g3 i6 Y% n- y0 s" l" O3 `, j
datap[j]=mccGetRealVectorElement(&Pxx, (j+1));//功率谱密度存于datap[]数组* i# v# J5 R2 J& L' ~8 f. A. q
2 d: p* s2 A5 G2 A/ q
dataf[j]=mccGetRealVectorElement(&f, (j+1));//相应频率存于数组dataf[]中 ! n6 W$ {2 C6 [7 w; t9 u+ [* K7 c* _; _
} 1 F1 \8 M7 S2 J7 `4 C! \7 s4 Q3 y5 u' [2 ~7 k* k; ?. K1 v3 s
mccFreeMatrix(&Pxx); 6 _. W- k1 ?; y, n. d5 k& O; F C; |( m8 ~$ E! V' }
………………. ( p- E- ?& Z, f+ [# N$ t- F( H1 f% V4 A3 {! J8 f$ b
SendMessageBox(WM_PAINT,0,0);//利用Vc下的图形函数画图7 y+ l7 i* A7 g/ E: _1 G( o' k
1 {8 ], s& }( a7 `* g9 R7 V4 r
Return;1 }/ |: ]0 z/ \- y4 D" t: \: W
4 S: L4 S; j9 E* s
}3 I4 G! R4 c" U; f$ X
! M, C$ W; ~4 g% R4 ?
, o+ }' P8 o: e! R% }9 k j, {6 j
4 r7 N" R( y+ ^) S" \如上生成的程序可读性不太好,而生成的c++代码则可读性较好,但千万注意只能用 Matlab的MATH库,不可用c++的MATH库,否则编译会出错,限于篇幅在此不述。 ( j* N8 B# q4 I% | 3 A7 f$ j4 I/ U7 e, d3)利用Matcom调用工具箱中的函数/ Y. p% A6 j/ ]0 ]* ^ e, }5 [* K9 D9 X
) g$ p& L8 ^5 m' `- |2 q' J ?
Matcom编译M文件,先将M文件按照与Matcom的cpp库的对应关系翻译为cpp源代码,然后用对应版本的c编译器将cpp文件编译成相应的exe或dll文件,所以第一次运行要指定c编译器的路径,否则无法编译,指定好的编译信息就写在Matcom\bin\matcom.ini文件中,不过这一步按装matcom时,它自动寻找编译器并将其写入matcom.ini文件中,matcom4.5版中使用TeeChart3.0 OCX控件,因而它支持图形操作。 0 x5 _7 m% m! ~: P! j, H; h1 Y6 o/ M4 C
我们依然用上述的testwin.m文件,不要将图形函数注释掉,利用Mideva来生成可被Vc调用的信号处理程序。 / N( P+ U5 u$ m/ g3 ]2 k+ D* e$ G% u9 Y* h$ `; O$ [3 w
运行Mideva在主界面上直打开M文件,在菜单中选择compile to dll,输入testwin..在Matcom debug目录下可以找到这样的几个文件,testwin.c ,testwin.h,testwin.cpp,testwin.lib,testwin.dll,testwin.exp等。6 R0 |9 S+ {2 k# C
: F$ d6 u/ M0 d, Q
将上述testwin.cpp和testwin.h加入工程中,project/add to project/files并且在相应的文件中加入”stdafx.h”" @5 O2 h) L, e- w6 R2 O
/ _: X: x) ^! ]4 z
加连接库:Tools\option\directory\ ,选include选项,加入e:\matcom45\lib (包含matcom.h)) X R" P* P: A5 z1 m1 U$ [
( H" D3 W" }- ]/ h
library选项,加入e:\matcom45\lib/ b" O& k9 L8 s
( ~! ]- F1 y9 d" b
4) project\add to project\files 文件类型选项选(.lib)将e:\matcom45\lib\v4501.lib加入工程中编译运行。相应代码如下: ' f8 E# Y* P& H+ r# H3 p9 ?. p$ f# O: R' T- z- g8 I
void CtestmatcomDlg::OnpsdButton(){" u. X2 d. ^ l: Y) \
4 I2 W8 a$ `$ K; ?* m$ k9 s
double datap[512],dataf[512]; ; b1 W7 s+ u& ~8 u) T + q5 l6 c. f" Z1 r- s* v! y# uinitM(MATCOM_VERSION);//初始化matcom库 $ D% a* f* c4 g$ d; V0 ^) I# V9 S/ s2 A# ~; V
Mm Fs,nfft,noverlap;//创建矩阵, M+ [+ Y/ k1 Q9 `# L
: W% ~) |# }( _5 N4 \Mm x=zeros(1,1024); , k3 L$ j3 k G0 M4 |$ T# z ; f: {( `8 u! WFs=1024;nfft=1024;noverlap=128; 2 I3 v3 L5 P& M- o / N3 ?9 [3 x% A& s hdMm(Pxx_o);dMm(f_o);//创建并命名矩阵6 Z, w, i: K5 i- p# R5 B$ x
/ t" ]5 \' D) _& X6 [datax[];//数据采集的数据存于此数组中3 A0 E( O/ |' p. i9 x
: u4 D" p5 Z* Q5 I* X: J6 dfor(int i=1;i<=1024;i++) ( L, }6 S0 v( P9 s* R! T k9 `: K& V6 V
{' J' y8 N) G2 F. t! S l; u- \4 C/ b
, U" e( ^6 P ? ?
x.r(1,i)=datax[i+1];//给x阵赋值 6 N; ^) c5 k: S+ b g 3 x. L0 U4 r7 w0 v4 S4 X o& E9 _7 X} & @1 r+ _- B2 z* T1 E) H& `& \( J
testwin(Fs,nfft,noverlap,x,i_o,Pxx,f_o);//matcom生成的函数% ^4 T5 J8 t9 m9 s- E6 R
9 o4 t. T3 o& O$ q4 x* N8 e* q9 T, j
for(i=0;i<513;i++){//取出功率谱密度分析结果" }! E5 m) S% k0 p' v
S' `* o/ q: _% y4 `6 p) Gdataf=f_o.r(i+1,1); 6 A3 G2 \2 I' r6 u9 s9 l9 a/ j5 P* o% W) e- B
datap=Pxx_o.r(i+1,1);} % r. r; z( H3 c/ { z7 m 4 l( b% c5 V; Z& F f$ H+ K( \$ @exitM(); 1 P4 \2 a1 W2 i$ }: _" A2 V0 L0 ~' g+ D5 e- X& E& ?
return; 8 p: ~) s- G4 z5 W @ - l R! T$ Q8 D1 y, a}! Q* s7 A% k: f
! O) Z; O G. M O可见利用Matcom进行M文件转换非常的容易,生成的代码可读性很好,以上的转换同时生成了可供Vc调用的动态连接库,其使用和一般的动态库一样使用。同时需指明Matcom不仅可转换独立的不依赖于其它M文件的M文件,同时可转换调用其它M文件的M文件嵌套。条件是这此M文件在同一个目录下面,如前所述的psd.m可直接用上述方法转换,生成了多个重载形式的psd函数2 W8 b5 y0 S% h7 V
9 }: M# h7 f" _/ T9 F/ F b! B结论:利用Mtlab引擎调用工具箱中的函数可节省大量的系统资源,应用程序整体性能较好,但不可脱离Matlab 的环境运行。用Matlab编译器进行工具箱函数的调用,须转换相应的M文件使其成为独立的M文件,且不支持图形函数,转换的代码可读性不太好。用Matcom 进行转换非常方便,生成的代码可读性很好,支持图形函数,且代码执行的速度比不转换平均要快1.5倍以上。以上程序在Vc++ 6.0,Matlab5.2,Matcom4.5中调试通过,以上方法在工程实践中已得到很好的运用。6 Q" C& B6 L+ p
/ x; K$ G1 E* g K, g; f
摘要:本文详述了在Vc环境下如何利用Matlab工具箱进行数字信号处理,全文以Matlab工具箱中功率谱密度分析函数为例,介绍了通过Matlab自带的引擎、Matlab自身的编译器以及利用MathTools公司的Matcom进行对工具箱函数的调用。6 C+ [+ S7 M/ C# u; L7 n
2 X5 B$ N5 Q, E0 Q7 d( Y5 S% A: X/ [' U 5 \, O9 ~/ h# I4 U . X7 o; i" @( ]" ]6 Y# E