(1)平移后图像上的每一点都可以在原图像中找到对应的点。对于不在原图像中的点,可以直接将它的像素值统一设置为0或者255。
(2)若图像平移后图像不放大,说明移出的部分被截断。
(3)若不想丢失被移出的部分图像,将新生成的图像扩大。
I=imread('lena512x512.bmp');
I=double(I);
I_moveresult=zeros(size(I));
H=size(I);
Move_x=50;
Move_y=50;
I_moveresult(Move_x+1:H(1),Move_y+1:H(2))=
I(1:H(1)-Move_x,1:H(2)-Move_y);
%I_moveresult(Move_x+1:H(1),Move_y+1:H(2),1:H(3))=I(
1:H(1)-Move_x,1:H(2)-Move_y,1:H(3));
imshow(uint8(I_moveresult));
用OpenCV实现。
也可以通过直接逐行地复制图像来实现。
I=imread('airplane.bmp');
I=double(I);
H=size(I);
I_flipud(1:H(1),1:H(2),1:H(3))=I(H(1):-1:1,1:H(2),1:H(3)); %垂直镜像
imshow(uint8(I_flipud));
figure;
I_fliplr(1:H(1),1:H(2),1:H(3))=I(1:H(1),H(2):-1:1,1:H(3)); %水平镜像
imshow(uint8(I_fliplr));
figure;
I_fliplr_flipud(1:H(1),1:H(2),1:H(3))=I(H(1):-1:1,H(2):-1:1,1:H(3));
%对角镜像
imshow(uint8(I_fliplr_flipud));
和图像平移一样, 在垂直镜像中也可以利用位图存储的连续性整行复制图像。
利用OpenCV提供的flip函数进行图像镜像的大致结构为flip(src, dst, flip_mod)。flip_mod为图像的镜像方式: 当flip_mod=0时表示沿x轴进行翻转;当flip_mod>0 (如flip_mod=1)时表示沿Y轴进行翻转; 当flip_mod<0(如flip_mod=-1)时表示沿x轴和y轴进行翻转, 翻转后像素点的取值可按下式处理:
图像的旋转是指以图像中的某一点为原点以逆时针或顺时针的方向将图像上的所有像素都旋转一个相同的角度。
须指明图像绕着什么旋转。一般以图像的中心为原点旋转。
旋转变换后仅产生图像位置的变化,但图像的大小一般会改变(画布)。
和图像平移一样, 在图像旋转变换中既可以把转出显示区域的图像截去, 也可以扩大新图像的尺寸以显示所有的图像。
图像旋转之后,出现了两个问题:
1)像素的排列不是完全按照原有的相邻关系。这是因为相邻像素之间只能有8个方向(相邻为45度),如下图所示。
2)会出现许多的空洞点。
出现问题的核心是像素之间的连接是不连续的。
相邻像素的角度是无法改变的,所以只能通过增加分辨率的方法来从整体上解决这个问题。
采用某种填补方法来填充空洞。
最简单的方法是行插值(列插值)方法。
经过插值处理之后,图像效果就变得自然。
如果目标是要求绕图像原点逆时针旋转的新图像。那么从新图像的像素点坐标反过来求原图像所对应的点坐标:
由式(4-19)计算得旋转后的坐标并用双线性插值方法充填空洞点, 可以用OpenCV编写一个实现图像旋转的函数rotateImage()。 该函数的结构和主要算法大致如下。
(1) 读入源图像:
Mat src;
src = imread(“4-26.jpg”);
(2) 计算图像中心:
Point2f center(src.cols / 2, src.rows / 2);
(3)构建变换矩阵:
Mat rotmat = getRotationMatrix2D(center, 30, 1);
//第3个变量大于0表示逆时针旋转; 小于0表示顺时针旋转。
Mat dst(src.cols, src.rows, src.type());
(4) 进行变换:
warpAffine(src, dst, rotmat,
dst.size(),
INTER_LINEAR, BORDER_CONSTANT, Scalar(0) );
用上述函数对图4-26所示的原始图像旋转15°, 并按式(4-11)进行双线性插值处理后的结果如图4-27。 将如图4-28所示的图像旋转30°, 并将局部放大后如图4-29所示,由图4-29可见, 旋转后的图像在边缘会产生锯齿现象。
图像的复合变换是指对给定的图像连续进行若干次平移、 镜像、 比例缩放、 旋转等基本变换。
变换矩阵仍可用3阶矩阵表示, 且可用数学证明: 复合变换的矩阵等于基本变换的矩阵按顺序依次相乘得到的矩阵乘积。
通常为相对原点(图像中心)作平移、 比例缩放、 旋转等, 若要相对某一个参考点作变换, 则需使用含有不同种基本变换的复合变换。
如果图像绕一个指定点(a, b)旋转, 则先要将坐标系平移到该点, 再进行旋转, 然后将旋转后的图像平移回原来的坐标原点。
1.下面推导图像复合变换公式:
首先推导坐标系平移的转换公式。 如图4-32所示, 将坐标系Ⅰ平移到坐标系Ⅱ处, 其中坐标系Ⅱ的原点在坐标系Ⅰ中的坐标为(a, b)。
两个坐标系之间的坐标变换矩阵表达式为
假设图像未旋转时中心坐标为(a, b), 旋转后中心坐标为(c,d) (在新的坐标系下旋转后新图像左上角为原点), 则旋转变换矩阵表达式为
其逆变换表达式为
式(4-27)表明绕任意点(a, b)旋转的图像几何变换是由3个基本变换:平移、 旋转、 平移所构成。
2.编写实现图像旋转的OpenCV函数:
需计算出公式中需要的几个参数: a, b, c, d和旋转后新图像的高度和宽度。
以图像中心为坐标系原点, 则原始图像4个角的坐标分别为
在旋转后的新图像中, 该4个点坐标分别变为
则新图像的宽度lNewWidth和高度lNewHeight为
式(4-32)和式(4-33)即为图像绕任意点(a, b)旋转的变换公式。 只要先按上述公式计算出旋转后新图像的高度和宽度以及常数f1和f2, 并按照公式(4-33)计算出变换后图像上的点(i0, j0):