Matlab中image、imagesc和imshow函数⽤法解析
原⽂转⾃:://blog.csdn/zhupananhui/article/details/16340345
1、显⽰RGB图像
相同点:这三个函数都是把m*n*3的矩阵中的数值当做RGB值来显⽰的。
区别:imshow将图像以原始尺⼨显⽰,image和imagesc则会对图像进⾏适当的缩放(显⽰出来的尺⼨⼤⼩)。
2、显⽰灰度图像概括是什么意思
沙河粉
说明:先搞明⽩什么是索引图像?(灰度图像也是索引图像的⼀种)
当⽤Matlab中的imread函数将图像读⼊并存⼊矩阵时,我们知道如果是RGB图像,得到是m*n*3的矩阵,但如果是索引图像,得到就是m*n的矩阵,这个矩阵的每个元素只是1个数值,那么怎么确定它的RGB值来显⽰图像呢?这就需要colormap 了,colormap是⼀个m*3的矩阵,每⼀⾏有3列元素构成RGB组,也就是⼀种颜⾊,⼀个m*3的colormap中有m中颜⾊,⽽索引图像存储的数值和colormap中的⾏号对应起来就可以像RGB那样显⽰图⽚了,⾄于对应⽅法,可以直接对应(⽐如1对应1,2对应2)也可以
是线性映射对应(⽐如[-128,128]映射到[1,256])。还有⼀点要说明的是,默认情况下每⼀个figure都有且仅有⼀个colormap,⽽且默认的是 jet(64),可在figure窗⼝通过,edit-&查看,另外在弹出的窗⼝colormap editor 中,可通过Tools->Standard colormap来修改当前figure的colormap,这⾥是Matlab已经做好的⼀些colormap。
(1)当灰度图像转化成矩阵后,矩阵中的元素都介于[0,255],下⾯我们结合具体实例来看看这三个函数的调⽤效果,并解释原因。代码:
显⽰效果:
我们看到现象是image 和imagesc 显⽰出来是彩⾊的,只有imshow显⽰出来是灰度图像,为什么会出现这种情况呢?还记得前⾯所说的吗,索引图像是矩阵和colormap配合起来显⽰的,⽽每个figure默认使⽤的colormap 是jet(64),⽽不
是gray(gray和gray(64)是⼀样的),这个jet(64)就使得figure1和figure2中显⽰出来时是彩⾊的,当然你也可以修改当卷面分析
前figure的colormap使⽤colormap(gray)(使⽤64个等级的灰度⾊图),或者colormap(gray(256))(使⽤256个等级的灰度⾊图,这就是调⽤imshow函数时使⽤的colormap,后⾯有讲解)。⽽figure3为什么会是灰度图像呢,这是因为当调蔬菜保鲜
宝宝绿便
⽤imshow来显⽰索引图像时,这个函数就会把当前的figure的colormap设置成gray(256),这下明⽩为什么会出现这种情况了吧。我们再仔细观察⼀下figure1和figure2会发现,figure2中⼈物的轮廓显⽰的还算可以,⽽figure1中则出现了⼤⾯积的红⾊的区域,⼈物的轮廓被抹掉了很多。
维特根斯坦为什么会出现这样的情况呢?这就要说说索引图像矩阵中的数(以下简称矩阵中的数)和colormap中的索引(index)的对应关系了。
image:这个函数,直接把矩阵中的数当做索引值(我称为直接映射),例如colormap中索引为1的是
颜⾊RGB1,索引为2的是颜⾊RGB2,……,索引为64的是颜⾊RGB64。那么矩阵中为1的数就显⽰成颜⾊RGB1,矩阵中为2的数就显⽰成颜⾊RGB2,……,矩阵中为64的数就显⽰成颜⾊RGB64,值得注意的是当矩阵中的数⼩于1时,此时该数也将被显⽰成颜⾊RGB1,同样,⽽矩阵中⼤于64的数将被显⽰成颜⾊RGB64(类似于信号处理⾥⾯的限幅,也可以认为是削顶或者削底了),这下我们就能明⽩为什么figure1中会出现⼤⾯积的红⾊区域,这说明这些地⽅的数值都⼤于等于64。
imagesc: 在figure2中我们⽤imagesc来显⽰图像与figure1相⽐能较好的显⽰出来,同样我们也得搞明⽩调⽤imagesc时矩阵的数和colormap中索引的对应关系,与image不同的是imagesc采⽤的不是直接映射⽽是线性映射,⾄于什么是线性映射,我粗略的说⼀下,⽐如把区间A = [0,a]映射到区间B = [0,b]我们对A中的元素做A/a*b就可以了,矩阵的数到colormap索引的线性映射⼤概就是这样,Matlab会⾃动获取矩阵中数的最⼩值和最⼤值,并把区间[Cmin,Cmax]映射到colormap的[最⼩索引,最⼤索引]⽐如[1,64],然后再根据这个对应关系把图像显⽰出来,具体的算法细节是Matlab确定的,当然也可以⾃⼰指定显⽰范围,⽐如⼀副索引图像I范围为[27,218],⽽我只想显⽰[1 64 ],使⽤命令imagesc(I,[1 64])就可以了,如果你把上⾯程序中的imagesc(I)换成imagesc(I,[1,64]),那么figure2中的效果就和figure1中⼀样了,因为只是把[1,64]这个范围映射到⾊图,超过的都被认为是64。关于映射,我截图Matlab中imagesc的help页给⼤家看看,这⾥要⾃⼰慢慢体会哦,使⽤imagesc(I)这种线性映射就可以⽤到整个⾊图从⽽将图像较好的显⽰出来,这就是figure2中的显⽰效果⽐figure1中好的原因。
梦想x计划imshow:调⽤这个函数会把当前figure的colormap设置成gray(256),这个前⾯也有提到,我们先讨论矩阵元素是uint8型(范围:0~255,整数,⼀般使⽤imread和 rgb2gray返回的都是uint8型的),同样我们也要搞明⽩矩阵中的数和colormap中颜⾊索引的对应关系,imshow的功能是⽐较全的,它即可使⽤像image那样的直接映射,也可使⽤像imagesc那样的线性映射,当我们使⽤imshow(I),即只有⼀个矩阵作为参数,这时采⽤的是直接映射,⽐如矩阵中元素0就显⽰成colormap中索引为1的颜⾊也就是⿊⾊,矩阵中元素255就显⽰成colormap中索引为256的颜⾊也就是⽩⾊,(注意:uint8范围是0~255,⽽gray(256)的索引是1:256,当然这些我们只要了解就可以了,编程并不会⽤到,因为这些对应的细节Matlab已经帮我们做好了)如果这样调⽤imshow(I,[ ]),此时矩阵中的数和颜⾊表就是线性映射,为什么会这样,我解释⼀下,我们看这种调⽤⽅式和imagesc(I,[1 64])很相似,其实原理是⼀样的,第⼆个参数是⼀个向量,这个向量指定了矩阵中映射到颜⾊表的数的范围,也就是显⽰范围
(Matlab⾥叫做display range)前⾯已经介绍了,Matlab中imshow的help中说如果采⽤imshow(I, [low high])调⽤imshow的话⽽且你⽤[ ]代替[low high]那么imshow会使⽤[min(I(:)) max(I(:))]作为显⽰范围,也就说I中的最⼩值会显⽰成⿊⾊,最⼤值会显⽰成⽩⾊,这其实就是整个范围的线性映射(没有削顶也没有削底),此时的imshow(I,[ ])函数就相当于imagesc(I);
为了说明imshow不仅具有image的功能也具有imagesc的功能,同时体会⼀下直接映射和线性映射的区别,我们来写⼀段⼩程序来测试⼀下,程序如下:
刘家长
显⽰效果: