Matlab中的细节问题及技巧(持续更新)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Matlab中的细节问题及技巧(持续更新)
接触Matlab是从⼤⼆开始的,但那时对数字信号处理不怎么感兴趣,因此⼀学期下来,连编写⼀个最基本的function都不会……
⼤三开始学习数字图像处理,⽆奈,只好重拾Matlab。
虽然Matlab的交互界⾯做的很好,Manual尤其强⼤,但由于基础不好,在写程序时还是不时地被细节问题困扰,因此决定⽤此⽂来记录那些让我不胜其烦的细节问题,同时也分享给⼤家
1. 在进⾏图像处理时常常会⽤到图像的长宽像素信息,⼀般语句为
[M N]=size('figurename'); 这⾥M是图像⼆维矩阵的⾏数,N是⼆维图像的列数。
⽐如下⾯的图像,是⼀个5*8⼤⼩。
学过framebuffer的同学应该知道,对于显⽰屏,⼀般的坐标是从左向右是x坐标,从上到下是y坐标,因此对于图像来说N表⽰的是x⽅向上的⼤⼩,M表⽰y⽅向的⼤⼩。
如果不注意,在进⾏图像⼏何变换时要注意。
否则常常会把因为习惯问题把M误以为是x⽅向的,⽽N是y⽅向的。
2.关于Matlab中变量的类型问题。
在Matlab中,我们处理的是整数坐标,但Matlab中像素值本⾝并不是整数,在Matlab和IPT为表⽰像素值所⽀持的数据类型有以下10种:
①double 8byte/pix
②uint8 1byte/pix 平时我们⽤imread读出图像时⼀般都是这个类型的
③uint16 2byte/pix
④uint32 4byte/pix
⑤int8 1byte/pix
⑥int16 2byte/pix
⑦int32 4byte/pix
⑧single 4byte/pix
⑨char 2byte/pix
第⼗种只有在⼆值图像中才会⽤到,即logical类的。
logical型虽然只⽤1bit就可以表⽰,但在Matlab中却需要占⽤1byte。
为嘛?其实我也不清楚,可能Matlab不能像C⼀样进⾏位操作吧。
我们知道,Matlab内部是以double类型进⾏计算的,因此在初始化⼀个变量时,如果不指定你要给变量赋什么类型的值,它就默认是double型的。
如:
a=1; 则a将占8byte,假如你想把a初始化为⼀个logical类型的,这这样写:a=logical(1);
⽤⼀个变量对另⼀个变量进⾏初始化,如果不进⾏类型转换,则被初始化的变量将和⽤于初始化的变量的类型⼀致,看下⾯的例⼦:
>> a=uint8([255 255])
a =
255 255
>> b=a(1)+a(2)
b =
255
显然,b得到的不是我们想要的答案,因为a向量中的元素为uint8类型的,如果直接相加并赋给b,Matlab是不会因为溢出⽽把类型进⾏扩展的,因此在预测到会溢出时应事先进⾏类型转换,否则就得不到正确数据。
例如我在对图像进⾏⼆维傅⾥叶变换时没注意到这个问题,导致每次变换后图像⼏乎是⼀⽚⿊,我郁闷了半天。
后来发现原来是因为直流分量本来很⼤,但由于没有进⾏类型转换,导致直流被活⽣⽣地截掉了。
类型转换格式如下:
B=data_class_name(A)
data_class_name可以使以上类型中的任意⼀种。
转换的原则可参照下⾯的例⼦
>> a=[256 3 500 -1]
a =
256.00 3.00 500.00 -1.00
>> b=uint8(a);
>> b
b =
255 3 255 0
a是double型的,要转换成uint8型时,⼤于uint8类型最⼤值255的就变成255,⼩于uint8型最⼩值0的,就变为0,其他不变。
函数islogical⽤来判断数据是否是logical型的,⽤法是
islogical(a);
若a为logical的,则返回1,否为为0
图像类和类型间的转换函数主要有:
名称:输出类型:输⼊类型
im2uint8 uint8 logical,uint8,uint16,double
im2uint16 uint16 logical,uint8,uint16,double
mat2gray double(在0到1之间) double
im2double double logical,uint8,uint16,double
im2bw logical uint8,uint16,double
⽤法直接查看Manual就好。
3. 对数组的索引
直接上例⼦>> a=[1 2;4 3]
a =
1.00
2.00
4.00 3.00
>> a(1:end)
ans =
1.00 4.00
2.00
3.00
>> a(:)
ans =
1.00
4.00
2.00
3.00
没错:a(1:end)产⽣⾏向量,a(:)产⽣列向量
其实a(:)有⼀个很重要的⽤法,就是对⼀个数组进⾏重新变为a的形状。
前提是两者元素数量相等。
例⼦:
a =
0 0 0
0 0 0
>> b=[1 2 3 4 5 6]
b =
1.00
2.00
3.00
4.00
5.00
6.00
>> a(:)=b
a =
1.00 3.00 5.00
2.00 4.00 6.00
b不限于向量,也可以是3*2的数组。
4.Matlab中句柄的使⽤
句柄是什么?没学过Windows编程,因此对句柄的理解也停留在字⾯上。
百度百科上这样解释:WINDOWS程序中并不是⽤物理地址来标识⼀个内存块,⽂件,任务或动态装⼊模块的。
相反,WINDOWS API给这些项⽬分配确定的句柄,并将句柄返回给应⽤程序,然后通过句柄来进⾏操作。
在《WINDOWS编程短平快》(南京⼤学出版社)⼀书中是这么说的:句柄是WINDOWS⽤来标识被应⽤程序所建⽴或使⽤的对象的唯⼀整数,WINDOWS使⽤各种各样的句柄标识诸如应⽤程序实例,窗⼝,控制,位图,GDI对象等等。
WINDOWS句柄有点象C语⾔中的⽂件句柄。
从上⾯的2个定义中我们可以看到,句柄是⼀个标识符,是拿来标识对象或者项⽬的。
它就像我们的车牌号⼀样,每⼀辆注册过的车都会有⼀个确定的号码,不同的车号码各不相同,但是也可能会在不同的时期出现两辆号码相同的车,只不过它们不会同时处于使⽤之中罢了。
从数据类型上来看它只是⼀个32位的⽆符号整数。
应⽤程序⼏乎总是通过调⽤⼀个WINDOWS 函数来获得⼀个句柄,之后其他的WINDOWS函数就可以使⽤该句柄,以引⽤相应的对象。
对于matlab下的句柄使⽤,也是从百度知道上了解到的:
⽐如定义f(x)=x^2,可以写为
f=@(x)(x.^2)
其中@(x)(x.^2)就是匿名函数,第⼀个括号⾥⾯是⾃变量,第⼆个括号⾥⾯是表达式,@是函数指针
f=@(x)(x.^2)表⽰将匿名函数@(x)(x.^2)赋值给f,于是f就表⽰该函数。
于是f(2)=2.^2=4;f(1:3)=[1:3].^2=[1 4 9]等等
定义匿名函数时也可以调⽤别的匿名函数,⽐如
f1=@(x,y)(x.^2+y.^2)
定义了函数x^2+y^2
f2=@(t)(f1(t,2))
定义了函数t^2+4
f3=@(x)(f1(x(1),x(2)))
定义了函数x(1)^2+x(2)^2
使⽤匿名函数时⼀定要注意函数本⾝的参数形式,如
f1(2,3)
表⽰2^2+3^2
f2(3)=3
表⽰3^2+4
f3([1,2])
表⽰1^2+2^2
说⽩了就是函数指针
ps:这⾥还是有点晕,句柄到底是不是函数指针?
⼏个关于⾯积,连通域的函数⽤法(此部分摘⾃/gaoshangbing/MyArticles.html)
1、 matlab函数bwareaopen──删除⼩⾯积对象
格式:BW2 = bwareaopen(BW,P,conn)
作⽤:删除⼆值图像BW中⾯积⼩于P的对象,默认情况下使⽤8邻域。
算法:
(1)Determine the connected components.
L = bwlabeln(BW, conn);
(2)Compute the area of each component.
S = regionprops(L, 'Area');
(3)Remove small objects.
bw2 = ismember(L, find([S.Area] >= P));
2、matlab函数bwarea──计算对象⾯积
格式:total = bwarea(BW)
作⽤:估计⼆值图像中对象的⾯积。
注:该⾯积和⼆值图像中对象的像素数⽬不⼀定相等。
3、matlab函数imclearborder──边界对象抑制
格式:IM2 = imclearborder(IM,conn)
作⽤:抑制和图像边界相连的亮对象。
若IM是⼆值图,imclearborder将删除和图像边界相连的对象。
默认情况conn=8。
注:For grayscale images, imclearborder tends to reduce the overall intensity level in addition to suppressing border structures.
算法:
(1)Mask image is the input image.
(2)Marker image is zero everywhere except along the border, where it equals the mask image.
4、matlab函数bwboundaries──获取对象轮廓
格式:B = bwboundaries(BW,conn)(基本格式)
作⽤:获取⼆值图中对象的轮廓,和OpenCV中cvFindContours函数功能类似。
B是⼀个P×1的cell数组,P为对象个数,每个cell是Q×2的矩阵,对应于对象轮廓像素的坐标。
5、matlab函数imregionalmin──获取极⼩值区域
格式:BW = imregionalmin(I,conn)
作⽤:寻找图像I的极⼩值区域(regional maxima),默认情况conn=8。
Regional minima are connected components of pixels with a constant intensity value, and whose external boundary pixels
all have a higher value.
6、matlab函数bwulterode──距离变换的极⼤值
格式:BW2 = bwulterode(BW,method,conn)
作⽤:终极腐蚀。
寻找⼆值图像BW的距离变换图的区域极⼤值(regional maxima)。
⽤于距离变换的距离默认为euclidean,连通性为8邻域。
7、regionprops统计被标记的区域的⾯积分布,显⽰区域总数。
函数regionprops语法规则为:STATS = regionprops(L,properties)
该函数⽤来测量标注矩阵L中每⼀个标注区域的⼀系列属性。
L中不同的正整数元素对应不同的区域,例如:L中等于整数1的元素对应区域1;L中等于整数2的元素对应区域2;以此类推。
返回值STATS是⼀个长度为max(L(:))的结构数组,结构数组的相应域定义了每⼀个区域相应属性下的度量。
Properties可以是由逗号分割的字符串列表、包含字符串的单元数组、单个字符串'all'或者'basic'。
如果properties等于字符串'all',则表4.1中的度量数据都将被计算;如果properties等于字符串'basic',则属性:'Area','Centroid'和'BoundingBox'将被计算。
表1就是所有有效的属性字符串。
表1 属性字符串列表
properties值度量图像区域的属性或功能
'Area'图像各个区域中像素总个数
'BoundingBox'包含相应区域的最⼩矩形
'Centroid'每个区域的质⼼(重⼼)
'MajorAxisLength'与区域具有相同标准⼆阶中⼼矩的椭圆的长轴长度(像素意
义下)
'MinorAxisLength'与区域具有相同标准⼆阶中⼼矩的椭圆的短轴长度(像素意
义下)
'Eccentricity'与区域具有相同标准⼆阶中⼼矩的椭圆的离⼼率(可作为特
征)
'Orientation'与区域具有相同标准⼆阶中⼼矩的椭圆的长轴与x轴的交⾓
(度)
'Image'与某区域具有相同⼤⼩的逻辑矩阵
'FilledImage'与某区域具有相同⼤⼩的填充逻辑矩阵
'FilledArea'填充区域图像中的on像素个数
'ConvexHull'包含某区域的最⼩凸多边形
'ConvexImage'画出上述区域最⼩凸多边形
'ConvexArea'填充区域凸多边形图像中的on像素个数
'EulerNumber'⼏何拓扑中的⼀个拓扑不变量——欧拉数
'Extrema'⼋⽅向区域极值点
'EquivDiameter'与区域具有相同⾯积的圆的直径
'Solidity'同时在区域和其最⼩凸多边形中的像素⽐例
'Extent'同时在区域和其最⼩边界矩形中的像素⽐例
'PixelIdxList'存储区域像素的索引下标
'PixelList'存储上述索引对应的像素坐标。