基于matlab的数字图像基本处理运算

一、实验目的

(1)掌握线性拉伸和非线性拉伸的概念实现方法

(2)掌握图像代数运算的概念和实现方法

(3)掌握图像放大、缩小、平移、镜像、旋转原理和实现方法

(4)掌握最邻近插值和双线性插值在几何变换中的应用

二、实验仪器(软件平台)

计算机,Matlab软件

三、实验原理

原图像f,新图像g。

1、灰度线性变换

g(x,y)=a*f(x,y)+b;通过不同的a值和b值来对图像进行灰度变换。

2、灰度拉伸

(1)灰度拉伸变换

利用归一化公式f-minmax-min把图像矩阵进行归一化,在通过给定的拉伸参数,把灰度值重新映射到拉伸参数的范围中。

(2)对数变换

对数变换公式gx,y=clg(1+f(x,y)),c是一个常数。对数变换的作用是对原图像的灰度值动态范围进行压缩,主要用于调高输入图像的低灰度值。

(3)拉伸函数imadjust()

img=imadjust( I,[low_in;high_in],[low_out;high_out],gamma)中[low ,high]是增强前灰度级范围,[bottom,top]是增强后灰度级范围,参数gamma指定了曲线的形状,该曲线用来映射I的亮度值。如果gamma小于1,映射被加权到更高的输出值。如果gamma大于1,映射被加权到更低的输出值。如果省略了函数的参量,则gamma默认为1(线性映射)。

3、放大缩小

基于matlab的数字图像基本处理运算_第1张图片

 

4、平移

设初始坐标为(x0,y0)的像素平移(∆x,∆y)后的坐标为(x1,y1),如下所示,

       

 

5、镜像

设图像高度为h,宽度为w。

 

图 1 水平镜像

基于matlab的数字图像基本处理运算_第2张图片

图 2垂直镜像

                                                                                   

6、旋转

基于matlab的数字图像基本处理运算_第3张图片  基于matlab的数字图像基本处理运算_第4张图片

 

 

基于matlab的数字图像基本处理运算_第5张图片

 

7、最近邻插值

这是最简单的一种插值方法,不需要计算,在待求像素的四邻像素中,将距离待求像素最近邻的像素灰度值赋给待求像素。最近邻插值法虽然计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。

基于matlab的数字图像基本处理运算_第6张图片 这是非整数倍放大图像的最近邻插值的计算方法。

8、双线性插值

基于matlab的数字图像基本处理运算_第7张图片

9、三次差值

三次插值法求一个三次的方程。它的思想就是把已知的数分为一个一个小区间,人拟合到曲线上去。就是一个多分段函数高阶函数(此处的阶数为3)。

基于matlab的数字图像基本处理运算_第8张图片

(1)任意选择几幅图像,对其进行灰度线性变换,结合以下情况分析输入图像和输出图像两者有何变化。

基于matlab的数字图像基本处理运算_第9张图片

clc;clear;
close all
%y=a*r+b/255;中r是8位整型,b/255debianhua太小了,会直接被舍弃,解决方法1:把r改为double型
%解决方法2:b/255改为b,b取值大一点,100,50,不要10那么小
%r = imread('D:\Matlab\toolbox\images\imdata\yellowlily.jpg'); 
%r = imread('g:\图片\相册\微信图片_20200611154901.jpg');
r = imread('yellowlily.jpg');
subplot(4,2,1);
imshow(r);title('yuantu');
a=2;b=10;y=a*r+b;subplot(4,2,2);imshow(y);title('y a>1');

a=0.5;b=10;y1=a*r+b;subplot(4,2,3);imshow(y1);title('y1 a<1');

a=1;b=-50;y2=a*r+b;subplot(4,2,4);imshow(y2);title('y2 a=1,b<0');

a=1;b=50;y3=a*r+b;subplot(4,2,5);imshow(y3);title('y3 a=1,b>0');

a=1;b=0;y4=a*r+b;subplot(4,2,6);imshow(y4);title('y4 a=1,b=0');

a=-1;b=255;y5=a*r+b/5;subplot(4,2,7);imshow(y5);title('y5 a=-1,b=255');

 (2)选择几幅图像,对其进行灰度拉伸,选择不同的拉伸参数,观察图像与原图有何不同,总结灰度拉伸的原理。

%% 1.图像灰度拉伸主程序代码
%图像灰度拉伸主程序及拉伸函数代码
clc;clear all;close all;
img1 = imread('indiancorn.jpg');
img1 = rgb2gray(img1);
para = [0,60];
img_lena2 = my_Gray_Scale_T(img1, para);
para = [60,128];
img_lena3 = my_Gray_Scale_T(img1, para);
para = [100,250];
img_a4 = my_Gray_Scale_T(img1, para);
%显示图像
figure(1); 
subplot(2,2,1);imshow(img1);title('原始图像');
subplot(2,2,2);imshow(img_lena2);title('拉伸至0~60');
subplot(2,2,3);imshow(img_lena3);title('拉伸至60~128');
subplot(2,2,4);imshow(img_a4);title('拉伸至100~250');

%% 2.图像灰度非线性拉伸(对数拉伸)程序
% 灰度非线性拉伸之对数拉伸程序
 C_img=imread('onion.png');  
 Img=rgb2gray(C_img);
 figure(2);
 subplot(1,2,1),imshow(Img); title('原始灰度图像');
 J=double(Img);%double类型--计算
 Img_log=40*(log(J+1));%对数变换 clog(f(x,y)+1)
 Img_gen=uint8(Img_log);%转为uint8类型--图像
 subplot(1,2,2),imshow(Img_gen);title(' 对数变换图像');
 
 %% 3.使用MATLAB函数imadjust拉伸
% 使用MATLAB函数imadjust拉伸
% 对灰度图像进行直接灰度变换;
%I为增强前灰度图像,J为增强后的灰度图像
%[low high]增强前灰度级范围
%[bottom top]增强后灰度级范围
% img=imadjust( I,[low_in;high_in],[low_out;high_out],gamma)
% 该gamma参数为映射的方式,默认值为1,即线性映射。当gamma不等于1时为非线性映射
%将图像I中low_in至high_in之间的值映射到low_out至high_out之间,而low_in以下和high_in以上的值被剪切掉。
%输入图像I应该为uint8、uint16或double类的灰度图像,输出图像J与输入图像I类型相同。
%参数gamma指定了曲线的形状,该曲线用来映射I的亮度值。如果gamma小于1,映射被加权到更高的输出值。
%如果gamma大于1,映射被加权到更低的输出值。如果省略了函数的参量,则gamma默认为1(线性映射)。
Img01=imread('yellowlily.jpg');
img=rgb2gray(Img01);
bw1=im2bw(img,0.8);%转为二值图像,level=0.8,--level*255--超过255*level的赋值255,否则赋值0
New_img=imadjust(img,[0.1 0.6], [0 1],0.5);%把[0.1,0.6]之间的值映射到【0,1】之间
bw=im2bw(New_img,0.8);%把拉伸新得到的图像转为二值图像
bw=medfilt2(bw);%中值滤波 
figure(3)
subplot(1,3,1);imshow(Img01);title('原始图像');
subplot(1,3,2);imshow(bw1);title('二值图像');
subplot(1,3,3);imshow(bw);title('过中值滤波的二值图像');
 
%% 3.图像放缩程序代码
%axis on--显示坐标
I=imread('x.jpg');
figure(4);
subplot(231);imshow(I);title('原图');
J1=imresize(I,0.5,'nearest');
subplot(232);imshow(J1);title('放大图');
J2=imresize(I,2,'nearest');
subplot(233);imshow(J2);title ('缩小图');
J3=imresize(I,[620,380],'nearest');
subplot(234);imshow(J3);axis on;title ('非比例放大图');
J4=imresize(I,[80,180],'nearest');
subplot(235);imshow(J4);title ('非比例缩小缩小图');

%% 4.图像镜像变换程序
% 图像镜像变换程序
clc;clear 
Img=imread('x.jpg');
[M,N]=size(Img);
Img_Horizontal=Img;%Horizontal 水平 x1=x0;y1=w-y0,w水平长度--列
for i=1:M
    for j=1:N
        Img_Horizontal(i,j)=Img(i,N-j+1);
    end
end
figure(5);
subplot(2,2,1);imshow(Img);title('原始图像');
subplot(2,2,2);imshow(Img_Horizontal);title('水平镜像');
Img_vertical=Img;%垂直,x1=h-x0,y1=y0,h图像的高--行
for i=1:M
    for j=1:N
        Img_vertical(i,j)=Img(M-i+1,j);
    end
end
subplot(2,2,3);imshow(Img_vertical);title('垂直镜像');

%% 5.图像旋转程序
% 图像旋转程序代码
%B=imrotate(A,angle,method,bbox)---将图像A以原点为中心按照angle角度进行旋转,旋转时采用method的方法进行插值,bbox为旋转之后图像的大小。
%angle大于0,逆时针方向旋转;angle小于0,顺时针方向旋转。
%method---‘nearest’最近邻插值(默认),'bilinear’双线性插值,‘bicubic’双三次插值
%bbox---‘crop’表示输出图像与输入图像大小相等,旋转后的图像进行剪裁;‘loose’表示能将完整旋转图像容下的足够大的图像。
Img=imread('tree.png');
figure(6);
subplot(221);imshow(Img);title('原始图像');
I1=imrotate(Img,30);                  %旋转30°
I2=imrotate(Img,30,'crop');           %旋转30°并剪切图像,使旋转后的图像和原图像大小一致
I3=imrotate(Img,30,'bilinear','crop');%双线性插值法旋转30°并剪切图像,使图像和原图像大小一致
subplot(222);imshow(I1);title('原图像旋转30°');
subplot(223);imshow(I2);title('原图像旋转30°并剪切');
subplot(224);imshow(I3);title('基于双线性插值旋转30°并剪切');
 
%% 6.使用matlab函数的图像旋转与灰度插值实验
%使用matlab函数的图像旋转与灰度插值实验
%常用不同插值方法比较
clc;clear 
img = imread('women.jpg'); 
rotateimg1=imrotate(img,45,'nearest');   %最邻近插值 
rotateimg2=imrotate(img,-45,'bilinear'); %双线性插值 
rotateimg3=imrotate(img,45,'bicubic');   %三次插值 
figure(7);
subplot(2,2,1);imshow(img); title('原始图像'); 
subplot(2,2,2);imshow(rotateimg1); title('最邻近插值'); 
subplot(2,2,3);imshow(rotateimg2); title('双线性插值'); 
subplot(2,2,4);imshow(rotateimg3); title('高阶插值');

%% 7.图像错切变换程序
%Matlab实现图像错切源代码
im=(imread('onion.png'));
figure(8);
subplot(2,2,1);imshow(im);title('原始图像');
im1=rgb2gray(im);
subplot(2,2,2);imshow(im1);title('灰度图像');
[row,col]=size(im1); %获取行数 和 列数
%图像的水平错切
G=zeros(row,col);
a=pi/6; %水平错切30度
b=tan(a);
for m=1:row
for n=1:col
G(round(m+b*n),n)=im1(m,n);
end
end
subplot(2,2,3);imshow(uint8(G));title('垂直错切图像');
G=zeros(row,col);
a=pi/6; %水平错切30度
b=tan(a);
for m=1:row
for n=1:col
G(n,round(m+b*n))=im1(m,n);
end
end
subplot(2,2,4);imshow(uint8(G));title('水平错切30度图像');

%% 自定义拉伸函数
%拉伸函数代码   ----函数定义需要在文件结尾
function img = my_Gray_Scale_T(img, para)
    a = para(1);
    b = para(2);
    if(a > b)
        error('para参数,最小灰度值a不能超过最大灰度值b!');
    elseif(a < 0 || b > 250)
        error('para参数,最小灰度值a和最大灰度值b的范围在0~255!');
    end
    img_norm = im2double(img);% uint8转换为double,并将0~255范围归一化为区间0~1
    img_min = min(img_norm(:));%(:)将每一列合并成一个长列
    img_max = max(img_norm(:));%从一个长列里选出最大值
    %(矩阵每个元素减去最小值)点除(最大值减去最小值)----归一化?----原本的值占总的
    img = (img_norm - img_min)./(img_max - img_min);%将图片压缩到0~1之间的数值
    %(区间最大值减最小值)点乘上一步得到的归一化+区间a,---根据归一化得到的权值在[a,b]上分配灰度值
    img = (b - a) .* img + a;           %像素值还原到原para区间
    img = uint8(img);                   %灰度转换为uint8的格式
end


 实验结果

基于matlab的数字图像基本处理运算_第10张图片

图 12 灰度线性变换

基于matlab的数字图像基本处理运算_第11张图片

图 13 灰度拉伸

基于matlab的数字图像基本处理运算_第12张图片

图 14 对数变换

基于matlab的数字图像基本处理运算_第13张图片

图 15 imadjust拉伸函数

基于matlab的数字图像基本处理运算_第14张图片

图 16 比例缩放和非比例缩放

基于matlab的数字图像基本处理运算_第15张图片

图 17 镜像

基于matlab的数字图像基本处理运算_第16张图片

图 18 旋转并剪切

基于matlab的数字图像基本处理运算_第17张图片

图 19 旋转不剪切

基于matlab的数字图像基本处理运算_第18张图片

图 20 错切

由图 12可得如果a>1,输出图像的对比度增大,即图像变得更亮;如果a<1,输出图像的对比度减小,即图像变得更暗;如果a=1,b<0,输出图像整体上是变暗了,但是亮的地方与暗的地方存在一定的对比度;如果a=1,b>0,输出图像整体变亮,明暗对比度减低;如果a=1,b=0,输出图像没有变化;如果a=1,b=255,输出图像变暗,看不清物体形状。

图 18看到图像旋转后大小不变,但是经旋转而离开画面的部分被剪切,而图 19中的图像旋转后没有被剪切图像,但是图像大小出现变化。

图19可以看出通过最近邻插值法的图像在灰度变化的地方存在明显的锯齿状,程度是三个插值法中最严重的,双线性插值法也存在轻微的锯齿问题,但是比最近邻插值要细微些,而三次多项式插值法最效果最好的一个。

你可能感兴趣的:(计算机视觉,图像处理,人工智能,matlab)