1.图像数据
1.1什么是图像数据?
MATLAB® 的基本数据结构是数组,即实数或复数元素的有序集合。数组天然适合表示图像、实数值、颜色或强度数据的有序集合。(数组非常适合复数值图像。)
在 MATLAB 工作区中,大多数图像表示为二维数组(矩阵),其中矩阵的每个元素对应所显示图像的一个像素。例如,由 200 行和 300 列不同颜色的点组成的图像保存为一个 200×300 的矩阵。有些图像,如 RGB,需要三维数组,其中三个维度的第一个平面表示红色像素强度,第二个平面表示绿色像素强度,第三个平面表示蓝色像素强度。
这样的转换使用户可以像处理其他类型矩阵数据一样处理图形文件格式图像。例如,您可以使用普通的矩阵下标表示法从图像矩阵中取得一个像素:
I(2,15)
此命令返回图像 I
第 2 行第 15 列的像素值。
以下部分描述了不同数据和图像类型,并详细说明了如何读取、写入、使用和显示图形图像;如何在显示时修改图像的显示属性和纵横比;如何打印图像;如何转换图像的数据类型或图形格式。
1.2数据类型
MATLAB 数学支持三种不同的数值类用于图像显示:
-
双精度浮点数(
double
) -
16 位无符号整数(
uint16
) -
8 位无符号整数(
uint8
)
图像显示命令根据数据存入的数值类解释数据值。8 位和 16 位图像中介绍了 8 位和 16 位图像存储的内部工作原理的详情。
默认情况下,大多数数据都使用 double
类数组。这些数组中的数据存储为双精度(64 位)浮点值。所有的 MATLAB 函数和功能都能使用这些数组。
但是,对于以 MATLAB 函数支持的图形文件格式存储的图像而言,这种数据表现形式却并不理想。这样的图像中的像素数目可能非常巨大;如一个 1000×1000 的图像会有一百万个像素。由于至少要用一个数组元素表示一个像素,因此如果图像以 double
类存储,那么它至少需要 8 兆内存。
为了减小内存需求,您可以将图像数据存储在 uint8
和 uint16
这两类数组中。这些数组中的数据存储为 8 位或 16 位无符号整数。同样的数据,这些数组只需要 double
数组的八分之一或四分之一的存储容量。
MATLAB 输入函数读取任何一个支持的图形文件格式的最常使用的位深(每像素位数)。当数据存于内存中时,它可能存储为 uint8
、uint16
或 double
类的形式。
1.3支持的图像格式
MATLAB 命令可以读取、写入和显示以下几种图像的图形文件格式。对于 MATLAB 生成的图像,一旦显示一个图形文件格式的图像,该图像便会成为一个图像对象。MATLAB 支持如下图形文件格式以及其他格式:
-
BMP(Microsoft® Windows® 位图)
-
GIF(图形交换文件)
-
HDF (分层数据格式)
-
JPEG(联合图像专家组)
-
PCX(画笔)
-
PNG(可移植网络图形)
-
TIFF(标记图像文件格式)
-
XWD(X 窗口转储)
2.图像类型
2.1索引图像
索引图像由数据矩阵 X
和颜色图矩阵 map
组成。map
是一个 double
类的 m×3 数组,由 [0, 1] 范围内的浮点值组成。map
的每一行指定单一颜色的红、绿和蓝分量。索引图像使用像素值到颜色图值的“直接映射”。每个图像像素的颜色是以 X
中的对应值为索引求得的 map
中的值。因此 X
值必须是整数。值 1 指向 map
中第一行,值 2 指向第二行,以此类推。使用以下语句显示索引图像
image(X); colormap(map)
颜色图通常与索引图像一起存储,而且当您使用 imread
函数时,颜色图会随着索引图像一起加载。但您不仅限于使用默认的颜色图,您可以根据意愿选择任何一个颜色图。属性 CDataMapping 的说明描述了如何修改所使用映射的类型。
下一幅图展示了索引图像的结构。图像中的像素以整数表示,该整数是颜色图中存储的颜色值的指针(索引)。
图像矩阵和颜色图中值的关系取决于图像矩阵的类。如果图像矩阵是 double
类,那么值 1 指向颜色图中的第一行,值 2 指向第二行,以此类推。如果图像矩阵是 uint8
或 uint16
类,那么有个偏移 - 值 0 指向颜色图中的第一行,值 1 指向第二行,以此类推。在图形文件格式中使用偏移是为了使可支持的颜色数目达到最大。在上面的图像中,图像矩阵是 double
类。由于没有偏移,值 5 指向颜色图的第五行。
2.2灰度(强度)图像
灰度图像有时也称为强度图像,它是一个数据矩阵 I
,其中的值表示某一范围内的强度。灰度图像表示为单个矩阵,矩阵的每个元素对应一个图像像素。矩阵可能是 double
、uint8
或 uint16
类。尽管灰度图像很少与颜色图一起保存,但它仍需要用颜色图来显示。实际上,灰度图像被当做索引图像处理。
此图窗描绘了一幅 double
类的灰度图像。
要显示灰度图像,使请用 imagesc(“图像缩放”)函数,它允许设置强度图像的范围。imagesc
会调整图像数据以使用整个颜色图。使用 imagesc
的双输入形式显示灰度图像,例如:
imagesc(I,[0 1]); colormap(gray);
imagesc
的第二个输入参数指定了所需的强度范围。imagesc
函数通过将范围内的第一个值(通常是 0)映射到第一个颜色图条目,第二个值(通常是 1)映射到最后一个颜色图条目来显示 I
。这两者之间的颜色值在余下的颜色图颜色中呈线性分布。
尽管常规的做法是使用灰度颜色图显示灰度图像,但您也可以使用其他颜色图。例如,以下语句以不同深浅的蓝色和绿色显示灰度图像 I
:
imagesc(I,[0 1]); colormap(winter);
要将具有任意值范围的矩阵 A
显示为灰度图像,请使用 imagesc
的单参数形式。使用一个输入参数,imagesc
会将数据矩阵的最小值映射为第一个颜色图条目,最大值映射为最后一个颜色图条目。例如:这两个线条是等价的:
imagesc(A); colormap(gray)
imagesc(A,[min(A(:)) max(A(:))]); colormap(gray)
2.3RGB(真彩色)图像
RGB 图像,有时称为真彩色图像,以 m×n×3 数据数组形式存储,该数组定义了对应图像每个像素的红色、绿色和蓝色分量。RGB 图像不使用调色板。每个像素的颜色由存储在每个像素位置的颜色平面的红色、绿色和蓝色强度决定。图形文件格式将 RGB 图像存储为 24 位图像,其中红色、绿色和蓝色分量各占 8 位。这样便可能产生 1600 万种颜色。这种可复制现实中图像的精度由此被称为“真彩色图像”。
RGB MATLAB® 数组可以是 double
、uint8
或 uint16
类。在 double
类的 RGB 数组中,每个颜色分量都是 0 到 1 之间的值。颜色分量为 (0,0,0) 的像素显示为黑色,颜色分量为 (1,1,1) 的像素显示为白色。每个像素的三个颜色分量沿数据数组的第三个维度存储。例如像素 (10,5) 的红色、绿色和蓝色分量分别存储在 RGB(10,5,1)
、RGB(10,5,2)
和 RGB(10,5,3)
中。
要显示真彩色图像 RGB
,请使用 image 函数:
image(RGB)
下一幅图显示 double
类的 RGB 图像。
要确定 (2,3) 处像素的颜色,请查看存储在 (2,3,1:3) 的 RGB 三元组:假设 (2,3,1) 包含值 0.5176
,(2,3,2) 包含 0.1608
,(2,3,3) 包含 0.0627
。则 (2,3) 处的像素颜色是
0.5176 0.1608 0.0627
3. 8 位和 16 位图像
3.1 索引图像
双精度(64 位)浮点数是数值数据默认的 MATLAB® 表现形式。但为了降低使用图像的内存需求,您可以分别使用数值类 uint8
和 uint16
将图像保存为 8 位和 16 位无符号整数。数据矩阵为 uint8
类的图像称为 8 位图像;数据矩阵为 uint16
类的图像称为 16 位图像。
image
函数可以显示 8 位或 16 位图像,而无需将其转换为双精度。但如果图像矩阵为 uint8
或 uint16
,则 image
在解释矩阵值时会稍微有些不同。具体的解释取决于图像类型。
如果 X
的类是 uint8
或 uint16
,那么在被用作颜色图索引之前,它的值会偏移 1。值 0 指向颜色图中的第一行,值 1 指向第二行,以此类推。image 命令自动提供合适的偏移,从而无论 X
是 double
、uint8
还是 uint16
,显示方法都一样:
image(X); colormap(map);
uint8
和 uint16
数据的颜色图索引偏移是用于支持标准图形文件格式的,这种文件通常以索引形式与包含 256 个颜色的颜色图一起存储。偏移可以让您使用更节约内存的 uint8
和 uint16
数组操作和显示这种形式的图像。
由于偏移,必须加 1 将 uint8
或 uint16
索引图像转换为 double
类。例如:
X64 = double(X8) + 1;
or
X64 = double(X16) + 1;
反过来,减 1 可将 double
索引图像转换为 uint8
或 uint16
类:
X8 = uint8(X64 - 1);
or
X16 = uint16(X64 - 1);
3.2强度图像
double 图像数组范围通常是 [0, 1],而 8 位强度图像的范围通常是 [0, 255],16 位强度图像的范围通常是 [0, 65535]。使用如下命令以灰度颜色图显示 8 位强度图像:
imagesc(I,[0 255]); colormap(gray);
要将强度图像从 double
类转换为 uint16
类,首先乘以 65535:
I16 = uint16(round(I64*65535));
反过来,将 uint16
强度图像转换为 double
类之后,要除以 65535 :
I64 = double(I16)/65535;
3.3RGB 图像
8 位 RGB 图像的颜色分量是 [0, 255] 范围内的整数值,而非 [0, 1] 范围内的浮点值。颜色分量为 (255,255,255) 的像素显示为白色。image
命令会正确显示 RGB 图像,无论它的类是 double
、uint8
,还是 uint16
:
image(RGB);
要将 RGB 图像从 double
类转换为 uint8
类,首先乘以 255:
RGB8 = uint8(round(RGB64*255));
反过来,将 uint8
RGB 图像转换为 double
类之后,要除以 255:
RGB64 = double(RGB8)/255
要将 RGB 图像从 double
转换为 uint16
,首先乘以 65535:
RGB16 = uint16(round(RGB64*65535));
反过来,将 uint16
RGB 图像转换为 double
类之后,要除以 65535:
RGB64 = double(RGB16)/65535;
3.4 uint8 和 uint16 的数学运算支持
要在以下 MATLAB 函数中使用 uint8
和 uint16
数据,需要先将数据转换为 double
类型:
例如,如果 X
是一个 uint8
图像,那要将其数据转换为 double
类型便可使用以下语句:
fft(double(X))
在这种情况下,输出始终为 double
。
sum 函数返回与输入同一类型的结果,但它还提供了一个选项,可以使用双精度计算。
3.5 其他 8 位和 16 位数组支持
您可以对 uint8
和 uint16
数组执行其他几种操作,包括:
-
使用
save
和load
将uint8
和uint16
数组保存及加载到 MAT 文件。(请记住,如果要加载或保存图形格式文件图像,则必须使用 imread 和imwrite 命令代替。) -
使用 find 定位
uint8
和uint16
数组中非零元素的索引。但返回的数组始终为double
类。 -
关系运算符
3.6 将 8 位 RGB 图像转换为灰度图像
您可以对整型数据执行数学运算,这样可以直接转换图像类型,而无需先转换图像数据的数值类。
此示例将一个 8 位 RGB 图像读入 MATLAB 变量,并将其转换为灰度图像:
rgb_img = imread('ngc6543a.jpg'); % Load the image
image(rgb_img) % Display the RGB image
axis image;
注意
该图像是在太空望远镜科学研究所(由大学天文研究联合组织管理)支持下根据 NASA 合同 NAs5-26555 创建的,并得到 AURA/STScI 的复制许可。使用者可以免版权费获得由 AURA/ STScI 制作的图像的数字版本。感谢:J.P. Harrington 和 K.J. Orkowski(马里兰大学)以及 NASA。
基于 NTSC 标准合并 RGB 值,以此方式来计算单色亮度,这会将与眼睛敏感度相关的系数应用到 RGB 颜色:
I = .2989*rgb_img(:,:,1)...
+.5870*rgb_img(:,:,2)...
+.1140*rgb_img(:,:,3);
I
是具有整数值的强度图像,整数值范围从最小值零开始:
min(I(:))
ans = 0
到最大值 255:
max(I(:))
ans = 255
要显示图像,请使用 256 值的灰度颜色图。这样可以避免调整数据到颜色的映射,当使用不同尺寸的颜色图时通常需要进行此项调整。如果颜色图未包含每个数据值的项,则需使用 imagesc 函数。
现在使用灰度颜色图在新图窗中显示图像:
figure; colormap(gray(256)); image(I);
axis image;
其他的颜色范围从深色到浅色连续变化的颜色图也可生成可用的图像。例如,使用 colormap(summer(256))
生成经典的示波器样式。有关更多选项,请参阅 colormap。
brighten 函数可以让您增加或减少颜色图中的强度以补偿电脑显示差异或增强图像中模糊或明亮区域的可见性(其代价是另一端的颜色会有损失)。
3.7 图像类型和数值类摘要
下表总结了如何根据图像类型和数据类将数据矩阵元素解释为像素颜色。
图像类型 | 双精度数据 | uint8 或 uint16 数据 |
---|---|---|
索引 | 图像是由 [1, p] 范围内的整数组成的 m×n 数组。 颜色图是由 [0, 1] 范围内的浮点值组成的 p×3 数组。 | 图像是由 [0, p–1] 范围内的整数组成的 m×n 数组。 颜色图是由 [0, 1] 范围内的浮点值组成的 p×3 数组。 |
强度 | 图像是由经过线性调整以生成颜色图索引的浮点值组成的 m×n 数组。这些值通常的范围为 [0, 1]。 颜色图是由 [0, 1] 范围内的浮点值组成的 p×3 数组,通常为灰度颜色图。 | 图像是由经过线性调整以生成颜色图索引的整数组成的 m×n 数组。这些值的范围是 [0, 255] 或 [0, 65535]。 颜色图是由 [0, 1] 范围内的浮点值组成的 p×3 数组,通常为灰度颜色图。 |
RGB(真彩色) | 图像是由 [0, 1] 范围内的浮点值组成的 m×n×3 数组。 | 图像是由 [0, 255] 或 [0, 65535] 范围内的整数组成的 m×n×3 数组。 |