浅析imageimagescimageshow的用法.docx

上传人:b****3 文档编号:27335062 上传时间:2023-06-29 格式:DOCX 页数:11 大小:1.02MB
下载 相关 举报
浅析imageimagescimageshow的用法.docx_第1页
第1页 / 共11页
浅析imageimagescimageshow的用法.docx_第2页
第2页 / 共11页
浅析imageimagescimageshow的用法.docx_第3页
第3页 / 共11页
浅析imageimagescimageshow的用法.docx_第4页
第4页 / 共11页
浅析imageimagescimageshow的用法.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

浅析imageimagescimageshow的用法.docx

《浅析imageimagescimageshow的用法.docx》由会员分享,可在线阅读,更多相关《浅析imageimagescimageshow的用法.docx(11页珍藏版)》请在冰豆网上搜索。

浅析imageimagescimageshow的用法.docx

浅析imageimagescimageshow的用法

浅析image,imagesc,imageshow的用法

浅析image,imagesc,imshow的用法

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...查看,另外在弹出的窗口colormapeditor中,可通过Tools->Standardcolormap来修改当前figure的colormap,这里是Matlab已经做好的一些colormap。

(1)当灰度图像转化成矩阵后,矩阵中的元素都介于[0,255]

下面我们结合具体实例来看看这三个函数的调用效果,并解释原因。

代码:

clearall;clc;closeall;

img=imread('lenna.bmp');

%mypictureisnamedlenna.bmpwhileyoursmaybenot

I=rgb2gray(img);

%Attention:

weusetheaxisofftogetridoftheaxis.

figure

(1),image(I);%equalstoimagesc(I,[164]);youcantryit.

colorbar,title('showbyimageinfigure1');axisoff;

figure

(2),imagesc(I);

%equalstoimagesc(I,[min(I(:

))max(I(:

))]);youcantryit.

colorbar,title('showbyimagescinfigure2');axisoff;

%colormap(gray)%usethisstatementyoucangetagrayimage.

figure(3),imshow(I),colorbar,title('showbyimshowinfigure3');

显示效果:

我们看到现象是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],而我只想显示[164],使用命令imagesc(I,[164])就可以了,如果你把上面程序中的imagesc(I)换成imagesc(I,[1,64]),那么figure2中的效果就和figure1中一样了,因为只是把[1,64]这个范围映射到色图,超过的都被认为是64。

关于映射,我截图Matlab中imagesc的help页给大家看看,这里要自己慢慢体会哦,使用imagesc(I)这种线性映射就可以用到整个色图从而将图像较好的显示出来,这就是figure2中的显示效果比figure1中好的原因。

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,[164])很相似,其实原理是一样的,第二个参数是一个向量,这个向量指定了矩阵中映射到颜色表的数的范围,也就是显示范围(Matlab里叫做displayrange)前面已经介绍了,Matlab中imshow的help中说如果采用imshow(I,[lowhigh])调用imshow的话而且你用[]代替[lowhigh]那么imshow会使用[min(I(:

))max(I(:

))]作为显示范围,也就说I中的最小值会显示成黑色,最大值会显示成白色,这其实就是整个范围的线性映射(没有削顶也没有削底),此时的imshow(I,[])函数就相当于imagesc(I);

为了说明imshow不仅具有image的功能也具有imagesc的功能,同时体会一下直接映射和线性映射的区别,我们来写一段小程序来测试一下,程序如下:

 

clearall;clc;closeall;

img=imread('lenna.bmp');

I=rgb2gray(img);

figure

(1),image(I);colormap(gray(256));

colorbar,title('showbyimageinfigure1');axisoff;

figure

(2),imagesc(I);colormap(gray(256));

%Wecanseethattheimageshowedinfigure

(2)isalittlebright

%thaninfigure

(1).

colorbar,title('showbyimagescinfigure2');axisoff;

%Whenweusetheimshow,wedonotneedtosetthecolormap,

%becausetheimshowsetthecolormaptogray(256)automatically.

figure(3),imshow(I),colorbar,title('showbyimshow(I)infigure3');

%Theeffectivenessinfigure(3)isthesameasinfigure

(1).

figure(4),imshow(I,[]),colorbar,title('showbyimshow(I,[])infigure3');

%Theeffectivenessinfigure(4)isthesameasinfigure

(2).

显示效果:

我们可以看出figure2中的图像比figure1中的图像要亮一些,而且,figure3中的显示效果和figure1中是一样的,figure4中的显示效果和figure2中是一样的,为什么会这样呢?

这是因为image(I)和imshow(I)是将I中的值直接作为colormap(gray(256))中的索引,也就是我所说的直接映射,我这里读到的索引图像矩阵也就是I中的是值的范围是[27,218],也就是说直接映射显示I,只用到的色图(colormap)上[27,218]范围的颜色(比如表示白色的索引255就没有用到)。

但线性映射就不一样了,imagesc(I),和imshow(I,[])采用的就是线性映射,线性映射把[27,218]按照线性算法(Matlab写的)映射到色图索引[1,256]然后再显示出来,这样整个色图的颜色都被用到了,这里也可以认为把[27,218]放大到[1,256],这就是figure2中显示效果比figure1中亮的原因。

小结:

直接映射和线性映射的区别在于映射到色图的数值范围,如果是[min(I(:

))max(I(:

))]就是线性映射,如果是0-255或者1-64或者0-1就是直接映射。

这个数值范围就叫做显示范围(displayrange)。

 

3、最后在说说image,imagesc,imshow在显示double型数据时的用法,

我们做图像处理就会对图像进行运算,使用uint8型数据精度不高,因为当运算结果超过255时会被认为是255,而负数就会被认为是0(注意在Matlab中数据默认采用double型(64位)进行存储和运算)所以,我们读到灰度图像后一般都会将图像转换成double型(I=double(I))然后再参与运算,运算的结果有正有负,也有小数,正的还可能超过255,比如我经过运算后的得到图像矩阵I,假如I的范围是[-187,152],当然你也可以用max(I(:

))和min(I(:

))去获取,这时怎么显示图像呢?

image,imagesc,imshow都可以用来显示double型数据的图像矩阵,主要区别如下:

image:

将double型数据取整(正数取整就是把小数部分舍掉)然后使用直接映射的方法按照颜色表显示。

imagesc:

这个函数很好,会对数据进行缩放再显示,也就是把显示范围自动设置成[min(I(:

))max(I(:

))],也就是线性映射。

imshow:

这个函数调用方式不同,显示效果也不同,如下:

imshow(I):

直接调用,因为当图像为double型时imshow函数会把显示范围设置成[0,1],这样小于0的就变成黑色了,大于1的就变成白色了,所以处理不当就会出现全白的情况。

imshow(I/(max(I(:

))):

针对直接调用imshow函数出现的问题,用max(I(:

))对图像矩阵进行归一下再显示,这样负数部分会变黑,正数部分还可以正常显示,但有一部分信息丢失了。

imshow(uint8(I)):

这种方式把I转化成uint8,负数会被归零,超过255的被置为255,而且小数也会被round(四舍五入),当参数为uint8型时,imshow函数把显示范围设置成[0,255],这样图像虽然也能显示出来,但与原始数据相比来说,丢掉很多信息,但有时可能却是想要的结果,这个要看具体情况。

imshow(I,[]):

这种方式就是把imshow的显示范围设置成[min(I(:

))max(I(:

))],也就是线性映射,相当于imagesc(I),colormap(gray(256))可以将整幅图像的信息显示出来。

综上所述,大家根据自己实际需要选用显示函数和对应的参数,这些是我自己研究学习的心得,表述难免有些疏漏,有发现严重错误的,可以给我留言,但可以给大家一个感性的认识,从云里雾里的困境里走出来。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 管理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1