一、实验目的:
(1)了解和掌握图像处理工具Matlab,熟悉基于Matlab的图像处理函数,并为下一步编程进行图像处理打下基础。
(2)理解色彩的概念,掌握图像代数运算,几何变换方法。
二、实验原理
(1)imread函数
功能:实现多种类型图像文件的读取,如:BMP、GIF、JPEG、PNG、RAS等。
调用格式:A = imread(filename, fmt)。filename为图像文件名,可以是灰度图像,也可以是彩色图像,如果文件不在当前目录或不在Matlab目录下,则需要列全文件路径。fmt为文件的扩展名,指定文件类型。A为图像数据矩阵。
(2)imshow函数
功能:显示图像。
调用格式:
imshow(I,n):显示灰度图像I,n为要显示图像的灰度等级,整数,默认为256。
Imshow(I,[LOW HIGH]):以规定的灰度级范围[LOW HIGH]来显示灰度图像I,低于LOW值的显示为黑,高于HIGH值的显示为白,默认按256个灰度级显示。
imshow(RGB):显示真彩色图像RGB。
imshow(BW):显示二值图像BW。
imshow(X,map):显示索引图像,X为索引图像的数据矩阵,map为其颜色映射表。
imshow filename:显示filename指定的图像,若文件包括多帧图像,则显示第一幅,且文件必须在MATLAB的当前目录下。
(3)imwrite函数
功能:实现图像文件的保存。
调用格式:
imwrite(A,’filename’,fmt):A是要保存的图像数据矩阵,filename是文件名,fmt是文件格式。
imwrite(X,map,’filename’,fmt):X为索引图像的数据矩阵,map为其颜色映射表。
(4)rgb2hsv函数
功能:实现RGB数据图像向HSV数据图像的转换。
调用格式:
HSV = rgb2hsv(RGB)。RGB为RGB彩色图像,为3维矩阵;HSV为3维HSV图像矩阵,3维依次为H、S、V,取值均在[0,1]范围内。
(5)rgb2ycbcr函数
YCBCR = rgb2ycbcr(RGB) :实现RGB数据图像向YCbCr数据图像的转换。
(6)rgb2gray函数
功能:彩色图像灰度化。
调用格式:
I = rgb2gray(RGB):真彩色RGB图像变换为灰度图像I。
NEWMAP = rgb2gray(MAP):变换索引图像的调色板为灰度调色板。
(7)imrotate函数
功能:实现图像旋转。
调用格式:
B = imrotate(A,ANGLE,METHOD,BBOX):A为要进行旋转的图像;ANGLE为要旋转的角度()逆时针为正,顺时针为负;METHOD为图像旋转插值方法,可取“‘nearest’, ‘bilinear’, ‘bicubic’”,默认为nearest;BBOX指定返回图像大小,可取“crop”,输出图像B与输入图像A具有相同的大小,对旋转图像进行剪切以满足要求;可取“loose”,默认是,B包含整个旋转后的图像。
(8)imresize函数
功能:实现图像缩放。
调用格式:
B = imresize(A, SCALE,METHOD)):返回原图A的SCALE倍大小图像B;
B = imresize(A, [NUMROWS NUMCOLS], METHOD)):对原图A进行比例缩放,返回图像B的行数NUMROWS和列数NUMCOLS,如果二者为NaN,表明Matlab自动调整了图像的缩放比例;
[Y, NEWMAP] = imresize(X, MAP, SCALE, METHOD)):对索引图像进行成比例缩放。
(9)imtransform函数
功能:实现图像几何变换。
调用格式:
B = imtransform(A,TFORM,INTERP,param1,val1,param2,val2,…) :对图像A实现空间变换,TFORM为maketform函数或cp2tform函数产生的结构;INTERP为插值方法,可取“‘nearest’, ‘bilinear’, ‘bicubic’”。
T = maketform(TRANSFORMTYPE,…):产生转换结构;TRANSFORMTYPE为变换类型,可以为“‘affine’, ‘projective’, ‘custom’, ‘box’, ‘composite’”。
(10)fliplr函数
B=fliplr(X):实现二维矩阵X沿垂直轴的左右翻转。
(11)flipud函数
B= flipud(X):实现二维矩阵X上下翻转。
(12)flipdim函数
B=flipdim(X,DIM):使矩阵X按特定轴翻转,dim指定翻转方式:为1表示按行翻转;为2表示按列翻转。
(13)permute函数
B = permute(A,ORDER):按照向量ORDER指定的顺序重排A的各维,B中元素和A中元素完全相同,但在A、B访问同一个元素使用的下标不一样。order中的元素必须各不相同。
(14)imadd函数
C=imadd(A,B) :实现两幅图像相加。
1)A、B均为图像,则要求B和A的尺寸相等;若B是一个标量,则C表示对图像A整体加上某个值(对小数部分取整)。
2)假如A和B对应运算和大于255,C仍取255,即截断处理;为避免截断,可以将C存储为uint16,即C=imadd(A,B,’uint16’)。
(15)imsubtract函数
功能:实现两幅图像相减。
调用格式:
C=imsubtract(A,B):差值结果小于0的赋值为0,对A、B的要求同imadd相同。
C=imabsdiff(A,B):差值结果取绝对值。
(16)immultiply 函数
C=immultiply(A,B):实现两幅图像相乘。
(17)imdivide函数
C=imdivide(A,B) :实现两幅图像相除。
(18)灰度化处理:将彩色图像转换为灰度图像的过程
对于图像而言,灰度化处理就是使彩色的R,G,B分量值相等的过程。
灰度化处理的方法主要有如下3种:
最大值法:使R,G,B的值等于3值中最大的一个,R=G=B=max(R,G,B),最大值法会形成亮度很高的灰度图像。
平均值法:是R,G,B的值求出平均值,R=G=B=(R+G+B)/3,平均值法会形成较柔和的灰度图像。
加权平均值法:根据重要性或其他指标给R,G,B赋予不同的权值,并使R,G,B的值加权平均,R=G=B=WR+VG+UB,W,V,U分别表示权重,研究表明,人对绿色的敏感度最高,对红色次之,对蓝色的敏感度最低,因此W>V>U,实验和理论证明当W=0.2989,V=0.5870,U=0.1140时,能得到最合理的灰度图像。
Matlab自带的灰度化处理函数rgb2gray采用的是第三种方法。
注意:如果图像类型为double型,但是灰度值范围超过0-1,需要对图像进行归一化。否则会发现利用W=0.2989,V=0.5870,U=0.1140编写代码进行灰度化与rgb2gray进行灰度化结果不一致(经过rgb2gray处理的图像灰度值范围为0-1,超过1的均为1)。
三、实验步骤(包括分析、代码和波形)
首先来看看这个实验的内容。实验主要涉及打开一幅彩色图像Image1,使用Matlab图像处理函数,对其进行下列变换:
(1)将Image1色彩通道互换,并显示效果;
(2)将Image1灰度化为gray,并显示灰度化后图像;
(3)采用不同的插值方法实现gray的旋转、放大变换;
(4)打开另一幅彩色图像Image2,和Image1进行代数运算,要求运用拼接、加减乘除等多种技术;
实验要求中的拓展内容。:
(1)将彩色图像采用不同的灰度化方法实现灰度化;
(2)将彩色图像变换到YCbCr、HSV空间,熟悉各分量数据并显示。
(3)不采用Matlab函数,自行设计基于双线性插值的图像放大程序;
实验的思路是很明确的,结合原理中的讨论,我们只要按照题目的要求依据参考代码、查看运行并进行验证就可以了,不需要计算。
**下面是第(1)小题的代码。**这一部分需要注意的是imshow函数与imwrite函数,它们可以用来显示图像以及实现图像文件的保存:
% Image1=imread('peppers.jpg');//% 读取图像文件
红绿通道互换
Image2=Image1;// % 相当于将图像复制赋值给Image2
Image2(:,:,1)=Image1(:,:,2);//将Image1绿色通道赋值给Image2红色通道
//1:red ; 2:green ; 3:blue
Image2(:,:,2)=Image1(:,:,1);//将Image1红色通道赋值给Image2绿色通道
imshow(Image2);// % 显示蓝绿通道互换后图像
imwrite(Image2,'changecolor.jpg');//保存图像Image2
下面的图给出了红绿通道互换后的图:
**下面是第(2)小题的代码。**应该注意到rgb2gray函数可以用来使彩色图像灰度化。
%灰度化
gray=rgb2gray(Image1);//%用已有的函数进行RGB到灰度图像的转换
//%显示经过系统函数运算过的灰度图像
figure;
subplot(121),imshow(Image1),title('Original Image');// subplot(r,c,n) r:行数 c:列数 n:(图像位置)按顺序从左到右,从上到下依次
subplot(122),imshow(gray),title('Gray Image');// % imshow() 展示图像
imwrite(gray,'grayimage.jpg');
得到的灰度化的图如下图:
**下面是第(3)小题的代码。**这一部分需要注意的是imrotate函数,它可以实现图像旋转。
%图像旋转 //matlab函数:B = imrotate(A,angle,method);A是原始图像,angle是旋转角度,B为旋转后的图像
;使用method参数可以改变插值算法,例如:'nearest':最邻近线性插值 ;'bilinear':双线性插值 ;'bicubic':双三次插值(或叫做双立方插值)
Newgray1=imrotate(gray,15);//gray是原始图像,15是旋转角度,Newgray1是为旋转后的图像
Newgray2=imrotate(gray,15,'bilinear');// 'bilinear':双线性插值
figure;
subplot(121),imshow(Newgray1),title('旋转15°(最邻近插值)');
subplot(122),imshow(Newgray2),title('旋转15°(双线性插值)');
imwrite(Newgray1,'rotate1.jpg');
imwrite(Newgray2,'rotate2.jpg');
得到的旋转后的图如下图:
下面是第(4)小题的代码。这一部分需要注意的是imresize函数,它可以实现图像缩放;另外flipdim函数
B=flipdim(X,DIM):使矩阵X按特定轴翻转,DIM指定翻转方式:为1表示按行翻转;为2表示按列翻转。。
%图像缩放
Newgray3=imresize(gray,2.5,'nearest');//:返回原图gray的2.5倍大小图像Newgray3,使用method参数可以改变插值算法,例如:'nearest':最邻近线性插值
Newgray4=imresize(gray,2.5,'bilinear');
figure;
subplot(121),imshow(Newgray3),title('放大2.5倍(最邻近插值)');
subplot(122),imshow(Newgray4),title('放大2.5倍(双线性插值)');
imwrite(Newgray3,'scale1.jpg');
imwrite(Newgray4,'scale2.jpg');
%图像镜像与拼接
Image2=imread('lotus.bmp');
HImage=flipdim(Image2,2);//使矩阵Image2按特定轴翻转,翻转方式:为1表示按行翻转;为2表示按列翻转。
VImage=flipdim(Image2,1);//使矩阵Image2按特定轴翻转,翻转方式:为1表示按行翻转;为2表示按列翻转。
CImage=flipdim(HImage,1);//使矩阵HImage1按特定轴翻转,翻转方式:为1表示按行翻转;为2表示按列翻转。
[h w]=size(Image2);
NewImage=zeros(h*2,w*2,3);
NewImage=[Image2 HImage;VImage CImage];
figure,imshow(NewImage);
imwrite(NewImage,'newlotus.jpg');
得到放大与镜像与拼接的图如下:
实验要求中的拓展内容
下面是拓展第(1)小题的代码。实现彩色图像的灰度化主要有三种方法:最大值法、平均值法、加权平均法。
%最大值法参考代码
im=imread('autumn.tif');
[x,y,z]=size(im);//%得到原来图像im的矩阵的参数
immax=ones(x,y);//
%最大值灰度图像
for i=1:x
for j=1:y
immax(i,j)=max(im(i,j,:));
end
end
im(:,:,1)=immax;
im(:,:,2)=immax;
im(:,:,3)=immax;
figure('name','最大值灰度图像');
imshow(im);
%平均值法、加权平均法参考代码
im=imread('autumn.tif');
figure('name','原图像');
imshow(im);
%提取R、G、B三色分量
imR=im2double(im(:,:,1));
imG=im2double(im(:,:,2));
imB=im2double(im(:,:,3));
%平均值灰度图像
%取完平均值之后还要乘以255,将灰度值范围变回[0,255]并取整
imRGB=round((imR+imG+imB)/3*255);
im(:,:,1)=imRGB;
im(:,:,2)=imRGB;
im(:,:,3)=imRGB;
figure('name','灰度图像');
subplot(1,2,1);
imshow(im);
title('平均值灰度图像');
%加权平均值灰度图像
%Wr=0.587,Wg=0.299,Wb=0.114,加权平均后还要乘以255,将灰度值范围变回[0,255]并取整
imRGB2=round((0.587*imR+0.299*imG+0.114*imB)*255);
im(:,:,1)=imRGB2;
im(:,:,2)=imRGB2;
im(:,:,3)=imRGB2;
subplot(1,2,2);
imshow(im);
title('加权平均值灰度图像');
原图
最大值灰度图像
平均值灰度图像(左),加权平均值灰度图像(右)
下面是拓展第(2)小题的代码。将彩色图像变换到YCbCr、HSV空间,熟悉各分量数据并显示。
%将彩色图像变换到 YCbCr、HSV 空间,熟悉各分量数据并显示
Image = imread('peppers.jpg');
gray = rgb2gray(Image);
hsv = rgb2hsv(Image);
ycbcr = rgb2ycbcr(Image);
figure;
subplot(221);imshow(Image);title('原始图像');
subplot(222);imshow(gray);title('灰度图像');
subplot(223);imshow(hsv);title('HSV空间图像');
subplot(224);imshow(ycbcr);title('YCbCr图像');
%HSV空间显示其分量
figure;
H=hsv(:,:,1);
S=hsv(:,:,2);
V=hsv(:,:,3);
subplot(1,3,1);imshow(H);title('HSV空间H分量图像');
subplot(1,3,2);imshow(S);title('HSV空间S分量图像');
subplot(1,3,3);imshow(V);title('HSV空间V分量图像');
%YCbCr空间显示其分量
figure;
Y=ycbcr(:,:,1);
Cb=ycbcr(:,:,2);
Cr=ycbcr(:,:,3);
subplot(1,3,1); imshow(Y); title('YCbCr空间Y分量图像');
subplot(1,3,2); imshow(Cb); title('YCbCr空间Cb分量图像');
subplot(1,3,3); imshow(Cr); title('YCbCr空间Cr分量图像');
得到彩色图像变换到YCbCr、HSV空间的图如下:
下面是拓展第(3)小题的代码。不采用Matlab函数,自行设计基于双线性插值的图像放大程序;
% 相关基础知识;
% 图像插值是一种基本的图像处理方法,它可以为数字图像增加或减少像素的数目。
% 当图像被放大时,像素会相应地增加,该像素增加的过程实际就是插值程序自动
% 选择信息较好的像素作为新的像素以弥补空白像素空间的过程。虽然经过插值后
% 图像可以变得更平滑、干净,但由于新增加的像素也仅仅只是原始像素的某种组
% 合而已,所以图像的插值运算并不会增加新的图像信息。
% 插值图像提供坐标-->计算该坐标在原始图像中的对应坐标-->原始图像返回像素值并进行插值运算
% 双线性插值法充分利用了邻域像素的不同占比程度而计算得出最合适的插值像素,从而完成插值。
% 相比较于最近邻插值,双线性插值的插值效果要好得多,因为最近邻插值只跟(x,y)最近的像素值有关,
% 而双线性插值是按照(x,y)上下、左右四个像素值的重要程度进行插值的(即越接近越重要)
%%%% 这两行代码上面已经执行
Image1 = imread('peppers.jpg'); % 读取RGB格式的图像
[rows,cols,colors] = size(Image1);
mutiple = 0.5;
newRows = round(rows * mutiple);
newCols = round(cols * mutiple);
scaleImage = uint8(zeros(newRows,newCols, colors));
% 给原图像加"墙壁"
ImageAddWalls = zeros(rows+2,cols+2,colors);
ImageAddWalls(1,2:cols+1,:) = Image1(1,:,:); % 源图像上面加墙,像素值和边界一致
ImageAddWalls(rows+2,2:cols+1,:) = Image1(rows,:,:);% 源图像下面加墙,像素值和边界一致
ImageAddWalls(2:rows+1,2:cols+1,:) = Image1; % 将原图像赋值给中心部分
ImageAddWalls(:,1,:) = ImageAddWalls(:,2,:); % 源图像左边加墙,像素值和边界一致
ImageAddWalls(:,cols+2,:) = ImageAddWalls(:,cols+1,:); % 源图像右边加墙,像素值和边界一致
for i = 1 : newRows
for j = 1 : newCols
originX = ( i + 0.5 ) * cols / newCols - 0.5;
orininY = ( j + 0.5 ) * rows / newRows - 0.5;
Q22_x = ceil(originX); % 找到Q22点的坐标
Q22_y = ceil(orininY);
if Q22_x == 1
Q22_x = 2;
end
if Q22_y ==1
Q22_y = 2;
end
Q11_x = Q22_x - 1;% 找到Q11点的坐标
Q11_y = Q22_y - 1;
Q21_x = Q22_x - 1;% 找到Q21点的坐标
Q21_y = Q22_y;
Q12_x = Q22_x;% 找到Q12点的坐标
Q12_y = Q22_y - 1;
% 根据公式,将公式处理成线性代数的矩阵运算,计算该点像素
derX = [Q22_x - originX , 1 - Q22_x + originX];
derY = [Q22_y - orininY ; 1 - Q22_y + orininY];
for k = 1:3
QPiexl = [ImageAddWalls(Q11_x,Q11_y,k), ImageAddWalls(Q21_x,Q21_y,k);ImageAddWalls(Q12_x,Q12_y,k),ImageAddWalls(Q22_x,Q22_y,k)];
scaleImage(i,j,k) = derX*QPiexl*derY;
end
end
end
figure,imshow(Image1),title('原图像');
figure,imshow(scaleImage),title('缩放后的图像');
imwrite(scaleImage,'scaleImg.jpg');
得到自行设计基于双线性插值的图像的图如下:
四、实验总结
初步了解和掌握图像处理工具Matlab,熟悉基于Matlab的图像处理函数,并为下一步编程进行图像处理打下基础。通过实验深入了解了色彩的概念,掌握图像代数运算一些方法,还初步了解了几何变换的方法。