图像几何运算——Matlab实现

图像几何运算——Matlab实现

1.图像的平移

定义

图像平移指的是将图像按水平方向或竖直方向上进行移动,其本质就是将图像中的所有像素点都按照给定的平移量进行水平方向或竖直方向上的移动。

设图像空间的x,y正方向分别为向右、向下,初始坐标为 ( x 0 , y 0 ) (x_0,y_0) x0y0的点经过平移 ( Δ x , Δ y ) (\Delta x,\Delta y) ΔxΔy后,其坐标变为 ( x 1 , y 1 ) (x_1,y_1) x1y1,则这两点存在以下关系:
{ x 1 = x 0 + Δ x y 1 = y 0 + Δ y \begin{cases} x_1=x_0+\Delta x\\ y_1=y_0+\Delta y \end{cases} {x1=x0+Δxy1=y0+Δy
其矩阵形式为:
( x 1 y 1 1 ) = ( 1 0 Δ x 0 1 Δ y 0 0 1 ) ( x 0 y 0 1 ) \begin{pmatrix}x_1 \\y_1 \\ 1\end{pmatrix} =\begin{pmatrix} 1 & 0 &\Delta x \\ 0 & 1 & \Delta y\\0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x_0 \\ y_0 \\1 \end{pmatrix} x1y11 = 100010ΔxΔy1 x0y01
注意:此时设定的x,y正方向分别为向右、向下;

Matlab代码实现

  1. 利用平移原理实现,即矩阵的形式

    %% 利用图像平移原理实现图像平移效果,即矩阵的形式
    
    clc;clear;close all;    % 初始化
    I=imread('cameraman.tif');  % 读入一幅图像
    subplot(121);imshow(I);title('原图');
    
    [M,N]=size(I); g=zeros(M,N);    % 创建数组,与原图像矩阵一样大
    a=20;b=20;  % a为水平右移距离;b为垂直下移距离
    for i=1:M
        for j=1:N
            if((i-a>0)&&(i-a<M)&&(j-b>0)&&(j-b<N))  % 从坐标点到新坐标点的映射
                g(i,j)=I(i-a,j-b);
            else
                g(i,j)=0;   %新图像外的点置为0
            end
        end
    end
    subplot(122);imshow(uint8(g));title('平移后的图像');
    

    运行结果如下:
    在这里插入图片描述

  2. 利用Matlab内置的函数实现图像平移

% 图像的平移
close
clc
clear
I=imread('sherlock.jpg');   %读取图片
a=100;b=100;  % 设置平移坐标
se = translate(strel(1),[a,b]); %将一个平面结构化元素平移
J1=imdilate(I,se); %%利用形态学膨胀移动原图像 

a=-100;b=100;  % 再次设置平移坐标
se = translate(strel(1), [a b]);
J2=imdilate(I,se); %再次利用形态学膨胀移动原图像 

a=100;b=-100;  % 再次设置平移坐标
se = translate(strel(1), [a b]);
J3=imdilate(I,se); %再次利用形态学膨胀移动原图像 

a=-100;b=-100;  % 再次设置平移坐标
se = translate(strel(1), [a b]);
J4=imdilate(I,se); %再次利用形态学膨胀移动原图像 

set(0,'defaultFigurePosition',[200,100,1000,500]);  % 修改图形图像设置的默认设置
set(0,'defaultFigureColor',[1,1,1]);   %修改图像背景颜色的设置
subplot(2,3,1),imshow(I);title('原图像');axis on;
subplot(2,3,2),imshow(J1);title('向右下平移');axis on;
subplot(2,3,3),imshow(J2);title('向右上平移');axis on;
subplot(2,3,4),imshow(J3);title('向左下平移');axis on;
subplot(2,3,5),imshow(J4);title('向左上平移');axis on;

运行结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w0FKXGNy-1659447932562)(%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E5%9F%BA%E7%A1%80.assets/1659439381188.png)]

2.图像的镜像

图像的镜像主要分为水平镜像和垂直镜像,镜像变换又称对称变换。设原图的宽为w,高为h,原图中的点为 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),对称变换后的点为 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)

  1. 水平镜像

    图像的水平镜像操作是以图像的垂直中轴线为中心,将图像分为左右两部分镜像对称变换,水平镜像的变换公式为:
    ( x 1 y 1 1 ) = ( − 1 0 w 0 1 0 0 0 1 ) ( x 0 y 0 1 ) \begin{pmatrix}x_1 \\y_1 \\ 1\end{pmatrix}=\begin{pmatrix} -1 & 0 & w \\ 0 & 1 & 0\\0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x_0 \\ y_0 \\1 \end{pmatrix} x1y11 = 100010w01 x0y01
    利用matlab实现代码如下:

    %% 利用镜像的原理,即使用矩阵实现图像的镜像
    
    clc;clear;close all;    % 初始化
    I=imread('cameraman.tif');
    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);  % 垂直镜像同理,将i换为M-i+1即可
        end
    end
    subplot(122);imshow(uint8(g));title('水平镜像');
    

    运行结果如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5nq1ediX-1659521800124)(%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E5%9F%BA%E7%A1%80.assets/1659521174718.png)]

  2. 垂直镜像

垂直镜像是以原图的水平中轴线为中心,将图像分为上下两部分进行对称变换,其变换公式如下:
( x 1 y 1 1 ) = ( 1 0 0 0 − 1 h 0 0 1 ) ( x 0 y 0 1 ) \begin{pmatrix}x_1 \\y_1 \\ 1\end{pmatrix}=\begin{pmatrix} 1 & 0 & 0 \\ 0 & -1 & h\\0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x_0 \\ y_0 \\1 \end{pmatrix} x1y11 = 1000100h1 x0y01
图像的垂直镜像用matlab实现原理同水平镜像类似,只需将水平方向的像素翻转即可。

  1. 利用matlab的函数实现图像的镜像

matlab中可以利用mirror函数实现图像的镜像,但mirror函数在高版本的matlab中已经被移除,可以用flip函数或flipdim函数替代,而flipdim函数不推荐使用,推荐使用flip函数,参数不变

matlab代码如下:

%% 图像的镜像 调用mirror函数实现对原图像的镜像转换
%% 初始化
clear;
close all;
clc;
%% 读入图像并操作
% mirror函数在高版本的matlab中已经被移除,可以用flip函数和flipdim函数替代
% 而flipdim函数不推荐使用,推荐使用flip函数,参数不变
I=imread('cameraman.tif');  %输入图像
J1=flip(I,1);   % 水平镜像,即x镜像
J2=flip(I,2);   % 垂直镜像,即y镜像
J3=flip(J2,1);  % 水平垂直镜像
%% 设置幕布,将图片显示
set(0,'defaultFigurePosition',[200,100,1000,500]);  % 修改图形图像设置的默认设置
set(0,'defaultFigureColor',[1,1,1]);   %修改图像背景颜色的设置
subplot(2,2,1),imshow(I);title('原图像');axis on;
subplot(2,2,2),imshow(J1);title('水平镜像');axis on;
subplot(2,2,3),imshow(J2);title('垂直镜像');axis on;
subplot(2,2,4),imshow(J3);title('水平垂直镜像');axis on;

运行结果如图:
在这里插入图片描述

3.图像的旋转

图像的旋转变换是指以图像的中心为原点,将图像上的所有像素都旋转同一个角度的变换。
注意:图像旋转容易造成图像失真,为了避免图像旋转可能产生的信息丢失,可以先平移,然后再进行图像旋转。图像旋转之后可能出现一些空白点,需要对这些空白点镜像灰度级的插值处理,否则会影响旋转后的质量。

设原图的任意点 A 0 ( x 0 , y 0 ) A_0(x_0,y_0) A0(x0,y0)经旋转角度β后到新的位置 A ( x , y ) A(x,y) A(x,y),为表示方便,采取极坐标形式表示,原始的角度为α。根据极坐标相关知识点可知 A 0 ( x 0 , y 0 ) A_0(x_0,y_0) A0(x0,y0)的坐标为:
{ x 0 = r cos ⁡ α y 0 = r sin ⁡ α \begin{cases} x_0=r\cos \alpha\\y_0=r\sin \alpha \end{cases} {x0=rcosαy0=rsinα
旋转到新位置以后点 A ( x , y ) A(x,y) A(x,y)的坐标为:
{ x = r cos ⁡ ( α − β ) = r cos ⁡ α cos ⁡ β + r sin ⁡ α sin ⁡ β y = r sin ⁡ ( α − β ) = r sin ⁡ α cos ⁡ β − r cos ⁡ α sin ⁡ β \begin{cases} x=r\cos (\alpha-\beta)=r\cos\alpha\cos\beta+r\sin\alpha\sin\beta\\ y=r\sin (\alpha-\beta)=r\sin\alpha\cos\beta-r\cos\alpha\sin\beta \end{cases} {x=rcos(αβ)=rcosαcosβ+rsinαsinβy=rsin(αβ)=rsinαcosβrcosαsinβ
简化为:
{ x = x 0 cos ⁡ β + y 0 sin ⁡ β y = − x 0 sin ⁡ β + y 0 cos ⁡ β \begin{cases} x=x_0\cos \beta+y_0\sin\beta\\ y=-x_0\sin \beta+y_0\cos\beta \end{cases} {x=x0cosβ+y0sinβy=x0sinβ+y0cosβ
矩阵形式表示为:
( x y 1 ) = ( cos ⁡ β sin ⁡ β 0 − sin ⁡ β cos ⁡ β 0 0 0 1 ) ( x 0 y 0 1 ) \begin{pmatrix}x \\y \\ 1\end{pmatrix} =\begin{pmatrix} \cos\beta & \sin\beta & 0 \\ -\sin\beta & \cos\beta & 0\\0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x_0 \\ y_0 \\1 \end{pmatrix} xy1 = cosβsinβ0sinβcosβ0001 x0y01

其matlab代码实现如下:

%% 使用imrotate函数实现图像的旋转

%% 初始化
clc;
close;
clear;

%% 读入图像并操作
I=imread('office_2.jpg');   % 读入图像
% imrotate函数用于旋转图像,正值为逆时针旋转,负值为顺时针
J1=imrotate(I,30);  % 逆时针旋转
J2=imrotate(I,-30); % 顺时针旋转

%设置输出图像大小,实现旋转图像并显示
J3=imrotate(I,30,'bicubic','crop'); % crop输出的图像和原图像保持一致的尺寸,裁剪旋转的图像至合适的大小
J4=imrotate(I,30,'bicubic','loose');% loose输出足够容纳整个旋转图像的图像,通常比原图像大-默认值

%% 设置幕布,将图片显示
set(0,'defaultFigurePosition',[200,100,1000,500]);  % 修改图形图像设置的默认设置
set(0,'defaultFigureColor',[1,1,1]);   %修改图像背景颜色的设置
subplot(2,2,1),imshow(J1);axis on;
subplot(2,2,2),imshow(J2);axis on;
subplot(2,2,3),imshow(J3);axis on;
subplot(2,2,4),imshow(J4);axis on;

运行结果如下:
在这里插入图片描述

注意:代码中涉及到的imrotate函数详解

  1. 作用:
    旋转图像

  2. 句法规则:

    B=imrotate(A,angle)
    B=imrotate(A,angle,method)
    B=imrotate(A,angle,method,bbox)
    gpuarrayB=imrotate(gpuarrayA,)
    
  3. 描述:
    3.1
    B=imrotate(A,angle),将图像A围绕其中心点进行angle角度的逆时针旋转。
    如果想要顺时针旋转的话,则角度取负值,-angle。angle和-(360-angle)旋转角度是一致的
    3.2
    B=imrotate(A,angle,method),利用指定的插值方法method进行图像A的旋转,method是文本字符串,需要引号引出,默认值用大括号{}括起来。
    method包括:
    {‘nearest’}最临近插值-默认值
    'bilinear’双线性的
    'bicubic’双三次的
    3.3
    B=imrotate(A,angle,method,bbox),bbox指定返回图像的尺寸。bbox是文本字符串,默认值需要用大括号{}括起来。
    bbox包括:
    'crop’输出的图像B和输入的图像A保持一致的尺寸,裁剪旋转的图像至合适的大小
    {‘loose’}输出足够容纳整个旋转图像的图像B,图像B通常比图像A大-默认值

    3.4
    gpuarrayB=imrotate(gpuarrayA),通过图形处理器GPU进行旋转操作,gpuarrayA是一个gpuArray对象,其包括一幅灰度或二值图像。输出图像也是一个gpuArrary对象。该句法的使用需要通过并行计算工具箱来实现。

4.图像的缩放

通常情况下,数字图像的比例缩放是指将给定的图像在x方向和y方向按照相同的比例a缩放,从而获得一副新图像,又称为全比例缩放。如果在x方向和y方向缩放的比例不同,则图像的像素间位置会被改变,从而产生几何畸变。

若比例缩放所产生的图像中的像素在原图中没有相应的像素点时,就需要进行灰度级的插值运算,一般有以下两种插值处理方法。

  1. 直接赋值为和它最相近的像素灰度值,这种方法称为最近邻插值法,该方法简单,计算量小,但很可能会产生马赛克现象。
  2. 通过其他的数学插值算法来计算相应像素点的灰度值,这类方法处理效果好,但运算量较大

常用的灰度插值方法

  1. 最近邻法

    最近邻法是取需要插值的点最近的整数坐标点的灰度值,这种方法在各相邻像素点的灰度变化较小时比较好用,方便快捷,但是当相邻像素点灰度变化较大时,这种方法回产生较大的误差。

  2. 双线性插值法

    双线性插值法是对最近邻法的一种改进,即线性内插法,根据需要插值的点的四个相邻点的灰度值,通过插值计算出结果。此法相对最近邻法效果会好一点,但这种方法具有低通滤波性质,使得高频分量受到损失,图像轮廓模糊。

  3. 三次内插法

    三次内插法不仅考虑需要插值的点的直接邻点对他的影响,还考虑到周围16个点的灰度值对他的影响。故该方法精度高,且能较好的保存图像边缘,但计算量较大。

使用这三种方法分别对图像放大如下:

%% 利用matlab内置的imresize函数放大图像
% 分别使用最近邻法、双线性插值法、三次内插法
clc;clear;close all;    % 初始化
I=imread('C:\Users\xcz\Desktop\matlab_example\Images\lena.jpg');
J1=imresize(I,10,'nearest');    % 采用最近邻法放大10倍
J2=imresize(I,10,'bilinear');   % 采用双线性插值法放大10倍
J3=imresize(I,10,'bicubic');    % 采用三次内插法放大10倍
subplot(221);imshow(I);title('原图');axis on;
subplot(222);imshow(J1);title('最近邻法');axis on;
subplot(223);imshow(J2);title('双线性插值法');axis on;
subplot(224);imshow(J3);title('三次内插法');axis on;

运行结果如下:
在这里插入图片描述

代码中涉及到的imresize函数详解:

imresize:调整图像大小

语法

B = imresize(A,scale)
B = imresize(A,[numrows numcols])
[Y,newmap] = imresize(X,map,___)
___ = imresize(___,method)
___ = imresize(___,Name,Value)

说明

B = imresize(A,scale) 返回图像 B,它是将 A 的长宽大小缩放 scale倍之后的图像。输入图像 A 可以是灰度、RGB 或二值图像。如果 A 有两个以上维度,则 imresize只调整前两个维度的大小。如果 scale 在 [0, 1] 范围内,则 B比 A小。如果 scale 大于 1,则 B 比 A 大。默认情况下,imresize 使用双三次插值。
B = imresize(A,[numrows numcols]) 返回图像 B,其行数和列数由二元素向量 [numrows numcols]指定。
[Y,newmap] = imresize(X,map,___) 调整索引图像 X 的大小,其中 map 是与该图像关联的颜色图。默认情况下,imresize 返回经过优化的新颜色图 (newmap) 和已调整大小的图像。要返回与原始颜色图相同的颜色图,请使用 ‘Colormap’ 参数。

_ = imresize(_,method) 指定使用的插值方法。

_ = imresize(_,Name,Value)返回调整大小后的图像,其中 Name,Value 对组控制大小调整操作的各个方面。

方法说明
‘nearest’最近邻插值;赋给输出像素的值就是其输入点所在像素的值。不考虑其他像素。
‘bilinear’双线性插值;输出像素值是最近 2×2 邻点中的像素的加权平均值
‘bicubic’双三次插值;输出像素值是最近 4×4 邻点中的像素的加权平均值
注意:双三次插值可能生成在原始范围之外的像素值。
  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值