目录
(2)将彩色图像变换到 YCbCr、HSV 空间,熟悉各分量数据并显示。
(3)不采用 Matlab 函数,自行设计基于双线性插值的图像放大程序;
一、实验意义及目的
(
1
)了解和掌握图像处理工具
Matlab
,熟悉基于
Matlab
的图像处理函数,并为下一步
编程进行图像处理打下基础。
(
2
)理解色彩的概念,掌握图像代数运算,几何变换方法。
二、实验内容
打开一幅彩色图像
Image1
,使用
Matlab
图像处理函数,对其进行下列变换:
(
1
)将
Image1
色彩通道互换,并显示效果;
(2)将
Image1
灰度化为
gray
,并显示灰度化后图像;
(3)采用不同的插值方法实现
gray
的旋转、放大变换;
(4)打开另一幅彩色图像
Image2
,和
Image1
进行代数运算,要求运用拼接、加减乘除
等多种技术;
(5)实验要求中的拓展内容。
三、Matlab 相关函数介绍
(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)
:实现两幅图像相除。
四、参考代码
参考代码中实现了彩色图像的灰度化、旋转、缩放两种几何变换以及镜像及拼接。
Image1=imread('peppers.jpg');
%红绿通道互换
Image2=Image1;
Image2(:,:,1)=Image1(:,:,2);
Image2(:,:,2)=Image1(:,:,1);
imshow(Image2);
imwrite(Image2,'changecolor.jpg');
%灰度化
gray=rgb2gray(Image1);
figure;
subplot(121),imshow(Image1),title('Original Image');
subplot(122),imshow(gray),title('Gray Image');
imwrite(gray,'grayimage.jpg');
%图像旋转
Newgray1=imrotate(gray,15);
Newgray2=imrotate(gray,15,'bilinear');
figure;
subplot(121),imshow(Newgray1),title('旋转15°(最邻近插值)');
subplot(122),imshow(Newgray2),title('旋转15°(双线性插值)');
imwrite(Newgray1,'rotate1.jpg');
imwrite(Newgray2,'rotate2.jpg');
%图像缩放
Newgray3=imresize(gray,2.5,'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);
VImage=flipdim(Image2,1);
CImage=flipdim(HImage,1);
[h w]=size(Image2);
NewImage=zeros(h*2,w*2,3);
NewImage=[Image2 HImage;VImage CImage];
figure,imshow(NewImage);
imwrite(NewImage,'newlotus.jpg');
%图像的加减乘除
clc;
clear all;
ImageA = imread('lotus.bmp');
ImageB = imread('you.jpg');
%两张图之间要做运算首先需要有相同分辨率,将图片做了一个像素的统一化:
[a,b,c]=size(ImageA);
ImageB=imresize(ImageB,[a,b,]);
%分别对AB图像做了加 乘 除 减
Imagei = imadd(ImageA,ImageB);
Imagej = immultiply(ImageA, ImageB);
Imagek = imdivide(ImageA,ImageB);
Imagel = imsubtract(ImageA,ImageB);
figure;
subplot(321), imshow(ImageA);
subplot(322), imshow(Imagel);
subplot(323), imshow(ImageB);
subplot(324), imshow(Imagei);
subplot(325), imshow(Imagej);
subplot(326), imshow(Imagek);
五、运行结果
六、实验要求
1.
熟悉
Matlab
函数,读懂参考代码;
2.
拓展内容:
(1)将彩色图像采用不同的灰度化方法实现灰度化;
MyImage1 = imread('peppers.jpg');%读取彩色图像
%显示原来的图像
figure(1);
imshow(MyImage1);
%经过系统函数运算得到的灰度图像
MyGrayPic1 = rgb2gray(MyImage1);
figure(2);
imshow(MyGrayPic1);
[rows,cols,colors] = size(MyImage1);%得到原来图像矩阵的参数
MidGrayPic1 = zeros(rows,cols);%得到一个全0矩阵,用于存储之后生成的灰度图像
MidGrayPic1 = uint8(MidGrayPic1);%将创建的全0矩阵转换为uint8格式,因为用上面的语句创建之后图像是double型的
for i =1:rows
for j =1:cols
sum=0;
for k =1:colors
sum = sum+MyImage1(i,j,k)/3;%进行转化的关键公式,sum每次都因为后面的数字而不能超过255 ,
end
MidGrayPic1(i,j)=sum;
end
end
%平均值法转化后的灰度图像
figure(3);
imshow(MidGrayPic1);
MidGrayPic2=zeros(rows ,cols);%用得到的参数创建一个全0的矩阵,用于存储之后生成的灰度图像
MidGrayPic2=uint8(MidGrayPic2);%将创建的全0矩阵转换为uint8格式
for i=1:rows
for j=1:cols
MidGrayPic2(i,j)=max(MyImage1(i,j,:));
end
end
%最大值法转化之后的灰度图像
figure(4);
imshow(MidGrayPic2);
MidGrayPic3 = zeros(rows ,cols);%用得到的参数创建一个全0矩阵
MidGrayPic3 = uint8(MidGrayPic3);%将创建的全0矩阵转换为uint8格式
for i = 1:rows
for j=1:cols
MidGrayPic3(i , j) = MyImage1(i , j , 1)*0.30+MyImage1(i , j , 2)*0.59+MyImage1(i , j , 3)*0.11;
end
end
%加权平均值法转化之后的灰度图像
figure(5);
imshow(MidGrayPic3);
运行结果:
(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分量图像');
运行结果:
(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');
运行结果: