数字图像处理-Matlab实现图像的几何变换

目录

 

图像的平移

图像的旋转

图像的切变

图像的镜像

上述函数的测试脚本

结果


图像的平移

function OutImage = ImageShiftFun(InputImage,deltaX,deltaY,method)
%================================================================
% 功能:图像的x轴和y轴平移
% 参数:InputImage为输入单通道图像,deltaX为x轴平移量,deltaY为y轴平移量。
%method=1时采取向前映射,method=2时采取向后映射
% 返回值:OutImage为InputImage同维数组
% 主要思路:利用平移矩阵
% 备注:如果图像为多通道则需要重复调用
%        如果平移量为小数则采用邻域插值
% 调用方法:OutImage = ImageShiftFun(InputImage,deltaX,deltaY)
% 日期:2019.11.26
% 作者:Leetion
[iLimit,jLimit] = size(InputImage);
switch method
    case 1
        OutImage = zeros(iLimit, jLimit);
        ShiftArray = [1 0 deltaX; 0 1 deltaY; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                InIndex= [xIndex;yIndex;1];
                OutIndex = ShiftArray*InIndex; 
                xOutIndex = round(OutIndex(1,1));
                yOutIndex = round(OutIndex(2,1));
                if (yOutIndex<=iLimit)&(xOutIndex <= jLimit)&(yOutIndex >= 1)&(xOutIndex >= 1)
                    OutImage(yOutIndex,xOutIndex) = InputImage(yIndex,xIndex);
                end
            end
        end
    case 2
        OutImage = zeros(iLimit, jLimit);
        ShiftArray = [1 0 -deltaX; 0 1 -deltaY; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                OutIndex = [xIndex;yIndex;1];
                InIndex = ShiftArray*OutIndex; %矩阵乘法
                xInIndex = round(InIndex(1,1));
                yInIndex = round(InIndex(2,1));
                if (yInIndex<=iLimit)&(xInIndex<=jLimit)&(yInIndex>=1)&(InIndex>=1)
                    OutImage(yIndex,xIndex) = InputImage(yInIndex,xInIndex);
                end
            end     
        end
    otherwise
        warning("method只能取1或2");
end
end

图像的旋转

function OutImage = ImageRotateFun(InputImage,x0,y0,theta,method)
%================================================================
% 功能:以任意中心点,任意角度旋转图像
% 参数:InputImage为输入单通道图像,(x0,y0)为旋转中心,theta为旋转角度,顺时针为正,单位为度。
%method=1时采取向前映射,method=2时采取向后映射
% 返回值:OutImage为InputImage同维数组
% 主要思路:利用旋转矩阵
% 备注:如果图像为多通道则需要重复调用
%       method1会因为向前映射出现马赛克
%       采用邻域插值
% 调用方法:OutImage = ImageRotateFun(InputImage,x0,y0,theta,method)
% 日期:2019.11.26
% 作者:Leetion
theta = theta*pi/180;
[iLimit,jLimit] = size(InputImage);
switch method
    case 1
        OutImage = zeros(iLimit, jLimit);
        RotateArray = [cos(theta) -sin(theta) x0;sin(theta) cos(theta) y0; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                InIndex= [xIndex-x0;yIndex-y0;1];
                OutIndex = RotateArray*InIndex; 
                xOutIndex = round(OutIndex(1,1));
                yOutIndex = round(OutIndex(2,1));
                if (yOutIndex<=iLimit)&(xOutIndex <= jLimit)&(yOutIndex >= 1)&(xOutIndex >= 1)
                    OutImage(yOutIndex,xOutIndex) = InputImage(yIndex,xIndex);
                end
            end
        end
    case 2
        OutImage = zeros(iLimit, jLimit);
        RotateArray = [cos(theta) sin(theta) x0;-sin(theta) cos(theta) y0; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                OutIndex = [xIndex-x0;yIndex-y0;1];
                InIndex = RotateArray*OutIndex;
                xInIndex = round(InIndex(1,1));
                yInIndex = round(InIndex(2,1));
                if (yInIndex<=iLimit)&(xInIndex <= jLimit)&(yInIndex >= 1)&(InIndex >= 1)
                    OutImage(yIndex,xIndex) = InputImage(yInIndex,xInIndex);
                end
            end
            
        end
    otherwise
        warning("method只能取1或2");
end
end

图像的切变

function OutImage = ImageRateFun(InputImage,x0,y0,RateX,RateY,method)
%================================================================
% 功能:水平垂直切变
% 参数:InputImage为输入单通道图像,(x0,y0)为旋转中心,theta为旋转角度,逆时针为正,单位为度。
%method=1时采取向前映射,method=2时采取向后映射
% 返回值:OutImage为InputImage同维数组
% 主要思路:利用旋转矩阵,使用最近插值
% 备注:如果图像为多通道则需要重复调用
%       method1会因为向前映射出现马赛克
%       采用邻域插值
% 调用方法:OutImage = ImageRotateFun(InputImage,x0,y0,theta,method)
% 日期:2019.11.26
% 作者:Leetion
[iLimit,jLimit] = size(InputImage);
switch method
    case 1
        OutImage = zeros(iLimit, jLimit);
        RateArray = [RateX 0 x0;0 RateY y0; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                InIndex= [xIndex-x0;yIndex-y0;1];
                OutIndex = RateArray*InIndex; 
                xOutIndex = round(OutIndex(1,1));
                yOutIndex = round(OutIndex(2,1));
                if (yOutIndex<=iLimit)&(xOutIndex <= jLimit)&(yOutIndex >= 1)&(xOutIndex >= 1)
                    OutImage(yOutIndex,xOutIndex) = InputImage(yIndex,xIndex);
                end
            end
        end
    case 2
        OutImage = zeros(iLimit, jLimit);
       RateArray = [1/RateX 0 x0;0 1/RateY y0; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                OutIndex = [xIndex-x0;yIndex-y0;1];
                InIndex = RateArray*OutIndex; 
                xInIndex = round(InIndex(1,1));
                yInIndex = round(InIndex(2,1));
                if (yInIndex<=iLimit)&(xInIndex <= jLimit)&(yInIndex >= 1)&(InIndex >= 1)
                    OutImage(yIndex,xIndex) = InputImage(yInIndex,xInIndex);
                end
            end
            
        end
    otherwise
        warning("method只能取1或2");
end
end

图像的镜像

function OutImage = ImageMirrorFun(InputImage,Direction)
%================================================================
% 功能:图片镜像
% 参数:InputImage为输入单通道图像
% Direction=1时x方向镜像,Direction=2时y方向镜像
% 返回值:OutImage为InputImage同维数组
% 主要思路:利用镜像矩阵
% 备注:如果图像为多通道则需要重复调用
% 调用方法:OutImage = ImageMirrorFun(InputImage,Direction)
% 日期:2019.11.26
% 作者:李习银
[iLimit,jLimit] = size(InputImage);
switch Direction
    case 1
        OutImage = zeros(iLimit, jLimit);
        MirrorArray = [-1 0 iLimit+1;0 1 0; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                InIndex= [xIndex;yIndex;1];
                OutIndex = MirrorArray*InIndex; 
                xOutIndex = round(OutIndex(1,1));
                yOutIndex = round(OutIndex(2,1));
                if (yOutIndex<=iLimit)&(xOutIndex <= jLimit)&(yOutIndex >= 1)&(xOutIndex >= 1)
                    OutImage(yOutIndex,xOutIndex) = InputImage(yIndex,xIndex);
                end
            end
        end
    case 2
        OutImage = zeros(iLimit, jLimit);
        MirrorArray = [1 0 0;0 -1 jLimit+1; 0 0 1];
        for yIndex = 1:iLimit
            for xIndex = 1:jLimit
                InIndex= [xIndex;yIndex;1];
                OutIndex = MirrorArray*InIndex; 
                xOutIndex = round(OutIndex(1,1));
                yOutIndex = round(OutIndex(2,1));
                if (yOutIndex<=iLimit)&(xOutIndex <= jLimit)&(yOutIndex >= 1)&(xOutIndex >= 1)
                    OutImage(yOutIndex,xOutIndex) = InputImage(yIndex,xIndex);
                end
            end
        end
    otherwise
        warning("method只能取1或2");
end
end

上述函数的测试脚本

%================================================================
% 功能:几何变换
% 主要思路:
% 备注:
% 日期:2019.11.26
% 作者:Leetion
clc,clear
close all
InputImage = imread('cameraman.tif'); 
deltaX = 50;
deltaY = 100;
theta = 10;
ShiftImage = ImageShiftFun(InputImage,deltaX,deltaY,2);
RotateImage = ImageRotateFun(InputImage,128.5,128.5,theta,2);
MirrorImage = ImageMirrorFun(InputImage,1);
RateImage = ImageRateFun(InputImage,128.5,128.5,2,3,2);
subplot(2,3,1)
imshow(uint8(InputImage));
title("原图");
subplot(2,3,2)
imshow(uint8(ShiftImage));
title("平移");
subplot(2,3,3)
imshow(uint8(RotateImage)); 
title("旋转后向插值");
subplot(2,3,4)
imshow(uint8(MirrorImage));
title("镜像");
subplot(2,3,5)
imshow(uint8(RateImage));
title("切变");
RotateImage = ImageRotateFun(InputImage,128.5,128.5,theta,1);
subplot(2,3,6)
imshow(uint8(RotateImage)); 
title("旋转前向插值");

结果

几何变换
Fig1.图像的几何变换测试

注:

1.转载请注明出处。

2.本文使用的算法是几何变换用矩阵表示。

3.插值算法可以进一步优化,笔者精力有限没做尝试。

4.本文的所有图像处理都使用了前向和后向两种映射,注意区别其产生的结果。

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值