图像基本运算
图像处理是建立在各种算法基础上的处理方法,图像基本运算主要包括点运算、代数运算(加、减、乘、除)、逻辑运算(与、或、非)和几何运算(平移、镜像、旋转、缩放)。这些基本运算都具有十分重要的意义,如:改变输入图像的灰度级、降低图像的噪声、进行各种各样的几何变换。
1、点运算(Point Operation)
点运算是对图像的每个像素点的灰度值按一定的映射关系运算,得到一福新图片的过程。由于点运算能够有规律的改变像素点的灰度值,故也被称为对比度增强或灰度变换。
1.1线性点运算
线性点运算是指输入图像的灰度级与输出图像呈线性关系。
s=ar+b
(r为输入灰度值,s为相应点的输出灰度值)。
当a=1,b=0时,新图像与原图像相同;
当a=1,b≠0时,新图像是原图像所有像素的灰度值上移或下移,是整个图像在显示时更亮或更暗;
当a>1时,新图像对比度增加;
当a<1时,新图像对比度降低;
当a<0时,暗区域将变亮,亮区域将变暗,点运算完成了图像求补;
MATLAB程序如下:
I=imread('E:\my photo and video\1.jpg');
I=im2double(I);
figure(1);subplot(3,2,1);
imshow(I);
title('原图像','fontsize',7);
a=1;
b=50;
O=a.*I+b/255;
figure(1);
subplot(3,2,2);
imshow(O);title('a=1,b=50,图像变亮','fontsize',7);
a=2;b=0;
O=a.*I+b/255;
figure(1);subplot(3,2,3);imshow(O);
title('a=2,b=0,对比度增大','fontsize',7);
a=0.5;b=0;
O=a.*I+b/255;
figure(1);subplot(3,2,4);imshow(O);
title('a=0.5,b=0,对比度降低','fontsize',7);
a= -1;b=255;
O=a.*I+b/255;
figure(1);subplot(3,2,5);imshow(O);
title('a=-1,b=255,图像反色','fontsize',7);
运行结果:
注:代码中O=a.*I+b/255 ,b除以255原因是: 灰度数据有两种表式方法:一种是用unit8类型,取值0~255;另一种是double类型,取值0~1。两者之间相差255倍。 就这段代码而言,I刚读入时是unit8类型,在第2句转换为double,所以后面涉及到与它进行运算的时候,为了统一,都要转换到0~1的范围,所以要除255。
1.2非线性点运算(Non-Linear Point Operation):
非线性点运算是指输入与输出为非线性关系,常见的非线性灰度变换为对数变换和幂次变换,对数变换一般形式为:
s=clog(1+r)
其中c为一常数,并假设r≥0.此变换使窄带低灰度输入图像映射为宽带输出值,相对的是输出灰度的 高调整。
MATLAB程序如下:
I=im2double(I);
figure(1);subplot(1,2,1);
imshow(I);
title('原图像','fontsize',7);
c=2;
O=c*log(1+I);
figure(1);subplot(1,2,2);imshow(O);
title('c>0','fontsize',7);
幂次变换一般形式:s=cr^γ
幂级数γ部分值把窄带暗值映射到宽带输出值
MATLAB程序如下:
I=imread('E:\my photo and video\1.jpg');
subplot(2,2,1);
imshow(I);
title('原图像','fontsize',9);
subplot(2,2,2);
imshow(imadjust(I,[],[],0.1));
title('Gamma=0.1');
subplot(2,2,3);
imshow(imadjust(I,[],[],1));
title('Gamma=1');
subplot(2,2,4);
imshow(imadjust(I,[],[],10));
title('Gamma=10');
运行结果:
2、代数运算(Algebra and Logical Operation)
代数运算是指对两幅或两幅以上的图像进行点对点的加、减、乘、除运算而得到目标图像的运算。
2.1加法运算
对M幅图片进行求平均,使图像每一点的信噪比提高了M倍。加法运算可以用来降低图片的噪声。
I=imread('E:\my photo and video\1.jpg');
J=imnoise(I,'gaussian',0.02);
subplot(131);imshow(I);title('原图')
subplot(132);imshow(J);title('加噪')
for i=1:100
J=imnoise(I,'gaussian',0.02);
J1=im2double(J);
J2=J1;
J2=J2+J1;
end
J2=J2/101;
subplot(133);imshow(J2);title('去噪');
?
2.2减法运算
减法运算又称为图像差分运算,主要用于提取噪声,在短时间内认为背景是固定的,可用差分法检测变换的或运动的物体。
如下给出提取图片高斯噪声的例子。
MATLAB代码:
I=imread('E:\my photo and video\1.jpg');
J=imnoise(I,'gaussian',0,0.02);%给图像加高斯噪声
K=imsubtract(I,J);%原始图片与添加噪声的图片相减从而提取出噪声
K1=255-K;
figure;imshow(I);title('原始图像');
figure;imshow(J);title('有噪声图像');
figure;imshow(K1);title('提取噪声')
运行结果:
注:加噪声
加高斯噪声:
1、J = imnoise(I,'gaussian',0,10);
2、使用randn加高斯噪声:I=imread('E:\my photo and video\2.jpg');
J=rgb2gray(I);
y=randn(size(J));
y=y/std(y);
y=y-mean(y);
a=0;
b=sqrt(5);
y=a+b*y;
y=uint8(I);
y=y+I;
figure;imshow(I);
figure;imshow(y);
加椒盐噪声:J= imnoise(I,'salt & pepper',0.1);
2.3乘法运算
简单的乘法运算可以用来改变灰度级,实现灰度级变换,也可以用来遮住图像的某些部分。
MATLAB代码:
I=imread('E:\my photo and video\1.jpg');
J=immultiply(I,1.2);
K=immultiply(I,2);
subplot(131);imshow(I);title('原始图像');
subplot(132);imshow(J);title('x1.2');
subplot(133);imshow(K);title('x2');
运行结果:
2.4除法运算
简单的除法运算可用于改变图像灰度级,典型运用是比值图像处理。可用于校正成像设备的非线性影响,在特殊形态图像(如CT为代表的医学图像)中用到。
3、逻辑运算
常见的逻辑运算有与、或、非,其主要针对二值图像。
A=zeros(128);
A(40:67,60:100)=1;
figure(1);imshow(A);title('A');
B=zeros(128);B(50:80,40:70)=1;
figure(2);imshow(B);title('B');
C=and(A,B);figure(3);imshow(C);title('A and B');
D=or(A,B);figure(4);imshow(D);title('A or B');
E=not(A,B);fgure(5);imshow(E);title('A not B');
运行结果:
4、几何运算
从变换的性质来分,几何变换可以分为图像的位置变换(平移、镜像、旋转)、形状变换(放大、缩小)及图像的复合变换等。一个几何运算需要两个独立的算法,首先需要一个算法定义空间变换,用它描述每个像素如何从其初始位置移动到终止位置,即每个像素的运动。同时还需要一个算法用于灰度级的差值。
4.1图像平移
MATLAB:
I=imread('E:\my photo and video\2.jpg');
subplot(121);
imshow(I);
title('原图像');
[M,N]=size(I);
g=zeros(M,N);
a=20;b=20;
for i=1:M
for j=1:N
if((i-a>0)&(i-a0)&(j-b
运行结果:
4.2图像的镜像(Image Mirror)
图像的镜像是指原始图像相对于某一参考面旋转180°的图像。
4.2.1水平镜像
以图像垂直中轴线为中心,将图像分为左右两部分镜像对称变换
MATLAB:
I=imread('E:\my photo and video\2.jpg');
subplot(121);
imshow(I);
title('原始图像');
[M,N]=size(I);
g=zeros(M,N);
for i=1:M
for j=1:N
g(i,j)=I(i,N-j+1);
end
end
subplot(122);imshow(uint8(g));title('水平镜像')
运行结果:
4.2.2垂直镜像
I=imread('E:\my photo and video\2.jpg');
subplot(121);
imshow(I);
title('原图像');
[M,N]=size(I);
g=zeros(M,N);
a=20;b=20;
for i=1:M
for j=1:N
if((M-i>0)&(N-j>0))
g(i,j)=I(M-i,N-j);
else
g(i,j)=0;
end
end
end
subplot(122);imshow(uint8(g));title('垂直镜像图像')
运行结果:
4.3图像的旋转(Image Rotation)
I=imread('E:\my photo and video\2.jpg');
J=imrotate(I,60,'bilinear');
K=imrotate(I,60,'bilinear','crop');
subplot(131),imshow(I);subplot(132),imshow(J);
subplot(133),imshow(K);
运行结果:
注:imrotation用法:
imrotation(A,angle,' method','BBox')
1、angle是旋转的角度,在matlab默认的是逆时针旋转的。
2、method 就是实现旋转用的方法。有三种:最邻近插值法 、双线性插值法、 三次卷积插值法,英语表示就是 'nearest' 'bilinear' 'bicubic'
3、bbox主要分为2种,一个是‘loose’ 另外一个是‘crop’
loose 就是宽松的意思 顾名思义就是说 图像旋转后 系统会给予一个宽松的环境去匹配它,这样得到的图片就是一个完整的图片
crop 就是剪切,为什么旋转后图像变小了,因为matlab默认的是crop 超过图片原来大小的部分被crop了
4.4图像的缩放
图像缩小变换时在已知的图像信息中以某种方式选择需要保留的信息(取原图像的偶数行或奇数行),但是,图像的放大变换则需要对图像尺寸经放大后多出来的像素点进行赋值,这些点在原始图像上没有直接对应点,需要通过计算进行估计。计算方法有两种:以(0,0.5)为例(1)取(0,0)为(0,0.5)的像素。(2)取(0,1)为
(0,0.5)的像素点。
4.5灰度插值
灰度插值法用来提高图片的质量,其方法有三种:最近邻法、双线性插值法、三次内插法。
(1)最近邻法:将(uo,vo)点最近的整数坐标(u,v)点的灰度值取为(uo,vo)
优:简单快捷
缺:当相邻像素间灰度差很大时,这种灰度估计法将产生较大误差。
(2)双线性插值法:根据四个相邻点的值计算出(uo,vo)的值。
f(uo,vo)=[f(u+1,v)-f(u,v)]α +[f(u,v+1)-f(u,v)]β +[f(u+1,v+1)+f(u,v)-f(u,v+1)-f(u+1,v)]α β +f(u,v)
优:能得到满意的插值效果
缺:此法具有低通滤波性质,使高频分量受到损失,图像轮廓模糊。
(3)三次插值:不仅考虑(uo,vo)点的直接影响,还考虑到该点周围16个邻点的灰度值对其的影响。
优:能精确地恢复原函数
缺:计算量大
以下是用三种不同插值方法进行图片的放大比较,MATLAB如下
I=imread('E:\my photo and video\1.jpg');
J1=imresize(I,10,'nearest');%最近邻法放大10倍
J2=imresize(I,10,'bilinear');%双线性法放大10倍
J3=imresize(I,10,'bicubic');%三次内插法放大10倍
figure;
imshow(I);
title('原图');
figure;
imshow(J1);
title('最近邻法');
figure;
imshow(J2);
title('双线性法');
figure;
imshow(J3);
title('三次内插法');
运行结果:
双线性插值法MATLAB代码实现
m=2; %放大或缩小的高度
n=2; %放大或缩小的宽度
img=imread('E:\my photo and video\1.jpg');
imshow(img);
[h w]=size(img);
imgn=zeros(h*m,w*n);
rot=[m 0 0;0 n 0;0 0 1]; %变换矩阵
for i=1:h*m
for j=1:w*n
pix=[i j 1]/rot;
float_Y=pix(1)-floor(pix(1));
float_X=pix(2)-floor(pix(2));
if pix(1) < 1 %边界处理
pix(1) = 1;
end
if pix(1) > h
pix(1) = h;
end
if pix(2) < 1
pix(2) =1;
end
if pix(2) > w
pix(2) =w;
end
pix_up_left=[floor(pix(1)) floor(pix(2))]; %四个相邻的点
pix_up_right=[floor(pix(1)) ceil(pix(2))];
pix_down_left=[ceil(pix(1)) floor(pix(2))];
pix_down_right=[ceil(pix(1)) ceil(pix(2))];
value_up_left=(1-float_X)*(1-float_Y); %计算临近四个点的权重
value_up_right=float_X*(1-float_Y);
value_down_left=(1-float_X)*float_Y;
value_down_right=float_X*float_Y; %按权重进行双线性插值
imgn(i,j)=value_up_left*img(pix_up_left(1),pix_up_left(2))+value_up_right*img(pix_up_right(1),pix_up_right(2))+ value_down_left*img(pix_down_left(1),pix_down_left(2))+ value_down_right*img(pix_down_right(1),pix_down_right(2));
end
end
figure,imshow(uint8(imgn))