资源描述
第六章 图像的几何变换,有时我们希望改变图像的形状、尺寸或者方向以适应我们不同场合的应用需要。 旋转和缩放都属于仿射变换。 仿射变换:一种特殊的投影变换。一个非奇异的线性变换(即变换矩阵行列式不为零的线性变换),接一个平移变换构成的组合变换。它能保证变换前后直线的平行性不变。,6.1数值插值 例:我们有四个数值,如果我们希望扩大到八个那么要怎样做。这八个值一样要平均分布。也就是说,希望把原来四个点所对应的区域平均的分成八份。设原来的点为 新的点为 假设原来每两点间的距离为1,则总长度为3,新的分法将把这长度等分为7份,两点间的距离为3/7,用数来表示如图6.2 那么原值与新值的关系可以表示成为 可见除了两个端点外新点没有与原来的点重合的。,若原来的值都对应一个函数值 那我们要来估计一下新的点对应的函数值,这种估计基于邻近的原来点的函数值的。 有两种估计方法:最近邻插值法、线性插值法 最近邻插值法是将距离新点最近的原点的函数值赋给新点,作为该点处的函数值。 线性插值是将原相邻两点间的函数值用直线连接,然后在这些直线上找到新点所对应的函数值。 例子如图6.5所示,这样可求出F,如果,考虑 这点位于 之间,对应的 值为2/7 则,考虑 这点位于 之间,对应的 值为4/7 则,6.2图像插值,上面提到的方法一样可以用到图像中,图6.6给出了通过插值将一幅4*4的图像扩充成为8*8的图像。空心的圆点表示原图像中的点,实心圆点表示插值运算之后的新点。 图6.7给出了关于四个相邻点的图像插值的过程。设原来点的函数值为 我们可以先沿着顶行计算两点之间插入的新值 而后再沿着底行计算两点之间插入的新值 最后沿着产生的新列 计算这两个新值之间的新值,通过第一节中的公式可以得到,沿着 插值,将前面两个式子代入第三个式子中,有,这个式子就是双线性插值的公式。,现在,当给出图像要缩放的参数(或直接给出行和列的缩放参数)。比如前面的例子。我们有4*4的图像,希望得到一幅8*8的图像,那么放大系数是2,或 (2*4)*( 2*4 )。根据第一节的公式有 的关系如下,如果给出了 那么我们可以用最近邻插值法或双线性插值法一点一点的计算出来对应的插入的函数值。,当放大系数小于1时,我们做的是抽值运算,这时输出的图像大小将小于原图像,可将图6.6的实心点看做原图的像素,而空心点看做抽值后的点。,图像放大,用最近邻插值法,最简单的思想是,如果需要将原图像放大为k倍,则将原图像中的每个像素值,填在新图像中对应的k*k大小的子块中。,显然,当k为整数时,可以采用这种简单的方法。,图像的成倍放大效果示例,图像放大,不等比例,设原图像大小为M*N,放大为k1M*k2N, (k11,k21)。算法步骤如下: 1)设旧图像是F(i,j), i=1,2,M, j=1,2,N. 新图像是G(x,y), x=1,2,k1M, y=1,2,k2N. 2)G(x,y)=F(c1*x,c2*y) c1=1/k1 c2=1/k2,K1=1.5, k2=1.2,i=1,2, j=1,3. x=1,3, y=1,4. x=1/1.5,2/1.5,3/1.5=i1,i1,i2, y=1/1.2,2/1.2,3/1.2,4/1.2=j1,j2,j3, j3.,图像放大,图像不等比例放大,MATLAB中有imresize这个函数可以实现图像的缩放。 调用格式为 imresize(A,k,method) A是图像,k是缩放比例,“method”是插值方式,“nearest”或者“bilinear” 另一种格式为 imresize(A,m,n,method) m,n是输出图像的尺寸,c=imread(cameraman.tif); head=c(33:96,90:153); imshow(head) head4n=imresize(head,4,nearest);figure,imshow(head4n) head4b=imresize(head,4,bilinear);figure,imshow(head4b),对比上面两种插值效果能够看出来,最近邻法有严重的马赛克效应。 双线性内插法具有低通滤波性质,使高频分量受损,图象轮廓模糊。,6.3一般插值方法,虽然最近邻法和双线性插值法看起来不太一样,但它们都 属于一般插值的特殊情况。下面来看一下一般插值的想法。 假设我们要求 , ,设 ,定义 一个插入函数R(u)。,图6.10说明了这式子的由来。 R(u)的中心在 处, 对应着 , 对应着 现在有两种类型的R函数R0和R1,分别对应着图6.11中的 结构,并且只定义了 的区间。,函数形式分别为,现在,用R0代替公式中的R,将得到最近邻法插值的结果。 若用R1代替R,将得到线性插值的结果。,另外还有一种插值方法三次插值 该方法利用三次多项式S(x)来逼近理论上的最佳插值函数 sin(x)/x。其数学表达式为:,定义的区间为 ,用的已知点也多了,用R3代 替R有,这里 位于 之间。,(i-1,j-1),(i-1,j+2),(i+2,j-1),(i+2,j+2),(x,y),u,v,应用到图像中,其中 A=s(1+v) s(v) s(1-v) s(2-v),C=s(1+u) s(u) s(1-u) s(2-u)T,待求像素(x,y)的灰度值由其周围十六个点的灰度值加权内插得到。可推导出待求像素的灰度计算式如下: f(x,y)=AB C,head4c=imresize(head,4,bicubic);figure,imshow(head4c),这种方法应用于图像称为双三次差值。 该算法计算量最大,但内插效果最好,精度最高。,6.4利用空域滤波器实现图像扩大,如果我们仅仅希望得到一个扩大两倍的图像,这里有一种 既快速又直接的方法利用线性滤波。通过例子来说明, 一个4*4的图像,m=magic(4) m = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1,第一步,通过插入0实现变形,主要是在行与行之间和 列与列之间插入全为零的行和列。如果m2是m做0插入 后的矩阵,那么可以将其定义为,function out=zeroint(a) % % m,n=size(a);a2=reshape(a;zeros(m,n),m,2*n); out=reshape(a2;zeros(2*n,m),2*n,2*m);,m2=zeroint(m) m2 = 16 0 2 0 3 0 13 0 0 0 0 0 0 0 0 0 5 0 11 0 10 0 8 0 0 0 0 0 0 0 0 0 9 0 7 0 6 0 12 0 0 0 0 0 0 0 0 0 4 0 14 0 15 0 1 0 0 0 0 0 0 0 0 0,现在,我们可以分别用两个空域滤波器来实现最近邻插值 和双线性插值。滤波模板分别为,filter2(1 1 0;1 1 0;0 0 0,m2) ans = 16 16 2 2 3 3 13 13 16 16 2 2 3 3 13 13 5 5 11 11 10 10 8 8 5 5 11 11 10 10 8 8 9 9 7 7 6 6 12 12 9 9 7 7 6 6 12 12 4 4 14 14 15 15 1 1 4 4 14 14 15 15 1 1,m2b=imresize(m,8,8,nearest);m2b m2b = 16 16 2 2 3 3 13 13 16 16 2 2 3 3 13 13 5 5 11 11 10 10 8 8 5 5 11 11 10 10 8 8 9 9 7 7 6 6 12 12 9 9 7 7 6 6 12 12 4 4 14 14 15 15 1 1 4 4 14 14 15 15 1 1,m2b=imresize(m,7,7,bilinear);m2b m2b = 16.0000 11.0000 3.0000 2.5000 3.7143 9.4286 13.0000 12.0714 9.6224 5.7041 5.3571 5.9082 9.1735 11.2143 5.7857 7.4184 10.0306 9.9286 9.4184 8.7653 8.3571 7.0000 7.7143 8.8571 8.5000 8.1429 9.2857 10.0000 8.6429 8.2347 7.5816 7.0714 6.9694 9.5816 11.2143 5.7857 7.8265 11.0918 11.6429 11.2959 7.3776 4.9286 4.0000 7.5714 13.2857 14.5000 14.0000 6.0000 1.0000,这里用7*7的输出矩阵是为了确保插值点都位于原图像的 两点之中点。,可用如下的矩阵模拟双三插值,分别用空域滤波的方法将head扩大两倍,6.5缩小,分为按比例缩小和不按比例缩小两种。 图像缩小之后,因为承载的信息量小了,所以画布可相应缩小。,(a) 按比例缩小 (b) 不按比例缩小,图像缩小实际上就是对原有的多个数据进行挑选或处理,获得期望缩小尺寸的数据,并且尽量保持原有的特征不丢失。 最简单的方法就是等间隔地选取数据。,设原图像大小为M*N,缩小为k1M*k2N, (k11,k21)。算法步骤如下: 1)设原图为F(i,j), i=1,2,M, j=1,2,N. 压缩后图像是G(x,y), x=1,2,k1M, y=1,2,k2N. 2)G(x,y)=F(c1*x,c2*y) 其中,c1=1/k1 c2=1/k2,图像缩小 例题,K1=0.6, k2=0.74,i=1,6, j=1,6. x=1,6*06=1,4, y=1,6*0.75=1,5. x=1/0.6,2/0.6,3/0.6,4/0.6=1.67,3.33,5,6.67=i2,i3,i5,i6, y=1/0.75,2/0.75,3/0.75,4/0.75,5/0.75=j1,j3,j4,j5,j6.,在实现方法上可以用imresize将其中的参数改成1就可以了。 例子,t=zeros(1024,1024); for i=1:1024; for j=1:1024; t(i,j)=(255.5)2(i-512)2+(j-512)2) end end t=t; imshow(t),tr=imresize(t,0.25); figure,imshow(tr),图像的旋转,图像的旋转计算公式如下:,这个计算公式计算出的值为小数,而坐标值为正整数。 这个计算公式计算的结果值所在范围与原来的值所在的范围不同。,因此需要前期处理:扩大画布,取整处理,平移处理 。,图像旋转之前,为了避免信息的丢失,画布的扩大是最重要的。 画布扩大的原则是:以最小的面积承载全部的画面信息。,画布扩大的简单方法是:根据公式 计算出x和y的最大、最小值,即xmin、xmax和ymin,ymax。 画布大小为: xmax xmin、 ymax ymin。,旋转后图像的画布大小为:,例,平移量为x=2; y=0。,图像旋转的效果示例,图像旋转 按照确定画布时的平移量取整,结论:按照图像旋转计算公式获得的结果与想象中的差异很大。,对原图的(1,1)像素,x=1,y=1,取整后,该点在新图的(2,1)上。,对原图的(1,2)像素,x=1,y=2,取整后,该点在新图的(2,2)上。,必须进行后处理操作。,图像旋转后处理 旋转后的隐含问题分析,图像旋转之后,出现了两个问题: 1)像素的排列不是完全按照原有的相邻关系。这是因为相邻像素之间只能有8个方向(相邻为45度),如下图所示。 2)会出现许多的空洞点。,图像旋转后处理 解决问题的思路,出现问题的核心是像素之间的连接是不连续的。 相邻像素的角度是无法改变的,所以只能通过增加分辨率的方法来从整体上解决这个问题。 采用某种填补方法来填充空洞。,图像旋转的后处理 插值,最简单的方法是行插值(列插值)方法。,1)找出当前行的最小和最大的非背景点的坐标,记作:(i,k1)、(i,k2)。,如右图有: (1,3)、(1,3); (2,1)、(2,4); (3,2)、(3,4); (4,2)、(4,3)。,图像旋转的后处理 插值,2)在(k1,k2)范围内进行插值,插值的方法是:空点的像素值等于前一点的像素值。 3)同样的操作重复到所有行。,图像旋转的后处理 插值效果分析,经过插值处理之后,图像效果就变得自然,旋转在MATLAB中通过imrotate实现 结构imrotate(image,angle,method) 此处的method与imresize中相同,缺省情况下是最近邻法。,c=imread(cameraman.tif); cr=imrotate(c,60); imshow(cr),crc=imrotate(c,60,bicubic); imshow(crc),crc=imrotate(c,90,bicubic); imshow(crc),crc=imrotate(c,180,bicubic); imshow(crc),crc=imrotate(c,270,bicubic); imshow(crc),
展开阅读全文