一、图像点运算
点运算又称为对比度增强、对比度拉伸或灰度变换,是一种通过图像中的每一个像素值(即像素点上的灰度值)进行运算的图像处理方式。它将输入图像映射为输出图像,输出图像每个像素点的灰度值仅由对应的输入像素点的灰度值决定,运算结果不会改变图像内像素点之间的空间关系,其运算的数学关系式如下:
其中,A(x,y) 表示原图像,B(x,y) 表示经过点运算处理后的图像,f表示点运算的关系函数。按照灰度变换的数学关系,点运算可以分为线性灰度变换、分段线性灰度变换和非线性灰度变换3种。
1、线性灰度变换
1.1 基本原理
假定原图像A(x,y)的灰度变换范围为[a,b],处理后的图像B(x,y)的灰度扩展为[c,d],线性灰度变换运算的数学表达式为:
在matlab中,使用灰度变换函数imadjust()实现。
1.2 matlab实现
% 线性灰度变换
% 关闭所有图形窗口,清除工作空间所有变量,清空命令行
close all;
clear all;
clc;
gamma=0.5; % 设定调整线性度取值
I=imread('peppers.png'); % matlab自带图像,直接读取即可
% 以下三个操作我们明白一个概念:一张RGB图像对应一个M*N*3的矩阵(三维数组,M代表图像的长,N代表图像的宽)。此处的3代表R,G,B三个分量,范围在0-255
% RGB(:,:,1)获取红色分量,RGB(:,:,2)获取绿色分量,RGB(:,:,3)获取蓝色分量
% 灰度线性变换函数f1=imadjust(f,[low_in high_in],[low_out high_out],gamma)
% f中灰度值低于low_in的像素点在f1中被赋值为low_out;同理,f中灰度值高于high_in的像素点在f1中被赋值为high_out
% 参数gamma,当gamma<1时图像整体变明亮;当gamma>1时,图像整体变灰暗
R=I; % 将原图像数据赋值给R,即下面可对R进行操作,而原图像I不变
R(:,:,2)=0;% 去除绿色
R(:,:,3)=0;% 去除蓝色,结果保留红色
R1=imadjust(R,[0.5 0.8],[0 1],gamma);% 对红色进行灰度线性变换
G=I; % 同理
G(:,:,1)=0;% 去除红色
G(:,:,3)=0;% 去除蓝色,结果保留绿色
G1=imadjust(G,[0 0.3],[0 1],gamma);% 对绿色进行灰度线性变换
B=I; % 同理
B(:,:,1)=0;% 去除红色
B(:,:,2)=0;% 去除绿色,结果保留蓝色
B1=imadjust(B,[0 0.3],[0 1],gamma);% 对蓝色进行灰度线性变换
I1=R1+G1+B1; % 经过线性灰度变换的RGB图像
%set(0,'defaultFigurePosition',[100,100,1000,500]);% 修改图像位置的默认设置,即figure的起点坐标为(100,100),宽度为1000,高度为500(个人感觉该语句可有可无,本例中无区别)
%set(0,'defaultFigureColor',[1,1,1]);% 修改图像背景颜色设置(个人感觉该语句可有可无,本例中无区别)(matlab图形窗口的默认背景颜色为灰色,此处将其改为白色)
figure(1),subplot(121),imshow(R);
title('原始R图像');
subplot(122),imshow(R1);
title('线性灰度变换后的R图像');
figure(2),subplot(121),imshow(G);
title('原始G图像');
subplot(122),imshow(G1);
title('线性灰度变换后的G图像');
figure(3),subplot(121),imshow(B),
title('原始B图像');
subplot(122),imshow(B1);
title('线性灰度变换后的B图像');
figure(4),subplot(121),imshow(I);
title('原始图像');
subplot(122),imshow(I1);
title('线性灰度变换后的图像');
2.1 基本原理
为了突出图像中感兴趣的目标或者灰度区间,可采用分段线性法,将需要的图像细节灰度拉伸、对比度增强。3段线性变换法运算的数学表达式如下:
2.2 matlab实现
% 分段线性灰度变换
% 关闭所有图形窗口,清除工作空间所有变量,清空命令行
close all;
clear all;
clc;
R=imread('peppers.png'); % matlab自带图像,直接读取即可
J=rgb2gray(R);% 注意此处需要先转换为灰度图像,因为此处R为一个RGB图像对应三维数组,转换为灰度图像后对应二维数组便于操作
[M,N]=size(J);% size函数用来获取灰度图像的行列数M,N
% 双重for循环分别读取原灰度图像中每个像素点的灰度值J(x,y),对灰度图像进行分段处理,将处理后的结果返回给矩阵H
x=1;y=1;
for x=1:M
for y=1:N
if(J(x,y)<=35)
H(x,y)=J(x,y)*10;
elseif(J(x,y)>35&&J(x,y)<=75)
H(x,y)=(10/7)*(J(x,y)-5)+50;
else
H(x,y)=(105/180)*(J(x,y)-75)+150;
end
end
end
set(0,'defaultFigurePosition',[100,100,1000,500]);
set(0,'defaultFigureColor',[1,1,1]);
subplot(121),imshow(J);
title('原始图像');
subplot(122),imshow(H);
title('分段线性灰度变换后的图像');
3.1 基本原理
当输出图像的像素点灰度值和输入图像的像素点灰度值不满足线性关系时,这种灰度变换都称为非线性灰度变换,此处仅介绍一种基于对数变换的非线性灰度变换,其运算的数学表达式如下:
其中a、b、c是为了调整曲线的位置和形状而引入的参数。图像通过对数变换可扩展低值灰度,压缩高值灰度。
3.2 matlab实现
% 非线性灰度变换
% 关闭所有图形窗口,清除工作空间所有变量,清空命令行
close all;
clear all;
clc;
R=imread('peppers.png'); % matlab自带图像,直接读取即可
G=rgb2gray(R);% 注意此处需要先转换为灰度图像,因为此处R为一个RGB图像对应三维数组,转换为灰度图像后对应二维数组便于操作
J=double(G);% 将数据类型由uint8转换为double,因为下面使用对数会产生double类型,若不转换则会报错:检查对函数 'log' 的调用中是否存在不正确的参数数据类型或缺少参数
H=(log(J+1))/10;% 基于常用对数的非线性灰度变换
set(0,'defaultFigurePosition',[100,100,1000,500]);
set(0,'defaultFigureColor',[1,1,1]);
subplot(121),imshow(G);
title('原始图像');
subplot(122),imshow(H);
title('非线性灰度变换后的图像');
注意:
以上分别给出了三种不同类型的点运算,它们相同之处在于都能够改变图像的显示灰度,不同之处在于采用的数学方法不同。用户在需要进行图形灰度变换时,根据实际情况选择不同的运算形式,当然还有其他类型的数学运算。用户可参照实例设计自己的灰度变换。
二、图像的代数运算
图像的代数运算是指将两幅或多幅图像通过对应像素之间的加、减、乘、除运算得到输出图像的方法,它们运算的数学表达式如下:
其中,A(x,y) 和B(x,y)表示进行代数运算的两幅图像,C(x,y)表示A(x,y)和B(x,y)运算后的结果。
在MATLAB中,可利用基本算术符(+、-、*、/等)执行上述4种图像的代数运算;同时MATLAB图像处理工具箱也提供了一个能够实现所有非稀疏数值数据的代数运算的函数集合。需要说明的是,在MATLAB中图像数据类型是uint8,当进行代数运算时有可能产生属性溢出,所以应当在进行图像代数运算之前首先将数据类型转换成double,从而保证结果的准确性。
1、图像的加法运算
图像加法运算的一个应用是将一幅图像的内容叠加到另一幅图像上,生成叠加图像效果,或给图像中每个像素叠加常数改变图像的亮度。在MATLAB图像处理工具箱中提供的函数imadd0可实现两幅图像的相加或者一幅图像和常量的相加,其具体的调用格式如下:
% 图像加法运算
% 关闭所有图形窗口,清除工作空间所有变量,清空命令行
close all;
clear all;
clc;
% 报错信息:X 和 Y 必须具有相同的大小和类,或 Y 必须为双精度标量
H=imread('rice.png');
I=imread('cameraman.tif');
J=imread('autumn.tif');
K=imadd(H,I);% imadd函数实现两幅图像的相加,要求这两幅图像大小相等
O=imadd(J,100);% imadd函数实现一幅图像和常量的相加,该常量用来改变图像的亮度,给图像的每个像素值增加常数
subplot(151),imshow(H);
title('原始图像1');
subplot(152),imshow(I);
title('原始图像2');
subplot(153),imshow(K);
title('原始图像1和2相加后的图像');
subplot(154),imshow(J);
title('原始图像');
subplot(155),imshow(O);
title('原始图像与常量相加后的图像');
图像减法也称为差分方法,是一种常用于检测图像变化及运动物体的图像处理方法。常用来检测一系列相同场景图像的差异,其主要的应用在于检测同一场景下两幅图像之间的变化或是混合图像的分离。
在MATLAB图像处理工具箱中提供了函数imsubtract(),可以将一幅图像从另一幅图像中减去,或者从一幅图像中减去一个常数,实现将一幅输入图像的像素值从另一幅输入图像相应的像素值中减去,再将这个结果作为输出图像相应的像素值,其具体的调用格式如下:
% 利用图像减法运算实现DSA减影
A=imread('cameraman.tif');
B=imread('testpat1.png');
C=imsubtract(A,B);% imsubtract函数表示从图像A中减去图像B
subplot(121),imshow(C);% 显示差异图像
title('差异图像');
subplot(122),imshow(255-C);% 显示反色的差异图像
title('反色的差异图像');
两幅图像进行乘法运算主要实现两个功能,一是可以实现掩模操作,即屏蔽图像的某些部分;二是如果一幅图像乘以一个常数因子,如果常数因子大于1,将增强图像的亮度;如果因子小于1则会使图像变暗。在MATLAB图像工具箱中提供了函数immultiply0实现两幅图像的乘法,该函数将两幅图像相应的像素值进行元素对元素的乘法操作(相当于MATLAB中矩阵的点乘),并将乘法的运算结果作为输出图形相应的像素值,其具体的调用格式如下:
% 利用图像乘法运算实现图像亮度的控制
% 一幅图像乘以一个常数,若常数大于1将增强图像亮度,若常数小于1将会使图像变暗
A=imread('cameraman.tif');
B=immultiply(A,1.5);
C=immultiply(A,0.5);
subplot(131),imshow(A);
title('原始图像');
subplot(132),imshow(B);
title('乘以缩放因子1.5后的图像');
subplot(133),imshow(C);
title('乘以缩放因子0.5后的图像');
图像的除法运算给出的是两幅图像相应像素值的变化比率,而不是每个像素的绝对差异,因而图像除法也称为比率变换,常用于校正成像设备的非线性影响。在MATLAB图像处理工具箱中提供了函数imdivide()实现两幅图像的除法,该函数对两幅输入图像的所有相应像素执行元素对元素的除法操作(即MATLAB中矩阵的点除操作),并将得到的结果作为输出图像的相应像素值,其具体的调用格式如下:
% 利用函数imdivide()完成图像除法运算
I=imread('office_1.jpg');
J=imread('office_2.jpg');
D=imdivide(J,I);% 两图像相除(两幅图像比率变换的差异图像)
K=imdivide(J,0.5);% 图像与一个常数相除(可以实现亮度调节)
subplot(221),imshow(I);
title('原始图像1');
subplot(222),imshow(J);
title('原始图像2');
subplot(223),imshow(D);
title('office2与officel相除以后的图像');
subplot(224),imshow(K);
title('office2与常数0.5相除以后的图像');
(1)绝对值差函数imabsdiff()
% 利用函数imabsdiff()实现图像矩阵和数据矩阵的绝对值差
I=imread('cameraman.tif');
% fspecial(type)函数用于产生预定义的滤波器,其中prewitt为水平边缘增强滤波器
% type还有:average均值滤波器、gaussian高斯低通滤波器、laplacian近似二维拉普拉斯运算滤波器、log高斯拉普拉斯运算滤波器、sobel水平边缘增强滤波器等
% filter2(H,X)函数中H为滤波器,X为要滤波的数据,将H放在X上移动进行模板滤波
J=filter2(fspecial('prewitt'),I);% 求滤波后的图像与原图像的绝对值差
K=imabsdiff(double(I),J);
subplot(131),imshow(I);
title('原始图像');
% 注意此处的imshow中的[]
% 为保证精度,经过了运算的图像矩阵I其数据类型会从uint8型变成double型
% 若直接运行imshow(I),发现显示的是一个白色的图像
% 因为imshow()显示图像时对double型是认为在0-1范围内,即大于1时都是显示为白色,而imshow显示uint8型时是0-255范围
% 而经过运算的范围在0-255之间的double型数据就被不正常得显示为白色图像
% 语句imshow(I,[]); %自动调整数据的范围以便于显示
subplot(132),imshow(J,[]);
title('滤波后的图像');
subplot(133),imshow(K,[]);
title('滤波后的图像与原图像绝对值差');
(2)图像求补函数imcomplement()
% 利用函数imcomplement()实现图像矩阵和数据矩阵的求补运算
% IM2=imcomplement(IM),该函数求图像矩阵IM的所有元素求补,结果返回给IM2
% 若IM是二值图像矩阵,求补后相应元素中'0'变'1','1'变'0'
% 若IM是灰度图像或RGB图像,求补结果为IM矩阵数据类型的最大值与对应像素值相减的差值
J=imread('rice.png');
J1=im2bw(J);% im2bw函数将灰度图像转换成二值图像
J2=imcomplement(J);% 求灰度图像的补
J3=imcomplement(J1);% 求二值图像的补
subplot(131),imshow(J1);
title('原始图像的二值图像');
subplot(132),imshow(J2);
title('原始图像的补');
subplot(133),imshow(J3);
title('二值图像的补');
(3)图像运算的线性组合函数imlincomb()
% 使用函数imlincomb可以实现图像的叠加、相减,与常数相乘和相除
I=imread('cameraman.tif');
J=imread('rice.png');
K1=imlincomb(1.0,I,1.0,J);% 两个图像的叠加(可以使用imadd函数)
K2=imlincomb(1.0,I,-1.0,J,'double');% % 两个图像的相减(可以使用imsubtract函数)
K3=imlincomb(2,I);% 将图像的灰度放大2倍
K4=imlincomb(0.5,I);% 将图像的灰度缩小1倍
subplot(141),imshow(K1);
title('两个图像叠加');
subplot(142),imshow(K2);
title('两个图像相减');
subplot(143),imshow(K3);
title('图像乘常数');
subplot(144),imshow(K4);
title('图像除常数');
图像的逻辑运算主要是针对二值图像,以像素对像素为基础进行的两幅或多幅图像间的操作。常用的逻辑运算有与、或、非、或非、与非和异或等。在MATLAB中,提供了逻辑操作符与(&)、或(|) \非(~)和异或(OR)等进行逻辑运算,复杂逻辑运算可通过基本运算推导得到。
% 实现图像的与、或、非及异或运算
% 图像的逻辑运算主要针对二值图像,常用的逻辑运算有与、或、或非、与非和异或等
% 进行逻辑运算的两个图像需大小相等
I=imread('lion.png');
J=imread('lion.png');
I1=im2bw(I); % 将I和J转换为二值图像
J1=im2bw(J);
K1=I1&J1; % 与运算
K2=I1|J1; % 或运算
K3=~I1; % 非运算
K4=xor(I1,J1); % 异或运算
K5=~(I1|J1);% 或非运算
K6=~(I1&J1);% 与非运算
subplot(241),imshow(I1);
subplot(242),imshow(J1);
subplot(243),imshow(K1);
subplot(244),imshow(K1);
subplot(245),imshow(K3);
subplot(246),imshow(K4);
subplot(247),imshow(K5);
subplot(248),imshow(K6);
原始图像为: