在之前就有提到的老师叫做的大坑,可其实完全不知道该怎么写,这个系列不知道能做到哪里,东西做还是会做完,可是系列可能未来会坑掉。嘛,有一期是一期的东西,那么这个系列目前应该算是记录自己的学习轨迹和笔记了,全当放飞自我了_(:з)∠)_

既然要用Matlab来表情合成,大概一定要先搞懂Matlab的图像是怎么储存和能怎么处理吧。

Matlab的图像

之前我们知道Matlab的基本数据结构是矩阵,矩阵天生就很适合用来表示又二维像素组成的电子图像, 矩阵中的每一个元素可以作为图像的一个像素被表示。

然后我们又知道平时我们看的图像有索引彩色图,灰度(强度)图和RGB真彩色图两种,其中索引图由数据矩阵和查找表两个矩阵组成;灰度图只要用一个二维矩阵就可以表示;RGB图由于需要储存三条色彩通道的数据,所以需要三个二维矩阵来表示。然后由此我们只需要将图像转换为矩阵,就可以很方便地取到对应像素值的数据。

那么知道了图像可以表示为矩阵,我们又知道矩阵的元素也有自己的元素数据类型, 在Matlab中图像可以用三种数据表示,double型,uint16型(16位无符号整数),uint8型(8位无符号整数),Matlab可以支持任意深度的图像,不过大多数时候Matlab使用的图像是uint8的八位深度,不过例如png和tiff则是十六位的,而对于索引图像则固定是double的。由于被解码出来储存在矩阵中的图像是无压缩的,若使用double型的话,图像需要占据很大的空间,可是这样大的空间占据很多时候没什么用,所以我们默认使用uint8来储存图像,这会造成损失,但是不太影响。这里我们储存每个像素使用的位数称为位深(深度)。

知道了储存的原理后必然开始担心格式支持的问题,不用担心,主流的图像格式Matlab都是支持的,例如 png,jpeg,bmp,gif,tiff 等等都是支持的。基础都目标了就该知道,怎么读取图像呢?

Matlab的图像读取写入

首先是我们最关心的图像读取,在Matlab中我们使用imread()函数来读取加载图像进入工作区,加载后生成的矩阵类型与上一条中说到的规则是一样的,然后我们再使用imwrite()可以重新把矩阵写回文件中。

其中对于imread()函数,参数主要可是直接是文件名表示直接读取,对于有多张图像的文件(gif之类)可以带上index第二参数读取特定张的图像。

而对于imwrite()函数,则主要用到的参数是:第一个参数是矩阵的名称,第二个参数是将要写入的文件名。后面的第三第四参数可选,是规定了输出图像的规格(位深之类),默认情况下位深是8。

然后对于图像的裁剪,我们可以使用imcrop()函数或者直接提取图像矩阵的需要区域然后重新导出。

而对于图像本身信息的读取,可以使用imfinfo()函数,参数是文件名。这会返回图像的详细参数。

然后这里我使用的测试图像是封面上的莱娜图(Lenna),这是图像处理领域最常用的标准测试图,在下面使用imread()读取她(被压缩为200*200)。

Matlab的图像的显示

在上一步中我们把图像读取变成了密密麻麻的矩阵,然后怎么将其显示出来呢?有三种函数,image(),imagesc()和imshow()。

这三个函数对于RGB真彩色图片的效果是相同的,区别只在于imshow()显示的图像在一开始是与屏幕的像素1:1的,而其他两个得到的图像会被缩放为某个大小的正方形。如果需要将图像变为正常的长宽比可以使用命令axis image

而当在处理索引图像或灰度图像时,三个函数便产生了区别。首先我们知道索引图是由数据矩阵和查找表构成的。而image函数默认是直接将索引图的数据矩阵取8位也就是直接映射到0-63的索引区间内,于是那些大于等于64的数据便会变为黑色(超出范围)。而对于imagesc函数,imagesc函数将会取数据矩阵的最高和最低数据,然后重新生成均匀的线性映射,并依据位数进行舍入处理,所以做出的效果将会比image函数好很多。再对于imshow函数,这个函数的做法是将查找表当作0-255的灰度表然后取数据图中的数据进行映射,对于索引图这样的做法会让其变为灰度图。不过对于这个问题,我们在生成绘图窗口(figure)后指定对应查找表来正确显示索引图。

综上最好是使用imagesc函数来显示图片。

Matlab的图像简单处理

从上面来看有时我们就会想,RGB图太方便了。很简单,对于索引图像,我们只要使用ind2rgb(X,map)函数就可以将矩阵X配合它的查找表map就可以生成RGB图返回了。其中X矩阵的数据类型就是将要得到的RGB矩阵中元素的数据类型。而对于灰度图,我们直接使用RGB = cat(3,I,I,I);代码将原图的三个副本进行串联就可以得到灰度的RGB图了。

得到了RGB图后,若图像是彩色的,我们又会想将其转换为灰度图,因为彩色在很多图像处理中并没有很大作用却又占空间增加复杂性。其中最简单的一种方法是使用NTSC的标准将RGB值合并为灰度值,这是对应的代码,其中rgb_img就是刚才得到的RGB图像矩阵:

I = .2989*rgb_img(:,:,1)+.5870*rgb_img(:,:,2) +.1140*rgb_img(:,:,3);

于是这样我们便又得到了灰度图,在显示这个图像矩阵时为了简便还是建议使用imagesc函数,这样不用去考虑灰度是否覆盖了查找表,要注意指定新的灰度查找表才能得到灰度图(当然可以通过改变查找表来达到不同的效果)。

而要得到查找表(Matlab中称为颜色图),可以使用colormap函数进行创建或直接改变。

没啥好记的,充个场面,内容基本都是官方文档“图像”

里面的内容,配合一些着看了一些函数的文档和网上查了下资料。

那么,该歇了。