关闭

关于matlab中pcolor显示图片时的shading设置问题

标签: 图片matlabpcolorshadinginterp
4763人阅读 评论(0) 收藏 举报
分类:

在用pcolor进行显示图片时,要调用colormap,caxis,shading进行设置,才有可能还原图片本来的色彩

pcolor的用法是:

pcolor(N)

其中N是一个矩阵,矩阵的行列数表示图片有多少个色块。忘了说了,pcolor不是用像素来表示图片大小,而是用色块来表示。如果N是一个a*b的矩阵,表示这个图片长宽各位(a-1)*(b-1)个色块。

a = [1 2 3 4
    5  6 7 8
    9 10 11 12];

pcolor(a);
shading faceted;

这里写图片描述

colormap在我的上一篇博客中有介绍http://blog.csdn.net/whoispo/article/details/49913513

这里要说明的是:N矩阵的值无论有多大多小,都可以等比例变换到colormap中(1到colormap的行数)。fill中也有类似的功能,imshow没有这样的功能,也就是imshow的矩阵的值必须在colormap中。

caxis就表示N中颜色的范围,用[min,max]表示,对于N中的所有小于等于min的值,都映射到colormap的第一行,N中所有大于等于max的值,都映射到colormap的最后一行。一般我们用默认的值,也就是min是N中最小的值,max是N中最大的值。

最后说一下shading,shading有三种模式:

shading flat
shading faceted
shading interp

flat和faceted只是色块和色块直接显示不显示黑线的问题,没有太大区别。色块的颜色用的是N中较小索引的颜色,也就是第(i,j)个色块,用的是N(i,j)的颜色值。色块内部颜色一致,所以N中最后一行和最后一列都没有用到。

interp是一个插值方法。色块内部颜色不是一致的,第(i,j)个色块内部颜色,用的是第N(i,j), N(i,j+1), N(i+1,j), N(i+1,j+1)的点的颜色进行插值出来的。因此会用到N中的所有数。

好了理论部分说完了,就说一下使用时会出现的问题吧。

问题1:
问题描述:pcolor显示图片一团黑。

[X, map] = imread('corn.tif');
pcolor(X);
colormap(map);

这里写图片描述

问题原因:这是因为matlab默认采用shading faceted。图片中的黑色,实际上是很多黑线。你放大看一看就明白了。
这里写图片描述

问题解决方法:
把黑线去掉就行了,有两种方法

solution1:

[X, map] = imread('corn.tif');
h = pcolor(X);
colormap(map);
set(h, 'edgecolor', 'none');

solution2:

[X, map] = imread('corn.tif');
h = pcolor(X);
colormap(map);
shading flat;

这里写图片描述

问题2:图片显示还是不理想,不是原图。
问题原因:[X, map] = imread(‘corn.tif’) 返回的map不是pcolor要用到的colormap,而是imshow用的colormap。我上面说了,imshow是不对矩阵做等比例变换的,imshow的矩阵中0对应map中的第一行,1对应第二行,……

你可以这样试一试

[X, map] = imread('corn.tif');
imshow(X, map);

这里写图片描述

这样就很完满地显示了图片。但是这里我想用pcolor显示图片,不用imshow。这个问题的根本原因其实就是上面返回的map矩阵,后面许多都是没用的行,也就是都是0的行。这个问题对于imshow不会出现问题,但是对于pcolor就会出问题。

因此保留map中前面的非零行作为pcolor的colormap,就没有问题了。

[X, map] = imread('corn.tif');
map = map(1:128,:);
pcolor(X);
colormap(map);
shading flat;

这里写图片描述

看起来长宽有些不对啊,用axis equal可以了

[X, map] = imread('corn.tif');
map = map(1:128,:);
pcolor(X);
colormap(map);
shading flat;
axis equal;

这里写图片描述

其实上面的这些我认为都不是什么太大的问题,自己尝试一下就明白了。下面是我认为比较重要的问题。

我在试上面的例子的时候,用的是shading interp。因为我之前用的colormap都是系统自带的winter,summer之类的colormap,这些colormap变化是平滑的,所以认为用shading interp会使得图片颜色更加平滑,放大不会出现锯齿。结果:

[X, map] = imread('corn.tif');
map = map(1:128,:);
pcolor(X);
colormap(map);
shading interp;
axis equal;

这里写图片描述

我放大之后才想明白这是什么问题:
这里写图片描述

这个原因就是colormap不是平滑的,所以插值出的颜色也是不平滑的。上面是一个色块的4个角点,matlab会在中间进行插值,插值的颜色会索引colormap,但是你看一下这个colormap:

[X, map] = imread('corn.tif');
map = map(1:128,:);
pcolor(X);
colormap(map);
shading interp;
axis equal;

x = [0, 0, 1, 1];
y = [0, 1, 1, 0];
figure;
fill(x, y, [0, 0, 2, 2]);
colormap(map);

这里写图片描述

我想到了一个方法也许能解决这个问题。把这个colormap进行排序,把它变得平滑一些。因为colormap变化了,所以重新修改图片矩阵的数值。这样也许就能用shading interp了。

我现在还没有试这个方法,也许以后有时间再试。

其实如果不出问题的话,shading interp真是个好东西。用这个方法显示出的图片无论放大多少都不会出现锯齿模糊,就像矢量图片一样。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:254462次
    • 积分:3344
    • 等级:
    • 排名:第10444名
    • 原创:90篇
    • 转载:7篇
    • 译文:1篇
    • 评论:32条
    最新评论