数学建模题目中有时会涉及到与数字图像有关的操作。在这类题目中,往往不会涉及到太多与数字图像处理相关的专业知识,但是要求程序员了解图像存储格式与常用基础操作等。
数字图像在计算机中以矩阵形式存储,通过一个或多个数字表示每个点的数值大小来控制每个像素点的颜色变化。常见的存储类型有灰度图像、RGB图像、二值图像、HSI图像等等。在这里我们着重介绍灰度图像与RGB图像。
灰度图像,顾名思义,是一种单色图像,只有纯白、纯黑、和254个不同深度大小的介于纯白、纯黑之间的灰色强度。对于灰度图,每个像素的亮度由且仅由一个数值来表示,通常数值范围在0到255之间,0表示黑、255表示白,其它值表示处于黑白之间的灰度,数字越小就越白。由于灰度图的存储方式易于理解,比较简单且涵盖了较多的图像信息,在不需要彩色信息时我们常将图像转化为灰度图像进行进一步操作。
二值图像,可以作为一种特殊的灰度图像来理解。他只有纯黑和纯白两种颜色,在计算机中每个像素点只有0、1两种取值可能。其中0表示黑色,1表示白色。
在中学学习美术时,我们都知道红、黄、蓝是三原色。通过这三个颜色的颜料画在一起叠加即可组合成任意一种颜色。在计算机里,也类似,但三原色不再是红、黄、蓝,而是红(R)、绿(G)、蓝(B)。在计算机里通过控制这三个颜色的量组合在一起,也可以合成任意一种颜色,于是就有了RGB图。RGB图像里,每个像素点由三个数值控制颜色,分别对应红、绿、蓝的分量大小。范围一般也为0~255之间,0表示这个颜色分量没有,255表示这个颜色分量取到最大值。例如:某RGB图中一个像素点的红、绿、蓝分量均为255,则根据光学叠加的理论可知,该点为纯白色。
HIS图像每个像素点由色调、饱和度、亮度决定。相比较之下,在数学建模类题目里并不常用。
相关实例与代码:
(1)假设matlab中有一张RGB图像存放于变量pic中,将其转化灰度图像。
newPic= rgb2gray('pic')
注:rgb2gray函数中的2,按照英文读作two,与to同音。这个函数读为rgb to gray,同理,其他图像存储类型转化函数也类似此函数。
(2)生成一幅128*128的RGB图像,该图像左上角为红色、右上角为蓝色、左下角为绿色,右下角为白色。
代码:
clear;clc;
picRed=zeros(128,128); %初始化RGB红色分量为0矩阵
picRed(1:64,1:64)=1;
picRed(65:128,65:128)=1; %令左上角、右下角的红色分量值为1
picGreen=zeros(128,128); %初始化RGB绿色分量为0矩阵
picGreen(65:128,1:64)=1;
picGreen(65:128,65:128)=1; %令左上角、右下角的绿色分量值为1
picBlue=zeros(128,128); %初始化RGB蓝色分量为0矩阵
picBlue(1:64,65:128)=1;
picBlue(65:128,65:128)=1; %令左上角、右下角的蓝色分量值为1
pic=cat(3,picRed,picGreen,picBlue); %合成RGB分量
imshow(pic);title('生成图像'); %显示图像
结果:
分析:
RGB图像存在红,绿,蓝三个颜色的通道。每个像素点由这三个通道的强度合成决定颜色。根据光学理论,当红色分量为255,其他分量为0时,呈现出红色;当绿色分量为255,其他分量为0时,呈现出绿色;当蓝色分量为255,其他分量为0时,呈现出蓝色。当三通道的颜色分量全为255时,显示出的颜色变为白色。同理,当三通道分量全为0时会显示黑色。
(1)图像读取——imread
Matlab自带参考文档里imread的用法介绍:
imread - Read image from graphics file
This MATLAB function reads a grayscale or color image from the file specified by
the string filename.
A = imread(filename, fmt)
[X, map] = imread(...)
[...] = imread(filename)
[...] = imread(URL,...)
[...] = imread(...,Param1,Val1,Param2,Val2...)
以其中一个常用的用法为例:
[...] = imread(filename)
其中filename为待读取图像文件名。若该图像不在matlab默认路径下并不与当前运行.m文件同目录时,需要手动添加路径名。
实例:
>> pic=imread('E:\1.jpg')
该代码将E盘下的1.jpg文件读入了matlab,用变量pic存储。
(2)图像显示——imshow
Matlab自带参考文档里imshow的用法介绍:
imshow - Display image
This MATLAB function displays the image I in a Handle Graphics figure, where I
is a grayscale, RGB (truecolor), or binary image.
imshow(I)
imshow(I,RI)
imshow(X,map)
imshow(X,RX,map)
imshow(filename)
imshow(___,Name,Value...)
imshow(gpuarrayIM,___)
imshow(I,[low high])
himage = imshow(___)
以其中一个常用的用法举例:
imshow(I)
其中,I为一个矩阵。该函数将把该矩阵所代表的图像显示出来。
注:并不是只有读取的图片所生成的变量才可以显示出图像,一般而言自己创建的、符合要求的矩阵均可通过该函数显示出其代表的图像。
(3)批量获取图像
在做题的时候,有时会需要读取一个文件夹里的所有图像。输入几十行imread的确是一种方法,不过非常低级。此时应使用批量读取图像的方法。
首先需学习dir函数,可以通过它获取当前文件夹下的文件名等信息。在此列出其几个常用用法:
filepath=dir('.') %列出当前目录下所有子文件夹和文件
filepath=dir('E:\matlab') %列出指定目录下所有子文件夹和文件
filepath=dir('*.m') %列出当前目录下符合正则表达式的文件夹和文件
变量filepath用于存放dir函数返回的文件信息。filepath变量不再是一个单纯的数值矩阵,而是一个面向对象的对象矩阵。每个对象包含name、date、bytes等属性。可通过filepath.name调用文件名。
有关正则表达式的知识在此不详细叙述,上述dir函数第三个用法中的正则表达式*.m表示所有文件名以.m结尾的文件。
以本校2017年新锐赛题目为例,将文件夹中20个图像统一格式、分别命名为1.jpeg~20.jpeg后,可用如下代码读取:
for i=1:20
imageName=strcat('附件1:英文纵切\',num2str(i-1),'.jpeg');
pic(:,:,i)=rgb2gray(imread(imageName));
end
此代码读取了文件夹中的20个数字图像文件并将其转化成了灰度图像存储于三维变量pic中。最高维数字代表第几张图。
若不事先手动统一名称,可用如下代码读取:
filepath=dir(‘*.jpeg’);
for i=1:size(filepath)
filename=strcat('附件1:英文纵切\’,filepath(i).name);
pic(:,:,i)=rgb2gray(imread(filename));
end
(1)水平镜像
代码:
I=imread('1.jpg'); % 读取图像1.jpg
subplot(1,2,1); % 画1行2列的子图的第一部分
imshow(I); % 显示图像
title('原图'); % 添加标题“原图”
I=double(I); % 将I图像中灰度值转化为double类型
H=size(I); % 将I图像大小赋值给H
I2(1:H(1,1),1:H(1,2))=I(1:H(1,1),H(1,2):-1:1); % 行坐标不变,列坐标反转
subplot(1,2,2); % 画1行2列的子图的第二部分
imshow(uint8(I2)); % 显示图像
title('水平镜像'); % 添加标题“水平镜像”
结果:
(2)大小变换——imresize
newPic=imresize(pic,[200,200])
此代码将存放于matlab中的图像变量转化成了200*200大小像素点的新图像,并存放于变量newPic中。
(3)旋转——imrotate
B=imrotate(A,angle,method,’loose’);
B=imrotate(A,angle,method,’crop’);
解释:angle为旋转的角度(默认逆时针旋转)
method为插值方式
loose:当图片旋转一定角度之后,若使得图片超出范围大小,不剪掉超出部分
crop:当图片旋转一定角度之后,若使得图片超出范围大小,剪掉超出部分
举例:
clear;
pic=imread('1.jpg');
pic_new1=imrotate(pic,45,'nearest','crop');
pic_new2=imrotate(pic,45,'nearest','loose');
subplot(1,3,1);
imshow(pic);
title('原图');
subplot(1,3,2);
imshow(pic_new1);
title('crop');
subplot(1,3,3);
imshow(pic_new2);
title('loose');
运行结果:
除此之外,数字图像还有多种滤波、频域变换、角点检测等知识,设计数字图像处理专业课知识且在数学建模中用的不多,在此不介绍。