目录
图像的平移
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("旋转前向插值");
结果
![几何变换](https://i-blog.csdnimg.cn/blog_migrate/e510b02168bf78963f7499db72cab88e.jpeg)
注:
1.转载请注明出处。
2.本文使用的算法是几何变换用矩阵表示。
3.插值算法可以进一步优化,笔者精力有限没做尝试。
4.本文的所有图像处理都使用了前向和后向两种映射,注意区别其产生的结果。