第3章 MATLAB图像处理基础 本章主要介绍利用MATLAB实现数字图像处理的基本操作,为后续更好地学习并仿真各种图像处理算法奠定基础 。本章主要包括以下内容: 图像文件的读取与显示、图像类型转换、色彩空间转换、视频文件的读写等。 3.1图像文件的读取与显示 图像文件的读取与显示是进行图像处理的第一步。本节介绍MATLAB提供的相应函数及其实现。 3.1.1图像文件信息读取 MATLAB提供了函数imfinfo和imageinfo来获取图像文件的信息。 1. 函数imfinfo 函数imfinfo用于返回一个结构体数组,以存储图像文件的相关信息。其调用格式如下。 INFO=imfinfo(FILENAME,FMT): FILENAME是当前路径下或指定了路径的图像文件的文件名; FMT是文件的扩展名; INFO是一个结构体,包含了文件中的图像信息,不同格式的文件最终得到的INFO所包含的字段不同,但其前9个字段一致,如表31所示。如果FILENAME是包含不止一幅图像的文件,如TIFF、HDF、ICO、GIF或CUR等,则INFO是一个结构体数组,数组中每一个元素是一个包含一幅图像信息的结构体,如INFO(2)是文件中第2幅图像的信息。 表31imfinfo函数返回的结构体数组基本内容 INFO结构体字段名含义 Filename文件名称,包含文件所在路径 FileModDate文件最近修改或者下载的日期和时间(日月年 时: 分: 秒) FileSize文件大小,整数,单位: 字节 Format文件格式或扩展名,由FMT指定 FormatVersion文件格式版本号 Width 图像的宽度,整数,单位: 像素 Height 图像的高度,整数,单位: 像素 BitDepth 图像文件中每一个像素存储所占位数,整数 ColorType 图像类型,包含但不限于: 'truecolor'RGB图像、'grayscale'灰度图像、'indexed'索引图像 2. 函数imageinfo 函数imageinfo用于创建一个图像信息工具,用于显示当前figure(图形图像窗口)中图像的信息,包括宽、高、图像类型等。其调用格式如下。 (1) imageinfo(H): 基于H创建图像信息工具,H为figure、坐标系或图像对象的句柄。 (2) imageinfo(FILENAME): 根据文件名创建图像信息工具,图像不一定要在figure窗口显示。 (3) imageinfo(INFO): 使用INFO结构体创建图像信息工具。 (4) imageinfo(HIMAGE,FILENAME): 创建图像信息工具,显示被HIMAGE句柄指定的图像基本属性和FILENAME指定的图像文件的元数据。 (5) imageinfo(HIMAGE,INFO): 创建图像信息工具,显示被HIMAGE句柄指定的图像基本属性和结构体INFO指定的图像文件的元数据。 (6) HFIGURE=imageinfo(…): 创建图像信息工具,并返回图像信息工具窗口句柄。 【例31】读取图像文件信息并显示查看。 程序如下: clear,clc,close all; imageinfo('flower.jpg');%创建图像信息工具,显示flower.jpg图像元数据 h=imshow('flower.jpg');%显示图像,并返回figure窗口句柄 info1=imfinfo('cameraman.jpg'); %获取cameraman.jpg图像信息,返回结构体数据info1 hfigure=imageinfo(h,info1); %创建图像信息工具,显示flower.jpg的基本属性和cameraman.jpg的元数据 info1%在命令窗口输出结构体info1的数据 info2=imfinfo('water.gif');%获取water.gif图像信息,返回结构体数据info2 info2(2)%在命令窗口输出water.gif文件中第2幅图像的信息 程序运行,创建的图像信息工具如图31所示。 图31创建的图像信息工具 在命令窗口显示INFO结构体数据,ans为water.gif文件中第2幅图像的信息。 Info= struct with fields: Filename: 'E:\MATLAB\3 Chapter\cameraman.jpg' FileModDate: '04-Mar-2013 10:51:36' FileSize: 31761 Format: 'jpg' FormatVersion: '' Width: 256 Height: 256 BitDepth: 24 ColorType: 'truecolor' FormatSignature: '' NumberOfSamples: 3 CodingMethod: 'Huffman' CodingProcess: 'Sequential' Comment: {} Orientation: 1 Software: 'ACD Systems Digital Imaging' DateTime: '2013:03:04 10:51:32' YCbCrPositioning: 'Centered' DigitalCamera: [1×1 struct] ans = struct with fields: Filename: 'E:\MATLAB\3 Chapter\water.gif' FileModDate: '05-Nov-2008 08:57:36' FileSize: 95308 Format: 'GIF' FormatVersion: '89a' Left: 1 Top: 57 Width: 240 Height: 264 BitDepth: 8 ColorType: 'indexed' FormatSignature: 'GIF89a' BackgroundColor: 215 AspectRatio: 0 ColorTable: [256×3 double] Interlaced: 'no' DelayTime: 13 TransparentColor: 256 DisposalMethod: 'LeaveInPlace' 3.1.2图像文件数据读取 MATLAB主要利用imread函数实现图像文件数据的读取,为适应不同的文件格式,有不同的调用格式。 (1) A=imread(FILENAME,FMT): 从FILENAME指定的文件中读取图像数据。FILENAME是当前路径下或指定了路径的图像文件的文件名; FMT是文件的扩展名,可以使用IMFORMATS函数查看当前扩展名支持的格式; 返回值A是包含图像数据的矩阵,对于灰度图像,A为M×N的矩阵; 对于真彩色图像,A为M×N×3的矩阵; 对于包含使用CMYK颜色模型图像的TIFF文件,A为M×N×4的矩阵。 (2) [X,MAP]=imread(FILENAME,FMT): 读取索引图像数据,图像数据存放于X中,颜色映射表数据自动归一化到[0,1],存放于MAP中。 (3) […]=imread(FILENAME): 根据文件内容推断图像类型,并根据待读取图像数据的类型选择格式1或格式2。 (4) […]=imread(URL,…): 读取来自网络的图像文件。 在MATLAB中,图像数据类型有uint8、uint16、double、logical、single等,在灰度级别的表示方面,uint8型数据用0~255表示,uint16型数据用0~65535表示,double型数据用0~1表示,logical型数据用0、1表示。 【例32】读取不同类型图像,并查看各返回值。 程序如下: clear,clc,close all; Image1=imread('flower.bmp'); Image2=imread('bird.bmp'); [Image3,MAP3]=imread('pig.bmp'); subplot(131),imshow(Image1),title('彩色图像'); subplot(132),imshow(Image2),title('二值图像'); subplot(133),imshow(Image3,MAP3),title('索引图像'); 程序运行结果如图32所示。在MATLAB工作窗口工作区,查看各变量,取值情况如表32所示,可以看出彩色图像数据为M×N×3的uint8矩阵,二值图像数据为M×N的logical矩阵,索引图像的颜色映射表为取值为0~1的P×3矩阵,P为颜色数目。 图32采用imread函数读取不同类型图像 表32例32各变量取值 名称尺寸数 据 类 型最小值最大值 Image1264×352×3uint80255 Image2359×304logical Image3182×268uint8188 MAP3256×3double01 (5) […]=imread(…,IDX): 读取包含多幅图像的ICO、CUR文件中的某一幅,IDX是整型数据,指定读取图像中的第几幅图像,默认情况下,读取文件中第1幅图像。 (6) [A,MAP,ALPHA]=imread(…): 返回图标文件的AND模板,用于处理透明像素信息。 (7) […]=imread(…,IDX): 读取动图GIF文件中的一幅或多幅图像,IDX取整数或整数向量,如3或者1:5,分别指读取第3幅或前5幅图像; IDX默认情况下,读取全部图像数据。 (8) […]=imread(…,'Frames',IDX): 读取动图GIF文件中的一幅或多幅图像,IDX可以取'all',则所有帧全部被读取,并且按照在文件中的顺序返回。由于GIF 的文件结构,特定帧的读取也需要读取所有帧数据,因此,IDX使用指定向量或'all'读取所有帧数据,比采用循环读取多帧运算速度快。 (9) […]=imread(…,REF): 读取HDF文件中的一幅图像,REF指定所读取图像的参考编号,但在HDF文件中,参考编号顺序和图像顺序未必一致,可以使用imfinfo函数获取某一幅图像的参考编号; REF默认情况下读取第1幅图像。 (10) […]=imread(…,'BackgroundColor',BG): 读取PNG图像文件,将透明像素与BG中的指定颜色合成。BG取 'none',则不合成; 如果输入的图像是索引图像,BG取[1,P]范围的整数,其中P为颜色数目; 如果输入的图像是灰度图像,BG取[0,1]范围的值; 如果输入图像是彩色图像,BG是三维向量,其元素取值范围为[0,1]。 (11) [A,MAP,ALPHA]=imread(…): 假如存在透明信息,则返回ALPHA通道数据,否则ALPHA为[]。这种格式下,BG默认值为'none'; 如果PNG文件包含了背景色,则BG默认值为背景色; 如果不使用ALPHA通道并且文件不包含背景色,对于索引图像,BG默认值为1; 灰度图像,BG默认值为0; RGB图像默认值为[0 0 0]。如果'BackgroundColor'被指定,则ALPHA数据为[]。灰度图像或真彩色图像MAP数据为[]。 【例33】采用imread函数的不同调用格式读取ICO、GIF、PNG图像,并查看各返回值。 程序如下: clear,clc,close all; Image1=imread('weather.ico',8); %读取ICO文件的第8幅图像 [Image2,MAP2]=imread('water.gif',2);%读取GIF文件的第2幅图像 [Image3,MAP3]=imread('water.gif');%读取GIF文件的全部帧 [Image4,MAP4]=imread('water.gif','frames','all');%读取GIF文件的全部帧 Image5=imread('fish.png');%读取PNG图像,透明像素与默认值合成 [A,MAP5,ALPHA] = imread('fish.png','BackgroundColor',[0 1 0.3]); %读取PNG图像,透明像素与指定值合成 subplot(221),imshow(Image1),title('weather.ico第8幅图像'); subplot(222),imshow(Image2,MAP2),title('water.gif第2幅图像'); subplot(223),imshow(Image5),title('透明像素与默认的黑色合成'); subplot(224),imshow(A),title('透明像素与指定颜色合成'); 程序运行结果如图33所示。 图33采用imread函数读取ICO、GIF、PNG图像 在MATLAB工作窗口工作区,查看各变量,取值情况如表33所示。 表33例33各变量取值 名称尺寸数 据 类 型最小值最大值 Image148×48×3uint80233 Image2320×240uint80254 Image34Duint80254 Image44Duint80254 Image5128×128×3uint80255 A128×128×3uint80255 ALPHA[]double MAP2256×3double00.9843 MAP3256×3double00.9843 MAP4256×3double00.9843 MAP5[]double 可以看出Image3和Image4都是读取了GIF图像的所有帧,即默认IDX和IDX设为'all'效果一样。由于GIF图像最多为256色,读取图像时,需要同时读取颜色映射表信息,全部帧共用同一颜色映射表,因此MAP2、MAP3和MAP4是一样的。 (12) […]=imread(…,'Param1',value1,'Param2',value2,…): 设定参数读取图像,JPEG 2000图像读取时参数如表34所示,TIFF图像读取时参数如表35所示。 表34JPEG 2000图像读取时参数表 参数取值及含义 ReductionLevel一个非负整数,指定图像分辨率的降低。若为L,则图像分辨率降低一个因子2L。默认值为0,代表分辨率不减少。imfinfo函数返回的结构体中,WaveletDecompositionLevels 字段指定分解级别,限制ReductionLevel的取值 PixelRegion{ROWS,COLS}。imread函数返回由ROWS和COLS中的值作为边界所指定的子图像。行列数都是二维向量,表示从1开始的索引[START STOP]。如果ReductionLevel大于0,则ROWS和COLS是在尺寸减小的图像上的坐标 V79Compatible逻辑值: 为真,返回的图像转换为和imread早期版本一致的灰度或RGB图像,采用本参数转换YCC图像为RGB图像。默认值为假 表35TIFF图像读取时参数表 参数取值及含义 Index正整数,指定TIFF图像文件中哪一幅图像被读取 Info函数imfinfo输出的结构体数组。当读取包含多幅图像的TIFF文件时,采用Info作为参数将提高imread函数在文件中定位要读取图像的速度 PixelRegion{ROWS,COLS}。imread函数返回由ROWS和COLS中的值作为边界所指定的子图像。行列数为二维或三维向量,二维向量表示从1开始的索引[START STOP]; 三维向量表示从1开始的索引[START INCREMENT STOP],允许图像下采样 各种不同格式的文件在用imread函数读取时,有像素位数、对应文件类型的细致区别,如有需要可以查阅MATLAB帮助文件。 【例34】采用imread函数读取JPEG、TIFF图像,并查看各返回值。 程序如下: clear,clc,close all; Image1=imread('football.jpg'); Image2=imread('autumn.tif'); Image3=imread('autumn.tif','PixelRegion',{[100 200],[10 200]}); %读取TIFF图像中的子图像 subplot(131),imshow(Image1),title('JPEG图像'); subplot(132),imshow(Image2),title('TIFF原图像'); subplot(133),imshow(Image3),title('TIFF子图像'); 程序运行结果如图34所示,Image3仅为Image2中的一部分。在MATLAB工作窗口工作区,查看各变量,取值情况如表36所示。8位的JPEG文件,无论采用有损还是无损压缩方式,读出来的数据类型都为uint8型数据,如Image1。Image3的宽高正如程序中设定的一样。 图34采用imread函数读取JPEG、TIFF图像 表36例34各变量取值 名称尺寸数 据 类 型最小值最大值 Image1256×320×3uint86255 Image2206×345×3uint81248 Image3101×191×3uint816176 3.1.3图像的显示 MATLAB主要利用imshow和imtool函数实现图像的显示,此外,也提供了适应一些特殊需求的显示函数,如image、imagesc、montage和imshowpair。 1. 函数imshow 函数imshow用于在通用的图形图像窗口显示图像,自动设置图像窗口、坐标轴和图像属性。根据图像源文件的不同,有如下多种调用格式。 (1) imshow(I): 显示灰度图像I。 (2) imshow(I,[LOW HIGH]): 指定灰度级范围[LOW HIGH]来显示灰度图像I,低于等于LOW值的显示为黑,高于等于HIGH值的显示为白,默认按256个灰度级显示。若未指定LOW和HIGH值,则将图像中最低灰度显示为黑色,最高灰度显示为白色。 (3) imshow(RGB): 显示真彩色图像RGB。 (4) imshow(BW): 显示二值图像BW,像素值为0显示黑色,像素值为1显示白色。 (5) imshow(X,MAP): 显示索引图像,X为索引图像的数据矩阵,MAP为其颜色映射表。 (6) imshow(FILENAME): 显示FILENAME指定的图像。此格式下,imshow通过调用imread或dicomread从文件FILENAME中读取图像数据。因此,要求图像能够被imread或dicomread读取。若文件包括多帧图像,则显示第一帧,且文件必须在当前目录或MATLAB路径下。 (7) HIMAGE=imshow(…): 返回创建的图像对象句柄。 (8) imshow(…,PARAM1,VAL1,PARAM2,VAL2,…): 显示图像时指定相关参数及其取值,参数如表37所示。 表37imshow函数参数表 参数取值及含义 Border一个字串,指明图像在figure窗口显示时是否显示边界,可取'tight' 和'loose',默认情况下取'loose' ColormapM×3实数矩阵,设置要显示图像的颜色映射表,也可用来将灰度图像进行伪彩色显示 DisplayRange二维向量[LOW HIGH],指定灰度范围显示灰度图像。在图像数据已经读取后显示,可以省略参数名,如imshow(I,[LOW HIGH]); 若imshow中采用FILENAME指定文件,则不能省略。根据图像I的值取整数或浮点数 InitialMagnification数值,或字串'fit',指定图像初始显示比例: 如100,则图像以100%比例显示; 若为'fit',以适合窗口的比例显示整幅图像。若图像太大不能显示完全,将进行警告并以适合屏幕的最大比例显示图像。默认为100。采用坐标定位显示时,将忽略指定的数值,取'fit'值; 使用'Reduce'参数时,只能取'fit'值 Reduce逻辑值,指明是否对文件FILENAME中的图像进行下采样。仅适用TIFF图像,用以显示大图像的概貌 Parent指向图像对象的父对象的坐标系句柄 XData二维向量,用以建立非默认的空间坐标系统 YData二维向量,用以建立非默认的空间坐标系统 【例35】采用imshow函数的不同形式显示图像。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('girl.bmp'); [Image2,MAP2]=imread('pig.bmp'); figure,imshow(Image2,MAP2,'InitialMagnification',40),title('显示比例为40%'); figure,imshow(Image2,MAP2,'Border','tight'),title('figure中不显示边界'); figure, subplot(221),imshow(Image1),title('默认显示'); subplot(222),imshow(Image1,[50 100]),title('指定灰度范围显示'); subplot(223),imshow(Image1,'Colormap',MAP2),title('用颜色映射表MAP2显示'); subplot(224),imshow(Image2,'XData',[100 300],… 'YData',[200 280]),title('建立新坐标系统显示'); 程序运行结果如图35所示。 图35imshow函数显示图像 2. 函数imtool 1) 图像工具窗口 在命令窗口输入指令: >> imtool 打开一个空的图像工具窗口,可以通过选择菜单File下的Open或者Import From Workspace选项选择一幅图像显示,如图36所示。在窗口内,可以通过菜单Tools下的选项,实现对图像显示比例的放大、缩小,对图像进行剪切、对比度调整、选择颜色映射表等处理。图像工具窗口的部分功能如图37所示。 图36imtool函数显示图像 图37图像工具窗口部分功能示意图 2) 函数imtool的调用 函数imtool也可以如同imshow函数一样,直接调用来显示具体图像。 (1) imtool(I): 显示灰度图像I。 (2) imtool(I,[LOW HIGH]): 指定灰度级范围显示灰度图像I,低于等于LOW的灰度显示为黑色,高于等于HIGH的灰度显示为白色,中间的按灰度级别依次显示; 不指定LOW和HIGH,则将图中的最低灰度显示为黑色,最高灰度显示为白色。 (3) imtool(RGB): 显示真彩色图像RGB。 (4) imtool(BW): 显示二值图像,像素值0显示为黑色,像素值1显示为白色。 (5) imtool(X,MAP): 显示索引图像,X为索引图像的数据矩阵,MAP为其颜色映射表。 (6) imtool(FILENAME): 显示FILENAME指定的图像。此格式下,要求图像能够被 函数imread或dicomread读取,或者是由 函数rsetwrite创建的数据集。若文件包括多帧图像,则显示第一帧,且文件必须在当前目录或MATLAB路径下。 (7) HFIGURE=imtool(…): 返回创建的图像对象句柄。 (8) CLOSE(HFIGURE): 关闭图像工具窗口。 (9) imtool CLOSE ALL: 关闭所有的图像工具窗口。 (10) imtool(…,PARAM1,VAL1,PARAM2,VAL2,…): 显示图像时指定相关参数及其取值,参数有'Colormap'、'DisplayRange'、'InitialMagnification'等。 【例36】采用imtool函数的不同形式显示图像。 程序如下: clear,clc,imtool close all; Image1=imread('girl.bmp'); imtool(Image1);%直接显示图像 imtool(Image1,[50 100]);%指定灰度级范围显示 imtool(Image1,'Colormap',jet);%指定颜色映射表显示 程序运行结果如图38所示。 图38调用imtool函数显示图像 3. 函数image和imagesc 函数image将矩阵中的数据显示为图像,函数imagesc采用拉伸过的色彩显示图像,有多种调用格式。 (1) image(C): 将矩阵C中的数据显示为图像,C的每一个元素指定图像中一个像素的颜色。当C为二维的M×N 矩阵时,每一个元素的值作为像素颜色值在当前颜色映射表中的索引值,由图像对象的CDataMapping属性决定: CDataMapping取'direct'(默认),C中元素值直接作为颜色索引; 取'scaled',C中的元素值先进行拉伸再作为索引值。当C为三维的M×N×3矩阵时,C(:,:,1)、C(:,:,2)、C(:,:,3)依次作为颜色的R、G、B分量值。如果C中元素的数据类型为double,则颜色值变化范围为[0.0,1.0]; 如果C中元素为uint8或uint16数据类型,则颜色值变化范围为[0,255]。 (2) image(x,y,C): x、y用于指定显示图像时,C中元素的坐标位置。函数image显示图像时,同时显示坐标轴,不设定x、y的值,则C(1,1)位于坐标(1,1)处,C(M,N)位于坐标(M,N)处; 设定x、y值,则C(1,1)位于坐标(x(1),y(1))处,C(M,N)位于坐标(x(end),y(end))处。 (3) imagesc(…): 数据经过拉伸作为颜色索引值,显示图像。 (4) imagesc(…,CLIM): 利用向量CLIM=[CLOW CHIGH]设置拉伸范围,CLOW对应颜色映射表中的第1个颜色,CHIGH对应颜色映射表中的最后一个颜色,中间的灰度线性对应颜色映射表中的其余颜色。 【例37】采用image和imagesc函数的不同形式显示图像。 程序如下: clear,clc,close all; Image1=imread('football.jpg'); [Image2,MAP2]=imread('girl.bmp'); figure,image(Image1),title('彩色图像'); figure,colormap(hot), h1=image(50,60,Image2),title('不拉伸映射'); %设置窗口颜色映射表为hot型,指定数据矩阵(1,1)位于(50,60)处 Y1=get(h1,'CDataMapping');%获取CDataMapping属性值 figure,colormap(hot),h2=imagesc(Image2,[30,150]),title('拉伸映射'); %灰度30对应颜色映射表第1个颜色,灰度150对应最后一个颜色 Y2=get(h2,'CDataMapping'); %获取CDataMapping属性值 程序运行结果如图39所示。 图39调用image和imagesc函数显示图像 从工作区可以看到,Y1='direct',Y2='scaled',即采用image函数显示不拉伸数据,而采用imagesc函数拉伸数据。 4. 函数montage 函数montage用矩形蒙太奇方式显示多帧图像的每帧,其调用格式如下。 (1) montage(FILENAMES): 显示FILENAMES指定的多帧图像。若FILENAMES不在当前目录或MATLAB路径下,则需要指明路径。 (2) montage(I): 显示多帧图像I,I可以是二值、灰度、彩色图像序列。 (3) montage(X,MAP): 显示索引图像的所有帧,X为多帧图像数据,共用颜色映射表MAP。 (4) montage(…,NAME1,VALUE1,NAME2,VALUE2,…): 定制显示,其参数如表38所示。 (5) H=montage(…): 返回图像对象句柄。 表38montage函数部分参数表 参数取值及含义 Size二维向量[NROWS NCOLS],指定蒙太奇行列数。行列数之一可以设定为NaN,在显示时,根据显示图像的总帧数和已知的行或列数目自动计算另一个 Indices一个数字序列,指明哪些帧要显示,如m:n,表示显示从第m帧到第n帧,默认为1:K,K为总帧数 DisplayRange1×2的向量[LOW HIGH],对显示的图像进行灰度拉伸,含义见函数imshow 【例38】采用montage 函数显示含有多帧的GIF、TIF图像。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('fly.gif');%读取GIF图像 figure,montage(Image1,MAP1,'size',[2 NaN]),title('GIF图像'); %两行排列显示GIF图像各帧 info=imfinfo('snoopy.tif');%获取TIF图像信息 len=length(info);%TIF图像含图像数 for i=1:len [Image2(:,:,:,i),MAP2]=imread('snoopy.tif',i);%依次读取TIF文件中各图像 end figure,montage(Image2,MAP2,'size',[1 NaN]),title('TIF图像'); %一行排列显示TIF图像各帧 程序运行结果如图310所示。 图310调用montage函数显示多帧图像 5. 函数imshowpair 函数imshowpair将图像成对显示,以比较图像间的差异。其调用格式如下。 (1) H=imshowpair(A,B,METHOD): 将图像A和B间的差异以METHOD指定的方式实现可视化,并返回创建的图像句柄H。如果A和B的大小不一致,则将较小的图像变为和较大图像同样大小,扩充的像素补0。METHOD的取值如表39所示。 表39imshowpair函数参数表 参数取值含义 METHOD falsecolor将A和B作为不同色彩通道合成RGB图像,默认值 blend采用α混合重叠A和B checkerboard从A和B创建具有交替矩形区域的图像 diff从A和B创建差异图像 montage将A和B在同一幅图像中相邻放置 Scaling independent 图像各自缩放,默认值 joint适用于在图像的动态范围之外具有大量填充值的单模态图像可视化 none不额外进行缩放 Parent指向创建的图像父对象的坐标轴的句柄 ColorChannels当METHOD取'falsecolor'时使用,将每个图像分配到输出图像中的特定颜色通道。设置为[R G B],指定哪一幅图像被指定到RGB对应通道,R、G、B取1表示该通道指定第1幅图像,取2表示第2幅图像,取0表示没有图像被指定; 可取'redcyan',等同于[R G B]=[1 2 2]; 可取'greenmagenta',等同于[R G B]=[2 1 2],默认值 (2) H=imshowpair(A,RA,B,RB): 根据RA和RB提供的空间参考信息显示A和B图像的差异。RA和RB由imref2d函数定义。 (3) imshowpair(…,PARAM1,VAL1,PARAM2,VAL2,…): 指定显示和混合方式显示图像。参数名称不区分大小写。各参数及取值含义见表39。 【例39】采用imshowpair函数显示GIF图像的不同帧。 程序如下: clear,clc,close all; info=imfinfo('fly.gif'); len=length(info); for i=1:len [Image(:,:,:,i),MAP]=imread('fly.gif',i); end subplot(131),imshowpair(Image(:,:,:,1),Image(:,:,:,len));%默认显示 subplot(132),imshowpair(Image(:,:,:,1),Image(:,:,:,len),'ColorChannels',[1 1 2]); subplot(133),imshowpair(Image(:,:,:,1),Image(:,:,:,len),'diff'); figure,imshowpair(Image(:,:,:,1),Image(:,:,:,len),'montage'); 程序运行结果如图311所示。 图311调用imshowpair函数显示图像差异 3.1.4像素信息的获取与显示 MATLAB利用impixel和impixelinfo函数实现像素信息的获取。 1. 函数impixel 函数impixel用于获取指定图像像素的R、G、B通道颜色值,其调用格式如下。 (1) P=impixel(I): 鼠标指定灰度图像I中的像素,获取其颜色值。 (2) P=impixel(X,MAP): 鼠标指定索引图像X中的像素,获取其颜色值。 (3) P=impixel(RGB): 鼠标指定真彩色图像RGB中的像素,获取其颜色值。 在以上3种调用中,impixel显示图像并等待用户用鼠标选择像素: 单击选择像素,双击或右击表示选择最后一个像素点,回车表示选择结束; 可以使用退格键Backspace和删除键Delete来删除之前选择的像素点,每次删除一个。若选择了N个点,则P为N×3的double型数组,存放每个点R、G、B颜色值。 【例310】采用impixel函数获取鼠标单击的像素的像素值。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('kids.tif');%索引图像 P=impixel(Image1,MAP1);%获取像素颜色值,存放于P数组中 Image2=imread('flower.jpg');%真彩色图像 Q=impixel(Image2);%获取像素颜色值,存放于Q数组中 运行程序,首先显示kids.tif图像,在图像上用鼠标左键点两个点,回车结束选择; 紧接着显示flower.jpg图像,在图像上用鼠标左键点一个点,双击结束选择; 运行结束。P、Q值如表310所示。P是索引图像像素颜色值,取值是MAP1中的0~1的数据; Q是彩色图像像素的红绿蓝色彩分量值,虽为double型数据,但在0~255。 表310例310 P、Q取值 名称尺寸数 据 类 型取值 P2×3double[0.3137,0.1490,0.1020; 0.09800,0.0941,0.1020] Q2×3double[245,123,0; 165,15,0] (4) P=impixel(I,C,R): C、R指定灰度图像I中的像素,获取其颜色值。 (5) P=impixel(X,MAP,C,R): C、R指定索引图像X中的像素,获取其颜色值。 (6) P=impixel(RGB,C,R): C、R指定真彩色图像RGB中的像素,获取其颜色值。 (7) [C,R,P]=impixel(…): 返回指定像素坐标。 在以上4种调用中,通过C、R直接指定像素。C和R为相同长度的向量,两向量中第k个对应元素构成像素的坐标(R(k),C(k))(矩阵坐标系),其颜色值为P的第k行数据。 (8) P=impixel(x,y,I,xi,yi): 非默认坐标系统下,指定灰度图像I中的像素,获取其颜色值。 (9) P=impixel(x,y,X,MAP,xi,yi): 非默认坐标系统下,获取索引图像X中指定像素的颜色值。 (10) P=impixel(x,y,RGB,xi,yi): 非默认坐标系统下,获取真彩色图像RGB中指定像素的颜色值。 (11) [xi,yi,P]=impixel(x,y,…): 返回指定像素坐标。 在以上4种调用中,x、y为二维向量,指定图像坐标范围; 通过xi、yi直接指定像素。xi、yi为相同长度的向量,两向量中第k个对应元素构成像素的坐标(yi(k),xi(k))(x、y指定的坐标系统),其颜色值为P的第k行数据。 【例311】采用impixel 函数获取指定的像素的像素值。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('kids.tif');%读取索引图像 Image2=imread('flower.jpg');%读取RGB真彩色图像 [N,M,color]=size(Image2);%获取真彩色图像尺寸 C=[20 40];R=[50 100];%设定指定像素坐标 P1=impixel(Image1,MAP1,C,R);%获取索引图像中指定像素的像素值,存于P1中 [C1,R1,P2]=impixel(Image2,C,R); %获取RGB图像中指定像素的像素值,并返回指定点坐标 x=[21 20+M];y=[51 50+N];%设定图像坐标范围,尺寸未变,坐标值整体增加[20 50] x1=[40 60];y1=[100 150];%设定指定像素坐标 P3=impixel(x,y,Image2,x1,y1);%获取RGB图像中指定像素的像素值,存于P3中 程序运行,各变量取值如表311所示。 表311例311各变量取值 名称尺寸数 据 类 型取值 Image1400×318uint8 MAP1256×3double Image2264×352×3uint8 P12×3double[0.4860,0.4275,0.3843; 0.4431,0.3686,0.3098] P22×3double[19,86,68; 0,59,0] P32×3double[19,86,68; 0,59,0] x1×2double[21,372] y1×2double[51,314] P1存放索引图像Image1中由C、R指定的两个像素点的像素值; P2存放RGB图像Image2中由C、R指定的两个像素点的像素值; P3存放改变图像坐标范围后的像素点值。在设定的坐标系统中,图像尺寸未变,没有变形; 指定的像素点坐标分别为(100,40)和(150,60),对应原图中的(50,20)和(100,40),和C、R指定的像素点一致,从表中可以看出,P3和P2取值一样。 2. 函数impixelinfo 函数impixelinfo用于在当前figure下创建像素信息,以显示光标所在位置处的图像像素信息。随着鼠标移动,可以显示figure中所有图像的像素的信息。 像素信息工具是一个uipanel控件,位于窗口的左下角,包含一个文本字串"Pixel Info:",后面显示像素位置和像素值,显示内容与图像类型和光标位置有关,如表312所示。 表312impixelinfo函数显示数据 图 像 类 型显 示 字 串示例 光标在图像区域外Pixel Info: (X,Y)Pixel Value 灰度图像Pixel Info: (X,Y) IntensityPixel Info: (13,30) 82 索引图像Pixel Info: (X,Y) [R G B]Pixel Info: (2,6) <4> [0.29 0.05 0.32] 二值图像Pixel Info: (X,Y) BWPixel Info: (12,1) 0 真彩色图像Pixel Info: (X,Y) [R G B]Pixel Info: (19,10) [15 255 10] 如果不显示"Pixel Info:"标签,可以使用impixelinfoval函数。 impixelinfo函数的调用格式如下。 (1) impixelinfo: 默认情况下,创建像素信息工具。 (2) impixelinfo(H): 在句柄H指定的figure下创建像素信息工具,H可以是图像、坐标系、uipanel或者figure对象,后三者应包含至少一幅图像。 (3) impixelinfo(HPARENT,HIMAGE): HIMAGE是图像句柄,在HPARENT 指向的figure或uipanel上创建像素信息工具,用以显示HIMAGE中的像素信息。 (4) HPANEL=impixelinfo(…): 创建一个像素信息工具,并返回像素信息工具的句柄。 【例312】采用impixelinfo 函数获取像素信息。 程序如下: clear,clc,close all; Image1=imread('pic4.bmp'); Image2=imread('bird.bmp'); [Image3,MAP3]=imread('kids.tif'); figure; subplot(121),imshow(Image1),title('真彩色图像'); subplot(122),imshow(Image2),title('二值图像'); impixelinfo figure; h=imshow(Image3,MAP3),title('索引图像'); H=impixelinfoval(gcf,h); 运行程序,在第1个figure中显示真彩色图像和二值图像,impixelinfo创建像素信息工具,随着光标移动,显示数据同表312所示一致; 在第2个figure中显示索引图像,impixelinfoval创建像素信息工具,随着光标移动,显示数据同表312所示一致,但不显示"Pixel Info:"标签。程序运行结果如图312所示。 图312像素信息工具显示效果 3.1.5局部区域的获取与显示 在对图像进行处理的过程中,可能只需对图像的部分区域进行处理,MATLAB提供了剪切函数imcrop 用于实现图像局部区域的获取与显示,其调用格式如下。 (1) I=imcrop: 创建一个与当前figure中显示的图像相关联的交互式图像剪切工具。使用鼠标在图像上绘制区域,大小可调整 、可移动,区域确定之后,双击或从右键菜单选择Crop Image命令实现该区域的剪切显示,并返回给I。该工具可以通过按 Backspace、Esc、Delete键,或者从右键菜单中选择Cancel命令取消,返回空值。 (2) I2=imcrop(I): 在figure中显示图像I并创建一个与之关联的剪切工具。I可以是灰度图像、RGB图像或者逻辑矩阵; I2为返回的剪切图像,类型与I一致。 (3) X2=imcrop(X,MAP): 在figure中显示索引图像并创建一个与之关联的剪切工具。 (4) I=imcrop(H): 创建一个与句柄H中的图像相关联的剪切工具。H可以是图像、坐标系、uipanel或figure的句柄,后三者的情况下,剪切工具作用在包含的第一幅图像上。 (5) I2=imcrop(I,RECT)或者X2=imcrop(X,MAP,RECT): 指定剪切矩形实现剪切,非交互式。RECT是一个4维向量[XMIN YMIN WIDTH HEIGHT],指定矩形的左上角位置及宽、高; 若是非默认的空间坐标系统,则需要指定XData和YData。 (6) [I2,RECT]=imcrop(…): 剪切的同时返回剪切矩形。 (7) [X,Y,I2,RECT]=imcrop(…): 剪切的同时返回剪切矩形及目标图像的XData和YData值。 【例313】采用imcrop函数剪切区域。 程序如下: clear,clc,close all; Image=imread('toysflash.png'); figure;imshow(Image),title('原图'); [h,w,c]=size(Image);%获取图像宽高信息 imcrop;%用鼠标选择剪切区域并显示 I1=imcrop;%在当前figure,即上一步剪切出来的图像中用鼠标选择区域剪切,返回给I1 I2=imcrop(Image,[w/2-60 h/2-120 w/3 h/3]);%在原图中指定矩形剪切 figure,imshow(I1),title('鼠标选定区域剪切'); figure,imshow(I2),title('原图中指定区域剪切'); 运行程序,首先显示原图,如图313(a)所示,等待用鼠标选择区域剪切; 剪切后显示剪切区域,如图313(b)所示; 再等待用鼠标选择区域剪切,剪切后显示如图313(c)所示,返回给I1; 紧接着显示在原图中指定矩形剪切的区域,如图313(d)所示。 图313区域获取与显示 3.1.6图像数据类型及转换 在处理图像的过程中,数据类型有可能发生变化,需要对其加以关注,避免出现错误。例如,在用函数imshow显示图像时,若数据为double型,则默认0~1为灰度范围; 若0~255的uint8数据无意中转换为0~255的double型数据,显示时会把大于1的像素全部按1(白色)显示。 图像数据类型可以根据需要转换,MATLAB提供了数据类型转换的相关函数。 函数im2double、im2uint8、im2uint16分别用于将图像数据转换为double、uint8、uint16型图像数据,取值范围分别为[0 ,1]、[0,255]及[0,65535]。输入的图像可以是二值图像、灰度图像、真彩色图像或索引图像。 函数double用于将数据强制转换为双精度型,但数值取值范围不变。 函数mat2gray用于将矩阵转换为灰度图像,其调用格式如下。 (1) I=mat2gray(A,[AMIN AMAX]): 将矩阵A转换为灰度图像I。A可以为逻辑型或数值型矩阵; I的取值为0~1的double型数据; AMIN和AMAX是矩阵A中对应图像I内0.0和1.0的数据,小于AMIN的数据变为0,大于AMAX的数据变为1.0。 (2) I=mat2gray(A): 将矩阵A转换为灰度图像I,A内的最小值、最大值分别为AMIN和AMAX。 【例314】打开图像,转换图像类型,观察数据变化,并显示图像。 程序如下: clear,clc,close all; Image=imread('boy.bmp'); %读取灰度图像,为uint8型数据 result1=double(Image);%转换为double型数据,不改变取值范围 result2=im2double(Image);%转换为double型数据,改变取值范围 result3=im2uint16(Image);%转换为uint16型数据 [N,M]=size(Image);%获取图像尺寸 A=rand(N,M);%创建0~1随机数值矩阵 A(N/2-40:N/2+40,M/2-40:M/2+40)=0;%中心小正方形区域设为0 result4=mat2gray(A);%矩阵转换为灰度图像 subplot(221),imshow(result1),title('0~255double型数据'); subplot(222),imshow(result2),title('0~1double型数据'); subplot(223),imshow(result3),title('uint16型数据'); subplot(224),imshow(result4),title('矩阵转图像'); 运行程序,各变量取值如表313所示,运行结果如图314所示。将原uint8型数据用double函数强制转换为double型,取值范围不变,存放于result1,图像显示为一片白色; 用im2double函数将原uint8数据转换为0~1范围内的double型数据,存放于result2,图像显示正常。 表313例314各变量取值 名称尺寸数 据 类 型最小值最大值 Image256×256uint87241 result1256×256double7241 result2256×256double0.02750.9451 result3256×256uint16179961937 result4256×256double01 A256×256double01.0 图314图像数据类型转换显示效果 3.1.7图像文件的保存 MATLAB主要利用imwrite函数实现图像文件的保存,其调用格式如下。 (1) imwrite(A,FILENAME,FMT): 将图像A以FMT指定的格式写入FILENAME指定的文件,A可以是M×N或者M×N×3的矩阵(即灰度图像或彩色图像)。若写为TIFF格式的文件,A可以是M×N×4的CMYK数据。 (2) imwrite(X,MAP,FILENAME,FMT): 将索引图像X及其关联的颜色映射表MAP以FMT指定的格式写入FILENAME指定的文件。若写为GIF图像,X应当是M×N×1×P的矩阵,P是图像中的帧数。 (3) imwrite(…,FILENAME): 根据FILENAME指定的文件的后缀来推断格式,将图像写入。 (4) imwrite(…,PARAM1,VAL1,PARAM2,VAL2,…): 指定参数控制输出文件的各种属性,保存图像。不同的文件格式参数不一致,支持GIF、HDF、JPEG、TIFF、PNG、PBM、PGM及PPM等格式。 【例315】打开一幅图像,将其保存为不同图像格式的文件。 程序如下: clear,clc,close all; info=imfinfo('snoopy.tif');%获取一幅TIF图像的信息 len=length(info);%获取TIF图像中的图像数目 for i=1:len [Image(:,:,:,i),MAP]=imread('snoopy.tif',i);%逐帧读取图像数据 end Image1=Image(:,:,:,1);%第一帧图像 imwrite(Image1,MAP,'snoopy1.bmp');%将第一帧索引图像存为BMP格式 imwrite(Image,MAP,'snoopy2.gif', 'DelayTime',0.2); %将TIF图像存为GIF图像,帧间播放间隔0.2s 程序运行,在当前目录下存储新图像snoopy1.bmp和snoopy2.gif。 3.2图像类型的转换 如第1章所讲,图像有二值图像、灰度图像、彩色图像等不同类型,当其色彩数目小于等于256时,又常存储为索引图像。在图像处理系统中,从输入图像到得到最终结果,图像的表示形式也在不断地发生变化,即不同类型的图像可以通过图像处理算法来转换,以满足图像处理系统的需求。 3.2.1彩色图像转换为灰度图像 将彩色图像转换为灰度图像,称为灰度化。彩色图像信息量大,数据量也大,在某些情况下,为了简化算法,需要进行灰度化。 灰度化一般是用像素点的亮度值作为像素值,亮度值可以通过变换颜色模型来计算,如式(31)、式(32)所示。 Y=0.299×R+0.587×G+0.114×B(31) I=(R+G+B)/3(32) 记录每个像素点的Y值或I值,则把彩色图像转化为灰度图像。也可以采用保留彩色图像不同色彩通道的数据的方法 转化。 MATLAB提供了函数rgb2gray实现灰度化,该函数利用式(31)将色彩值转换为亮度值。其调用格式如下。 (1) I=rgb2gray(RGB): 将真彩色图像RGB转换为灰度图像。 (2) NEWMAP=rgb2gray(MAP): 将MAP颜色映射表转换为灰度颜色映射表NEWMAP。 【例316】打开彩色图像,采用不同的方法将其灰度化,查看效果。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('snoopy.gif',1); Image2=im2double(imread('house.jpg'));%将读取的uint8数据转换为double型 MAP2=rgb2gray(MAP1);%将颜色映射表灰度化 Y=rgb2gray(Image2); r=Image2(:,:,1);g=Image2(:,:,2);b=Image2(:,:,3);%不同颜色通道 I=(r+g+b)/3;%利用式(3-2)灰度化 subplot(231),imshow(Image1,MAP2),title('灰度化颜色映射表'); subplot(232),imshow(Y),title('rgb2gray函数输出'); subplot(233),imshow(I),title('亮度I输出'); subplot(234),imshow(r),title('红色通道'); subplot(235),imshow(g),title('绿色通道'); subplot(236),imshow(b),title('蓝色通道'); 运行程序,输出图像如图315所示,颜色映射表MAP1和MAP2的两项取值如表314所示。MAP1中各颜色分量不同,呈现彩色; MAP2中各颜色分量相同,呈现灰色。程序中,读取彩色图像时,需要将数据转变为double型,若不转换,在计算I=(r+g+b)/3时,数据会溢出,将导致亮度I的计算不正确。 图315彩色图像灰度化 表314例316中MAP1和MAP2取值对比 变量尺寸类型前两项取值 MAP1256×3double 00.00390.0078 0.03920.50590.7451 MAP2256×3double 0.00320.00320.0032 0.39370.39370.3937 3.2.2多值图像转换为二值图像 将彩色、灰度、索引图像转换为二值图像,也称二值化。通常采用图像分割的方法完成,即把图像分成两个区域,前景用1、背景用0来表示,则转换为二值图像,这是比较直接的转换方法; 也可以根据具体需求转换,如检测到目标后,把目标区域用1来表示,背景部分用0来表示,转变为二值图像以便进行模板操作。 MATLAB提供了函数im2bw、imbinarize用于实现二值化,但推荐使用imbinarize函数。两个函数通过设定阈值,将亮度值大于阈值的像素变为1,其余的变为0,实现二值化。调用格式如下。 (1) BW=im2bw(I,LEVEL): 采用阈值LEVEL实现灰度图像I的二值化,无论I的数据类型是哪一种,阈值LEVEL都在[0,1]范围内。 (2) BW=im2bw(X,MAP,LEVEL): 采用阈值LEVEL实现索引图像X的二值化。 (3) BW=im2bw(RGB,LEVEL): 采用阈值LEVEL实现彩色图像RGB的二值化。 (4) LEVEL=graythresh(I): 采用OTSU方法(见第9章)计算图像I的全局最佳阈值LEVEL。 (5) BW=imbinarize(I): 采用基于OTSU方法的全局阈值实现灰度图像I的二值化。 (6) BW=imbinarize(I,METHOD): METHOD可选'global'和'adaptive',前者指定OTSU方法,后者采用局部自适应阈值方法,实现灰度图像I的二值化。 【例317】打开彩色、灰度、索引图像,实现二值化,查看效果。 程序如下: clear,clc,close all; Image1=imread('coins.png'); %打开灰度图像 result1=imbinarize(Image1);%采用自动全局阈值实现二值化 figure,imshow(result1),title('灰度图像二值化'); Image2=imread('plane.jpg');%打开彩色图像 result2=im2bw(Image2,0.5);%设定阈值0.5实现二值化 figure,imshow(result2),title('彩色图像二值化'); [Image3,MAP3]=imread('kids.tif');%打开索引图像 result3=im2bw(Image3,MAP3,0.5);%设定阈值0.5实现二值化 figure,imshow(result3),title('索引图像二值化'); 程序运行效果如图316所示。 图316图像二值化 3.2.3灰度图像转换为彩色图像 将灰度值映射到彩色空间,灰度图像即转换为彩色图像,也称为伪彩色增强,以便能够进行更好的观察。 例如,将图像中不同属性的材料或者不同的区域表示为不同的色彩,卫星图像的像素根据人的假设做标记,河流是蓝色的,郊区是紫色的,道路是红色的。也可以采用密度分割和灰度级变换的方法将灰度图像转换为彩色图像。 1. 密度分割法 密度分割法,又称为灰度分割法,该方法通过将图像中的整个灰度范围分为若干段,给每一段灰度分配一种颜色,将灰度图像变为彩色图像。若整个灰度范围仅分为两段,则实现二值化效果。方法简单直观,易于实现,但变换出的彩色信息有限,变换的彩色图像不够细腻。 【例318】采用密度分割法将索引图像转换为彩色图像。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('cartoon.bmp'); MAP2=zeros(256,3); MAP2(1:32,1)=30/256;MAP2(1:32,2)=32/256;MAP2(1:32,3)=30/256; MAP2(33:64,1)=93/256;MAP2(33:64,2)=193/256;MAP2(33:64,3)=195/256; MAP2(65:96,1)=180/256;MAP2(65:96,2)=108/256;MAP2(65:96,3)=186/256; MAP2(97:128,1)=67/256;MAP2(97:128,2)=119/256;MAP2(97:128,3)=98/256; MAP2(129:160,1)=95/256; MAP2(129:160,2)=137/256; MAP2(129:160,3)=110/256; MAP2(161:192,1)=81/256; MAP2(161:192,2)=173/256; MAP2(161:192,3)=255/256; MAP2(193:256,1)=256/256;MAP2(193:256,2)=256/256; MAP2(193:256,3)=256/256; %以上将颜色映射表分为7段,为每一段指定颜色分量 figure,imshow(Image1,MAP2),title('调整颜色映射表实现彩色化'); 图317分割颜色映射表实现伪彩色增强 程序运行效果如图317所示。程序中对颜色映射表直接进行了修改,将整个灰度范围分为7段,指定了每一段的颜色值。这种方法显示效果跟美观无关,比较适用于图像中特定灰度对应某种特殊信息的情况,给该段灰度以彩色,突出显示。 灰度图像没有颜色映射表,可以直接修改像素值实现彩色化。 【例319】采用密度分割法将灰度图像转换为彩色图像。 程序如下: clear,clc,close all; Image=rgb2gray(imread('lotus.jpg')); r=Image;g=Image;b=Image;%设置RGB颜色通道初始值 r(Image<20)=0;g(Image<20)=20;b(Image<20)=0; r(2090)=230;g(Image>90)=230;b(Image>90)=220; %以上将像素值分为5段,为每一段指定颜色分量 result=cat(3,r,g,b); figure,imshow(result),title('调整像素值实现彩色化'); 程序运行效果如图318所示。程序中将灰度范围分为5段,给每段指定了颜色。 图318分割像素值实现伪彩色增强 2. 灰度级变换法 通过将灰度图像f(x,y)送入具有不同变换特性的红、绿、蓝变换器,产生3个不同的输出fR (x,y)、fG (x,y)、fB(x,y) 作为彩色图像的红、绿、蓝色彩分量,即可合成一幅彩色图像。利用灰度级变换法生成的伪彩色图像颜色 是渐变的,视觉效果较好,但变换效果依赖于变换函数。下面介绍常见的灰度级变换函数。 1) 常见灰度级变换 灰度级变换法常采用的变换函数如图319所示,对应的公式如式(33)所示。L为灰度图像的灰度级别数,一般为256。 图319常用的一种灰度变换函数 R=00≤f=192)=255;%灰度级在红色通道变换 g(Image<64)=4*Image(Image<64); g(64<=Image & Image<192)=255; g(Image>=192)=-4*Image(Image>=192)+4*255;%灰度级在绿色通道变换 b(Image<64)=255; b(64<=Image & Image<128)=-4*Image(64<=Image & Image<128)+2*255; b(Image>=128)=0;%灰度级在蓝色通道变换 r=uint8(r);g=uint8(g);b=uint8(b);%为正确显示转变为uint8型数据 result=cat(3,r,g,b);%三通道合成彩色图像 figure,imshow(result),title('灰度级变换实现彩色化'); 程序运行效果如图320所示。 图320灰度级变换法实现伪彩色增强处理 2) 彩虹编码变换 另一种常见的灰度级变换方法称为彩虹编码,如图321所示,对应变换公式如式(34)所示。 图321彩虹编码的灰度变换函数 R=00≤f<96 255×f-963296≤f<128 255128≤f<256 G=00≤f<32 255×f-323232≤f<64 25564≤f<128 255×192-f64128≤f<192 255×f-19264192≤f<256B=255×f320≤f<32 25532≤f<64 255×96-f3264≤f<96 096≤f<192 255×f-19264192≤f<256 (34) 【例321】对灰色索引图像实现彩虹编码。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('cartoon.bmp'); MAP2=zeros(256,3);%创建新颜色映射表 MAP2(1:96,1)=0;MAP2(97:128,1)=((97:128)-96)/32;MAP2(129:256,1)=1; %修改颜色映射表红色通道 MAP2(1:32,2)=0;MAP2(33:64,2)=((33:64)-32)/32;MAP2(65:128,2)=1; MAP2(129:192,2)=(192-(129:192))/64; MAP2(193:256,2)=((193:256)-192)/64; %修改颜色映射表绿色通道 MAP2(1:32,3)=(1:32)/32;MAP2(33:64,3)=1; MAP2(65:96,3)=(96-(65:96))/32; MAP2(97:192,3)=0;MAP2(193:256,3)=((193:256)-192)/64; %修改颜色映射表蓝色通道 figure,imshow(Image1,MAP2),title('调整颜色映射表实现彩虹编码'); 程序运行效果如图322所示。需要注意,公式中灰度级用0~255表示,而MATLAB中数组下标从1开始,所以,程序中颜色映射表下标比公式中整体大1。 图322对颜色映射表进行彩虹编码实现伪彩色增强处理 3) 热金属编码变换 另一种常见的灰度级变换方法称为热金属编码,如图323所示,对应变换公式如式(35)所示。 图323热金属编码的灰度变换函数 R=00≤f<64 255×f-646464≤f<128 255128≤f<256 G=00≤f<128 255×f-12864128≤f<192 255192≤f<256B=255×f640≤f<64 25564≤f<96 255×128-f3296≤f<128 0128≤f<192 255×f-19264192≤f<256 (35) 【例322】对灰色索引图像实现彩虹编码。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('cartoon.bmp'); MAP2=zeros(256,3); MAP2(1:64,1)=0; MAP2(65:128,1)=((65:128)-64)/64;MAP2(129:256,1)=1; MAP2(1:128,2)=0; MAP2(129:192,2)=((129:192)-128)/64;MAP2(193:256,2)=1; MAP2(1:64,3)=(1:64)/64;MAP2(65:96,3)=1;MAP2(97:128,3)=(128-(97:128))/32; MAP2(129:192,3)=0;MAP2(193:256,3)=((193:256)-192)/64; figure,imshow(Image1,MAP2),title('调整颜色映射表实现热金属编码'); 程序运行效果如图324所示。 图324对颜色映射表进行热金属编码实现伪彩色增强处理 3.2.4索引图像的转换 MATLAB提供了相应的函数,用于实现索引图像和真彩色图像、灰度图像之间的互相转换,为便于后续程序设计,本节 详细介绍这些转换函数。 1. RGB图像和索引图像的相互转换 函数rgb2ind和ind2rgb用于实现RGB图像和索引图像之间的相互转换,调用格式如下。 (1) [X,MAP]=rgb2ind(RGB,N): 采用最小方差量化的方法将RGB图像转换为索引图像X,MAP颜色映射表至少包含N个颜色,N<=65536。 (2) X=rgb2ind(RGB,MAP): 将RGB图像转换为索引图像X,MAP是X的颜色映射表,转换中将RGB中的颜色和MAP中最接近的颜色匹配。 (3) [X,MAP]=rgb2ind(RGB,TOL): 利用均匀量化的方法将RGB图像转换为索引图像X,TOL取值范围为0.0~1.0,MAP最多包含(FLOOR(1/TOL)+1)3种颜色。 (4) […]=rgb2ind(…,DITHER_OPTION): 转换时设置DITHER_OPTION参数,选择是否采用颜色抖动,可取为'dither'(默认)和'nodither',前者损失空间分辨率获得较好的色彩分辨率,后者仅将原图中的色彩与新颜色映射表中最接近的颜色匹配。 (5) RGB=ind2rgb(X,MAP): 将矩阵X和对应的颜色映射表MAP转换为RGB图像。X可以为uint8、uint16或double型数据,RGB为M×N×3的double型矩阵。 【例323】实现RGB图像和索引图像的相互转换。 程序如下: clear,clc,close all; RGB1=imread('house.jpg'); figure,image(RGB1),title('原图'); [X,MAP]=rgb2ind(RGB1,16);%转变为只有16种颜色的索引图像 figure,image(X),colormap(MAP),title('索引图像'); RGB2=ind2rgb(X,MAP);%反变换回RGB图像 figure,image(RGB2),title('还原的RGB图像'); 运行程序,各变量如表315所示。原图RGB1有256个灰度级别,转换为索引图像X后为16个灰度级,对应MAP为16×3的矩阵。程序运行效果如图325所示。由于程序中真彩色图像转换为索引图像 时减少了颜色,因此索引图像及再变换回的RGB2图像色彩不够细腻,图像显得比较粗糙。 表315例323中各变量取值情况表 变量尺寸类型最小值最大值 RGB1234×352×3uint80255 RGB2234×352×3double0.00390.9686 X234×352uint8015 MAP16×3double0.00390.9686 图325RGB图像和索引图像的相互转换 2. 灰度图像和索引图像的相互转换 函数gray2ind和ind2gray用于实现灰度图像和索引图像之间的相互转换,其调用格式如下。 (1) [X,MAP]=gray2ind(I,N): 将灰度图像I转变为索引图像X; 颜色映射表MAP为gray(N),即MAP为N×3灰度映射表,N为当前figure颜色映射表的长度,若没有figure,为默认颜色映射表的长度; N≤256时,X为uint8型数据,否则为uint16型数据。N应当是1~65536之间的整数,默认情况下,N为64。 (2) [X,MAP]=gray2ind(BW,N): 将二值图像BW转换为索引图像X,颜色映射表MAP为gray(N)。默认情况下,N为2。 (3) I=ind2gray(X,MAP): 将索引图像X转变为灰度图像I,去掉了色调和饱和度信息,仅保留亮度值。 【例324】实现灰度图像和索引图像的相互转换。 程序如下: clear,clc,close all; I=imread('cameraman.tif'); %读取灰度图像 [X,MAP]=gray2ind(I,16);%转换为有16种颜色的索引图像 figure,imshow(X,MAP),title('索引图像'); J=ind2gray(X,MAP);%变换回灰度图像 figure,imshow(J),title('还原的灰度图像'); 运行程序,各变量如表316所示。原图I有256个灰度级别,转变为索引图像X后为16个灰度级,对应MAP为16×3的矩阵。运行结果如图326所示。由于程序中灰度图像转变为索引图像时减少了灰度级, 因此索引图像及再变换回的灰度图像显得比较粗糙。 表316例324中各变量取值情况表 变量尺寸类型最小值最大值 I256×256uint87253 J256×256uint80255 X256×256uint8015 MAP16×3double01 图326灰度图像和索引图像的相互转换 3.3色彩空间转换 颜色有多种表示方式,可以根据需要将图像转换到不同的色彩空间,便于处理。本节介绍图像在RGB空间和HSV、YCbCr、YIQ、LAB空间之间的转换。 3.3.1RGB空间和HSV空间的转换 MATLAB提供了函数rgb2hsv和hsv2rgb用于实现图像在RGB和HSV空间之间的转换,其调用格式如下。 (1) H=rgb2hsv(M): 将RGB颜色映射表M转换为HSV颜色映射表H。M、H均为取值为0~1的P×3矩阵,M每一行为一种颜色的RGB分量; H每一行为一种颜色的HSV分量。 (2) HSV=rgb2hsv(RGB): 将RGB图像转变为HSV图像。RGB是uint8、uint16、double型数据时,HSV为0~1的double型数据; RGB为single数据时,HSV也为single型数据。 (3) M=hsv2rgb(H): 将HSV颜色映射表H转换为RGB颜色映射表M。 (4) RGB=hsv2rgb(HSV): 将HSV图像转变为RGB图像。当HSV为logical、double型数据时,输出的RGB为double型数据; 当HSV为single型数据时,RGB也为single型数据。 【例325】将图像在RGB和HSV空间之间转换,尝试修改饱和度和亮度值,查看效果。 程序如下: clear,clc,close all; Image1=imread('montreal.jpg'); %打开彩色图像 [Image2,MAP1]=rgb2ind(Image1,256);%转换为256级的索引图像 H=rgb2hsv(MAP1);%将颜色映射表转换到HSV空间 H(:,2)=H(:,2)*2;H(H>1)=1; %饱和度增强为原来的2倍,超出范围的限幅为1 MAP2=hsv2rgb(H);%将增强饱和度后的颜色映射表转换回RGB空间 H(:,3)=H(:,3)*1.5;H(H>1)=1; %亮度增强为原来的1.5倍,超出范围的限幅为1 MAP3=hsv2rgb(H);%将增强饱和度、亮度后的颜色映射表转换回RGB空间 HSV=rgb2hsv(Image1);%将原真彩色图像转换到HSV空间 HSV(:,:,3)=HSV(:,:,3)*1.5; %将亮度增强为原来的1.5倍 Image3=hsv2rgb(HSV);%将增强亮度后的HSV数据转换回RGB空间 subplot(221),imshow(Image1),title('原图'); subplot(222),imshow(Image2,MAP2),title('增强饱和度'); subplot(223),imshow(Image3),title('增强亮度'); subplot(224),imshow(Image2,MAP3),title('增强饱和度、亮度'); 程序运行效果如图327所示。 图327RGB空间和HSV空间的相互转换 程序将RGB图像Image1转换为索引图像,并将颜色映射表MAP1转换为HSV空间的H,H为256×3的矩阵,其3列分别为每一种颜色的色调、饱和度和亮度的值,对饱和度进行2倍拉伸,反转换回RGB空间的颜色映射表MAP2,转换后图像色彩相对原图鲜艳,如图327(b)所示; 再对H的亮度进行1.5倍拉伸,反转换回RGB空间的颜色映射表MAP3,图像整体变亮,颜色变得鲜艳,如图327(d)所示。将图像矩阵Image1转换到HSV空间的三维矩阵HSV,对其第三维(亮度)进行1.5倍拉伸,反转换回RGB空间,如图327(c)所示,仅亮度增加。 3.3.2RGB空间和YCbCr空间的转换 MATLAB提供了函数rgb2ycbcr和ycbcr2rgb用于实现图像在RGB和YCbCr空间之间的转换,其调用格式如下。 (1) YCBCRMAP=rgb2ycbcr(MAP): 将RGB颜色映射表MAP转换为YCbCr颜色映射表YCBCRMAP。YCBCRMAP为P×3矩阵,每一行对应MAP中同一行的颜色,3列元素分别为该颜色的Y、Cb、Cr分量。 (2) YCBCR=rgb2ycbcr(RGB): 将RGB图像转变为YCbCr图像,RGB是M×N×3的矩阵。若RGB为uint8型数据,则Y∈[16,235],Cb,Cr∈[16,240]; 若输入为double或single型数据,则Y∈[16/255,235/255],Cb,Cr∈[16/255,240/255]; 若输入为uint16型数据,则Y∈[4112,60395],Cb,Cr∈[4112,61680]。 (3) RGBMAP=ycbcr2rgb(YCBCRMAP): 将YCbCr空间的颜色映射表YCBCRMAP转换为RGB空间的RGBMAP。 (4) RGB=ycbcr2rgb(YCBCR): 将YCbCr图像转换为RGB图像。 【例326】将图像在RGB和YCbCr空间之间转换,尝试修改数值,并查看效果。 程序如下: clear,clc,close all; Image1=imread('montreal.jpg'); YCBCR=rgb2ycbcr(Image1);%RGB图像转换到YCbCr空间 YCBCR(:,:,1)=YCBCR(:,:,1)*1.6;%增强亮度值 Image2=ycbcr2rgb(YCBCR);%反转换回RGB空间 [Image3,MAP1]=imread('kids.tif');%打开索引图像 YCBCRMAP=rgb2ycbcr(MAP1);%颜色映射表MAP1转换到YCbCr空间 YCBCRMAP(:,1)=YCBCRMAP(:,1)*1.1; %略增强亮度Y YCBCRMAP(:,3)=YCBCRMAP(:,3)*0.95;%弱化Cr值 YCBCRMAP(YCBCRMAP>1)=1;%限幅 MAP2=ycbcr2rgb(YCBCRMAP);%颜色映射表反转换回RGB空间 subplot(221),imshow(Image1),title('真彩色图原图'); subplot(222),imshow(Image2),title('增强亮度'); subplot(223),imshow(Image3,MAP1),title('索引图原图'); subplot(224),imshow(Image3,MAP2),title('增强Y,弱化Cr'); 程序运行效果如图328所示。程序中将RGB图像Image1转换到YCbCr空间,将亮度Y增大为原来的1.6倍, 反转换后图像的效果如图328(b)所示,亮度增强。MAP1为索引图像的颜色映射表,转换为YCbCr空间的YCBCRMAP,YCBCRMAP为256×3的矩阵,其3列分别为每一种颜色的Y、Cb和Cr值,将亮度Y增强为原来的1.1倍,Cr值弱化为原来的0.95倍,反转换回RGB空间的颜色映射表MAP2,转换后图像在一定程度上修正了原图偏红的色彩,如图328(d)所示。 图328RGB空间和YCbCr空间的相互转换 3.3.3RGB空间和YIQ空间的转换 MATLAB提供了函数rgb2ntsc和ntsc2rgb用于实现图像在RGB和YIQ空间之间的转换,其调用格式如下。 (1) YIQMAP=rgb2ntsc(RGBMAP): 将RGB颜色映射表RGBMAP转换为YIQ颜色映射表YIQMAP。YIQMAP为P×3矩阵,每一行对应RGBMAP中同一行的颜色,3列元素分别为该颜色的Y、I、Q分量。 (2) YIQ=rgb2ntsc(RGB): 将RGB图像转换为YIQ图像。 (3) RGBMAP=ntsc2rgb(YIQMAP): 将YIQ颜色映射表YIQMAP转换为RGB颜色映射表RGBMAP。YIQMAP和RGBMAP均为P×3的double型矩阵。 (4) RGB=ntsc2rgb(YIQ): 将YIQ图像转换为RGB图像。 【例327】将图像在RGB和YIQ空间之间转换,并查看数据。 程序如下: clear,clc,close all; RGB=imread('montreal.jpg'); YIQ=rgb2ntsc(RGB);%真彩色图像转换为YIQ数据 [X,RGBMAP]=imread('kids.tif'); YIQMAP=rgb2ntsc(RGBMAP);%索引图像颜色映射表转换为YIQ颜色映射表 运行程序,各变量取值情况如表317所示,RGB数据为uint8型,YIQ数据为double型,图像尺寸一致; RGBMAP和YIQMAP均为double型256×3的矩阵。 表317例327中各变量取值 变量尺寸类型最小值最大值 RGB512×512×3uint8 YIQ512×512×3double X400×318uint8063 RGBMAP256×3double00.9961 YIQMAP256×3double-0.05770.8500 3.3.4RGB空间和LAB空间的转换 MATLAB提供了函数rgb2lab和lab2rgb用于实现图像在RGB和CIE 1976 L*a*b*空间之间的转换,其调用格式如下。 (1) lab=rgb2lab(rgb): 将RGB值转换为CIE 1976 L*a*b*值。 (2) rgb=lab2rgb(lab): 将CIE 1976 L*a*b*值转换为RGB值。 【例328】将图像在RGB空间和LAB空间之间 进行转换,计算并查看色差图像。 程序如下: clear,clc,close all; RGB=imread('flower.jpg'); [N,M,C]=size(RGB); LAB=rgb2lab(RGB);%转换到LAB空间 L=LAB(:,:,1);A=LAB(:,:,2);B=LAB(:,:,3); delta=zeros(N,M); for i=2:M-1 for j=2:N-1 for m=-1:1%计算每个像素点和周围8个点的色差和 for n=-1:1 delta(j,i)=delta(j,i)+sqrt((L(j,i)-L(j+n,i+m))^2+ (A(j,i)-A(j+n,i+m))^2+(B(j,i)-B(j+n,i+m))^2); end end end end delta=delta/max(delta(:)); LAB(:,:,1)=L*0.8;%降低亮度 result=lab2rgb(LAB);%转换回RGB色彩空间 subplot(131),imshow(RGB),title('真彩色图原图'); subplot(132),imshow(delta,[]),title('色差图像'); subplot(133),imshow(result),title('降低亮度反变换'); 程序运行效果如图329所示。 图329RGB空间和LAB空间的相互转换 3.4视频文件的读写 数字视频,又称动态图像,是多帧位图的有序组合,在很多情况下,需要处理的对象正是数字视频。本节介绍MATLAB提供的对视频文件进行操作的相关函数。 3.4.1视频文件信息读取 MATLAB提供的mmfileinfo函数能够获取多媒体文件的信息,其调用格式如下。 INFO=mmfileinfo(FILENAME): 获取FILENAME指定的多媒体文件的音频、视频信息,存储于INFO结构体中。INFO结构体各变量如表318所示。 表318mmfileinfo函数返回结构体各变量 变量含义内容 Filename文件名一个字符串 Path文件绝对路径一个字符串 Duration文件时长,单位为秒 Audio一个结构体,文件中的音频信息 Format音频格式 NumberOfChannels音频通道数 Video一个结构体,文件中的视频信息 Format视频格式 Height帧高 Width帧宽 【例329】读取两种不同格式的视频文件,并查看返回结构体数据。 程序如下: clear,clc,close all; INFO1=mmfileinfo('tilted_face.avi'); INFO2=mmfileinfo('xylophone.mpg'); 程序运行结果如表319所示。 表319例329中各变量取值 变量分量取值变量分量取值 INFO1 Filename'tilted_face.avi' Path'E:\MATLAB\3 Chapter' Duration13.7667 Audio Format' ' NumberOfChannels[ ] Video Format'MJPG' Height480 Width640 INFO2 Filename'xylophone.mpg' Path'E:\MATLAB\3 Chapter' Duration4.7020 Audio Format'MPEG' NumberOfChannels2 Video Format'MPEG1' Height240 Width320 3.4.2视频文件数据读取 VideoReader函数创建一个多媒体读取对象,进而能读取视频数据,其调用格式如下。 (1) OBJ=VideoReader(FILENAME): 创建一个多媒体读取对象OBJ,可以通过OBJ读取多媒体文件的视频数据。 (2) OBJ =VideoReader(FILENAME,'P1',V1,'P2',V2,…): 设置相关属性创建多媒体读取对象OBJ,相关属性见表320。 表320函数VideoReader属性 属性含义属性含义 Name被读取的文件名 Path被读取的文件路径 Duration文件时长,单位: 秒 CurrentTime当前读取帧在文件中的位置 Tag用户设置的一般字符串 UserData用户自定义数据 Height帧高,单位: 像素 Width帧宽,单位: 像素 BitsPerPixel每像素所占位数 VideoFormat视频格式: 取值可以为'RGB24'、'Grayscale'、'Indexed' FrameRate帧率 创建多媒体读取对象OBJ有readFrame、hasFrame两种方法。readFrame方法用于从视频文件中读取下一个可读帧; hasFrame方法判断是否有可读取的帧。各自的调用格式如下。 (1) FLAG=hasFrame(OBJ): 有可读帧,则返回true; 否则返回false。 (2) VIDEO=readFrame(OBJ): 读取下一个可读帧,返回VIDEO。VIDEO是H×W×B的矩阵,H、W、B依次为帧图像的高、宽、色彩通道数,OBJ的VideoFormat指定格式返回数据。 (3) VIDEO=readFrame(OBJ,'native'): 读取下一个可读帧。指定参数'native'时,返回值与默认情况下有所区别,如表321所示。 表321VideoFormat属性与VIDEO返回值 VideoFormat指定'native'VIDEO数据类型VIDEO维数描述 'RGB24' 'Grayscale' 'Indexed' 否 uint8M×N×3真彩色图像 uint8M×N×1灰度图像 uint8M×N×3真彩色图像 'RGB24' 'Grayscale' 'Indexed'是 uint8M×N×3真彩色图像 struct1×1MATLAB movie* struct1×1MATLAB movie* 注: MATLAB movie是一个帧结构体矩阵,包含 "cdata"和"colormap"两个字段,分别为帧图像数据矩阵和颜色映射表。后文直接采用MATLAB movie来表示。 【例330】使用VideoReader函数创建多媒体读取对象,读取并显示视频,查看返回数据。 程序如下: clear,clc,close all; OBJ=VideoReader('atrium.mp4');%创建OBJ多媒体读取对象 OBJ.CurrentTime=0.1;%设置开始读取帧的位置 currAxes=axes;%在当前figure下使用默认属性值创建一个坐标系图形对象 while hasFrame(OBJ)%用循环语句读取每一帧,有可读帧则读取 Frame= readFrame(OBJ);%读取可读帧,返回给Frame image(Frame,'Parent',currAxes);%显示当前帧 currAxes.Visible = 'off';%不显示坐标 pause(1/OBJ.FrameRate);%帧和帧之间的时间间隔 end 运行程序,在figure中显示视频画面,如图330所示。程序中OBJ变量取值如表322所示; Frame变量为360×640×3的uint8型数据。 图330视频显示画面 表322例330中OBJ取值情况表 属性含义属性含义 Name'atrium.mp4'Height360 Path'E:\MATLAB\3 Chapter'Width640 Duration20.0000BitsPerPixel24 CurrentTime20.0000VideoFormat'RGB24' Tag''FrameRate30 UserData[ ] 3.4.3视频的播放 在例330中,采用循环语句依次读取并显示视频中的每一帧,帧和帧之间暂留时间小于视觉暂留时间,则看到连贯流畅的动态画面。除此之外,MATLAB还提供了movie函数, 用于实现视频的播放。本节介绍movie函数及与其相关的函数。 1. 函数getframe getframe函数通过捕捉当前坐标系下的快照来获取MATLAB movie中的帧,一般用于循环语句中,以获取多帧,其调用格式如下。 (1) getframe(H): 从句柄H指定的figure或坐标系中获取一帧。 (2) getframe(H,RECT): 从指定的矩形中获取位图数据,RECT相对于句柄H指定对象的左下角定义,单位为像素。 (3) F=getframe(…): 从包含两个字段"cdata" 和 "colormap"的结构体中返回MATLAB movie帧。其中,"cdata"为uint8型图像数据矩阵,"colormap"是double型矩阵; 返回F的“cdata” 为H×W×3的矩阵; 若系统采用真彩色图形显示方式, 则F的“colormap”为空。 2. 函数movie 函数movie用来播放视频帧,其调用格式如下。 (1) movie(M): 在当前坐标系下播放M中的MATLAB movie,M可以通过函数getframe获取。 (2) movie(figure_handle,…): 在指定的figure中播放视频。 (3) movie(M,N): 将M播放N次。若N为负数,每次播放包含正向一次,逆向一次; 若N是一个向量,第一个元素是播放次数,其余元素为要播放的帧,例如,M包含4帧,而N=[10 4 4 2 1],则播放MATLAB movie10次,每次按第4帧、第4帧、第2帧、第1帧播放。 (4) movie(M,N,FPS): 以每秒FPS帧的速度播放视频,FPS默认时为每秒12帧,若达不到指定的速度,则以能达到的最快速度播放。 (5) movie(H,…): 在对象H中播放MATLAB movie,H可以是figure或坐标系的句柄。 (6) movie(H,M,N,FPS,LOC): 指定位置播放MATLAB movie。LOC是位置向量[X Y 未使用 未使用],X、Y相对 位于对象H的左下角,单位为像素; 后2维虽未使用,但必须有。 【例331】使用getframe函数获取MATLAB movie数据并播放。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('snoopy.gif');%打开GIF图像 info=imfinfo('snoopy.gif'); len=length(info);%获取GIF图像帧数 for j=1:len imshow(Image1(:,:,:,j),MAP1); %依次显示GIF中各帧 M(j) = getframe;%获取MATLAB movie帧 pause(1/25);%画面显示时间间隔 end figure,movie(M);%新建figure下显示MATLAB movie figure,movie(M,[6 len 1 floor(len/2)]);%将M中第len、1、len/2帧依次显示6遍 figure, currAxes=axes; currAxes.Visible='off';%不显示坐标系 movie(M,3,3,[50 50 300 248]);%将M中各帧在位置[50 50]处以每秒3帧显示3遍 运行程序,依次显示4段视频: figure 1中是循环语句,依次显示GIF中各帧; figure 2中在左下角显示视频; figure 3中将M中第5、1、2帧依次显示6遍; figure 4中将M中各帧在位置[50 50]处以每秒3帧显示3遍。播放停止后的画面如图331所示。 图331视频显示画面 3. 函数im2frame和frame2im 函数im2frame用于将索引图像转换为MATLAB movie格式; 函数frame2im用于返回MATLAB movie帧的图像数据, 其调用格式如下。 (1) F=im2frame(X,MAP): 将索引图像X及其颜色映射表MAP转换为MATLAB movie帧F。若X为真彩色图像,MAP是可选项但无效。 (2) F=im2frame(X): 将图像X转换为MATLAB movie帧F。若X为索引图像,则使用当前颜色映射表。 (3) [X,MAP]=frame2im(F): 从MATLAB movie帧F返回索引图像X及其颜色映射表MAP。若F为真彩色,则MAP为空。 【例332】使用im2frame函数获取MATLAB movie数据,播放视频并查看数据。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('dog.gif'); info=imfinfo('dog.gif'); len=length(info); for j=1:len M(j)=im2frame(Image1(:,:,:,j),MAP1);%将GIF图像的每一帧转换为MATLAB movie帧 end figure,movie(M,-2,4,[100 130 240 117]); %将M中各帧在位置[100 130]处以每秒4帧显示2遍,每遍正向一次,逆向一次 [image2,MAP2]=frame2im(M(floor(len/2)));%将中间帧转换为索引图像image2 figure,imshow(image2,MAP2),title('中间帧'); 运行程序,在figure 1中播放两遍视频,每遍正向一次,逆向一次; 把中间帧转换为索引图像image2并显示,如图332所示。 图332视频显示画面 3.4.4视频文件的保存 MATLAB主要利用VideoWriter函数实现视频文件的存储。VideoWriter函数用于创建一个视频写入对象,其调用格式如下。 (1) OBJ=VideoWriter(FILENAME): 创建一个视频写入对象,将视频数据写入FILENAME指定的 AVI文件。若FILENAME 未包含扩展名'.avi',函数会自动附加。 (2) OBJ=VideoWriter(FILENAME,PROFILE): 设定属性创建一个视频写入对象,如表323所示。PROFILE 可取'Archival'、'Motion JPEG AVI'、'Motion JPEG 2000'、'MPEG4'、'Uncompressed AVI'、'Indexed AVI'、'Grayscale AVI',对应不同的视频压缩编码方法。 表323函数VideoWriter属性 属性含义 Path文件完全路径 Filename文件名 Duration文件时长,单位为秒 FileFormat字符串,文件类型 ColormapP×3颜色映射表 FrameCount帧数 FrameRate帧率 Height帧高 Width帧宽 LosslessCompression布尔值,为true,无损压缩,则CompressionRatio参数无效,用于Motion JPEG 2000 文件中 ColorChannels输出视频帧的色彩通道数 续表 属性含义 MJ2BitDepth输入图像数据中最低有效位数目,取值为1~16,仅用于Motion JPEG 2000文件中 Quality0~100的整数,仅用于Motion JPEG AVI和MPEG4配置中; 取值越大,视频质量越好但文件越大 CompressionRatio压缩比,仅用于Motion JPEG 2000文件中 VideoBitsPerPixel输出视频帧每像素位数 VideoCompressionMethod字符串,指定视频压缩类型 VideoFormat字符串,视频格式 视频写入对象OBJ有open、close、writeVideo、getProfiles 4种方法。可以根据需要设置OBJ的Colormap、FrameRate、LosslessCompression、Quality、CompressionRatio等属性,但必须在调用open函数前。4种方法各自的调用格式如下。 (1) open(OBJ): 打开要写入视频数据的文件,必须打开才能写入。 (2) close(OBJ): 在写入结束后关闭文件。 (3) writeVideo(OBJ,FRAME): 将FRAME写入与OBJ关联的视频文件。FRAME是一个包括cdata和colormap字段的结构体,可以通过getframe函数获取。文件中每一帧的宽、高应一致。 (4) writeVideo(OBJ,MOV): 将MOV指定的 MATLAB movie写入视频文件。 (5) writeVideo(OBJ,IMAGE): 将IMAGE中的数据写入一个视频文件。IMAGE可以为single、double、uint8型矩阵。 (6) writeVideo(OBJ,IMAGES): 将一系列彩色图像数据写入视频文件。IMAGES是四维矩阵为: 高×宽×1×帧数的灰度图像或者高×宽×3×帧数的彩色图像。 (7) PROFILES=VideoWriter.getProfiles(): 返回VideoWriter支持的配置。 【例333】读取GIF图像,保存为AVI文件。 程序如下: clear,clc,close all; [Image1,MAP1]=imread('fly.gif'); info=imfinfo('fly.gif'); len=length(info); vidObj = VideoWriter('fly.avi'); %创建视频写入对象 vidObj.FrameRate=10;%修改帧率 open(vidObj);%打开要写入的视频文件 for i=1:len Image2(:,:,:,i)=ind2rgb(Image1(:,:,:,i),MAP1); %将GIF帧转换为真彩色图像 end for j=1:len*3 for i=1:len Images(:,:,:,len*j+i)= Image2(:,:,:,i); End%重复GIF帧数据,存入Images图像序列中,增大帧数 end writeVideo(vidObj,Images);%将Images中的图像序列写入视频文件 close(vidObj);%关闭视频文件 运行程序,创建的视频写入对象取值如表324所示,在当前路径下增加了fly.avi文件。 表324例333中vidObj取值情况表 属性取值属性取值 Duration20Height248 Filename'fly.avi'Width300 Path'E:\MATLAB\3 Chapter'VideoFormat'RGB24' FileFormat'avi'Quality75 ColorChannels3VideoBitsPerPixel24 FrameCount200VideoCompressionMethod'Motion JPEG' FrameRate10 3.5实例 【例334】实现电影中常见的去彩色效果。 设计思路: 读取一段视频,按照时间剪切其中的一段,将其中的每一帧灰度化,转换为灰度视频段; 同时将该段视频 的每一帧转换到HSV空间,提取其色调通道,转换为色调视频段; 最后将灰度视频段和色调视频段分别保存为AVI文件。 程序如下: clear,clc,close all; OBJ = VideoReader('vippedtracking.mp4');%创建视频读取对象 OBJ.CurrentTime = 1;%读取视频从第1秒开始 j=1; while hasFrame(OBJ) && OBJ.CurrentTime<9%判断是否已有可读下一帧,是否在9秒前 Frame = readFrame(OBJ);%读取下一帧 grayFrame=rgb2gray(Frame);%灰度化 hsvFrame=rgb2hsv(Frame);%转换到HSV空间 M1(:,:,:,j)=grayFrame;%灰度视频段图像序列 M2(:,:,:,j)=hsvFrame(:,:,1);%色调视频段图像序列 j=j+1; end vidObj1 = VideoWriter('grayvideo.avi');%创建视频写入对象 open(vidObj1); writeVideo(vidObj1,M1);%打开视频文件并写入灰度视频 close(vidObj1);%关闭视频文件 vidObj2 = VideoWriter('hvideo.avi');%创建视频写入对象 open(vidObj2); writeVideo(vidObj2,M2);%打开视频文件并写入色调视频 close(vidObj2);%关闭视频文件 subplot(131),imshow(Frame),title('彩色视频段最后一帧'); subplot(132),imshow(grayFrame),title('灰度视频段最后一帧'); subplot(133),imshow(hsvFrame(:,:,1)),title('色调视频段最后一帧'); 运行程序,将生成两段AVI视频grayvideo.avi和hvideo.avi,各段视频最后一帧显示如图333所示。 图333各段视频最后一帧 【例335】实现图像编辑中的保留色彩。 设计思路: 显示一幅图像,用鼠标左键在图像上选择至少3个点,根据选择点确定要保留色彩的色调范围; 扫描图像,确定色彩在选择范围内的像素点,形成模板; 同时将图像灰度化。模板与原图相乘,反色的模板和灰度化图像相乘,两者相加,使得模板内的像素保留色彩,模板外的像素呈现灰色。 程序如下: clear,clc,close all; Image=imread('peony.jpg'); [height,width,color]=size(Image); figure,imshow(Image),title('选择至少3个像素点用于确定要保留的色彩范围'); [C,R,P]=impixel(Image); HSV=rgb2hsv(Image); gray=double(rgb2gray(Image)); len=length(C);coH=zeros(len,1); for i=1:len coH(i)=HSV(R(i),C(i),1);%选择点的色调值 end minH=min(coH);minH=max(minH-0.2*minH,0); maxH=max(coH);maxH=min(maxH+0.2*maxH,1);%确定色彩范围 mask=zeros(height,width); mask(HSV(:,:,1)>=minH & HSV(:,:,1)<=maxH)=1;%形成模板 maskRGB=double(cat(3,mask,mask,mask)); result=uint8(mask.*double(Image)+(1-mask).*gray);%生成保留色彩的图像 figure,imshow(result); 程序运行结果如图334所示。 图334保留色彩实例效果图 3.6本章小结 本章主要介绍了在MATLAB中实现图像处理的基本操作,包括图像文件的读写、图像的显示、数据转换、类型转换、色彩空间转换、视频文件的读写、视频的播放等。本章内容是后续图像处理的前提,应熟悉各函数功能,掌握输入输出变量的含义及要求。