图像处理与机器视觉_第三篇


前言

本篇讲的是图像的几何变换的知识,其中具有一些代码实现。


一、图像几何变换

由于拍摄图像的角度、距离等原因,可能会需要对图像进行适当的几何变换。
几何变换又称为空间变换,是将一幅图像中的坐标位置映射到另外一幅图像中的新坐标位置。


二、解决几何变换问题的思路

一般要考虑原图像中的某个像素点的坐标 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)和此像素点映射到新图像中的新坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)之间的关系。可由下式描述: x 1 = f 1 ( x 0 , y 0 ) x_1=f_1(x_0,y_0) x1=f1(x0,y0) y 1 = f 2 ( x 0 , y 0 ) y_1=f_2(x_0,y_0) y1=f2(x0,y0)


三、图像镜像

垂直镜像:图像的上半部分和下半部分以图像水平中轴线为中心轴进行对称变换。以下图为例:

在这里插入图片描述
在这里插入图片描述

水平镜像:图像的左半部分和右半部分以图像竖直中轴线为中心轴进行对称变换。以下图为例:

在这里插入图片描述
在这里插入图片描述


3.1、水平镜像的变换公式

( x 0 , y 0 ) (x_0,y_0) (x0,y0)是原图像上的点,中心轴如图所示,水平镜像对应的新坐标点为: x 1 = x 0 x_1=x_0 x1=x0 y 1 = N − y 0 y_1=N-y_0 y1=Ny0
在这里插入图片描述

水平镜像的变换矩阵:
在这里插入图片描述

代码示例如下:

read_image(Image, '图片路径')
mirror_image(Image, ImageMirror, 'column')

3.2、垂直镜像的变换公式

( x 0 , y 0 ) (x_0,y_0) (x0,y0)是原图像上的点,中心轴如图所示,水平镜像对应的新坐标点为: x 1 = M − x 0 x_1=M-x_0 x1=Mx0 y 1 = y 0 y_1=y_0 y1=y0
在这里插入图片描述

垂直镜像的变换矩阵:
在这里插入图片描述

代码示例如下:

read_image(Image, '图片路径')
mirror_image(Image, ImageMirror, 'row')

PS:要注意x轴和y轴分别是什么坐标轴,我的例子是x轴是纵轴、y轴是横轴,所以如果x、y轴有变化相应的公式以及变换矩阵也有变化。


四、图像转置

在这里插入图片描述


4.1、图像转置的公式

图像转置即行列互换, ( x 0 , y 0 ) (x_0,y_0) (x0,y0)是原图像上的点,转置后对应的新坐标点为: x 1 = y 0 x_1=y_0 x1=y0 y 1 = x 0 y_1=x_0 y1=x0;注意:图像尺寸有可能改变。

在这里插入图片描述


4.2、图像转置的程序实现

代码示例如下:

read_image(Image, '图像路径')
mirror_image(Image, ImageMirror, 'diagonal')

五、图像平移

( x 0 , y 0 ) (x_0,y_0) (x0,y0)是原图像上的点,图像水平平移量为 Δ y \varDelta y Δy,垂直平移量为 Δ x \varDelta x Δx,如图所示。
平移后的新坐标点为: x 1 = x 0 + Δ x x_1=x_0+\varDelta x x1=x0+Δx y 1 = y 0 + Δ y y_1=y_0+\varDelta y y1=y0+Δy
在这里插入图片描述
在这里插入图片描述

图像平移变换式的矩阵形式为:
在这里插入图片描述

以下为图像平移样例:
在这里插入图片描述

代码示例如下:

// 对图像进行右下移位
read_image(Image, '图像路径')
get_image_size(Image, Width, Height)
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, 60, 60, HomMat2DTranslate)
affine_trans_image(Image, ImageAffinTrans, HomMat2DTranslate, 'weighted', 'false')

结果如下:
在这里插入图片描述
矩阵形式:
在这里插入图片描述

其中,关于最后一个函数的解释:
在这里插入图片描述


六、图像缩放

在这里插入图片描述

图像比例缩放变换:指将给定的图像在x轴方向按比例缩放r倍,在y轴方向上按比例缩放r倍,从而获得一幅新的图像。比例缩放前后两点 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) P0(x0,y0) P ( x , y ) P(x,y) P(x,y)之间的关系可以表示为: { x = r x 0 y = r y 0 \begin{cases} {x=rx_0} \\ {y=ry_0}\end{cases} {x=rx0y=ry0

矩阵形式: [ x y 1 ] = [ r 0 0 0 r 0 0 0 1 ] [ x 0 y 0 1 ] \begin{bmatrix}{x}\\{y}\\{1}\end{bmatrix}=\begin{bmatrix}r & 0 & 0\\0 & r & 0\\0 & 0 & 1\end{bmatrix}\begin{bmatrix}{x_0}\\{y_0}\\{1}\end{bmatrix} xy1 = r000r0001 x0y01
其中: r > 1 r>1 r>1,放大; 0 < r < 1 0<r<1 0<r<1,缩小


6.1、缩小

目的:
1、使缩小后的图像符合显示区域的大小要求;
2、生成原图像的缩略图。

图像的缩小操作,是在现有的信息里挑选所需要的有用信息。

在这里插入图片描述
如果图像按任意比例缩小,则需要计算所需选择的行列。

图像缩小实现算法:
在这里插入图片描述
在这里插入图片描述

图像缩小例题:
在这里插入图片描述
使用四舍五入策略


6.2、放大

图像的放大操作,需对尺寸放大后所多出来的空格填入适当的值,这是信息的估计问题,所以较图像的缩小要难一些。

图像放大一般分为按比例放大不按比例放大两种:

  • 按比例放大: 如果需要将原图像放大k倍,则将一个像素值填在新图像的 k × k k\times k k×k的子块中。
  • 任意不按比例放大: 这种操作由于x方向和y方向的放大倍数不同一定带来图像的几何畸变。
  • 图像放大倍数太大,会出现马赛克效应。

图像放大实现思路:

最简单的思想是如果需要将原图像放大为k倍,则将原图像中的每个像素值,填在新图像中对应的 k × k k\times k k×k大小的子块中。
在这里插入图片描述

图像放大实现方法:

设原图像大小为 M × N M\times N M×N,放大为 k 1 M × k 2 N , ( k 1 > 1 , k 2 > 1 ) k_1M\times k_2N,(k_1>1,k_2>1) k1M×k2N,(k1>1,k2>1)。算法步骤如下:

  • 设旧图像是 F ( i , j ) , i = 1 , 2 , . . . , M , j = 1 , 2 , . . . , N F(i,j),i=1,2,...,M,j=1,2,...,N F(i,j),i=1,2,...,M,j=1,2,...,N;新图像是 G ( x , y ) , x = 1 , 2 , . . . , k 1 M , y = 1 , 2 , . . . , k 2 N G(x,y),x=1,2,...,k_1M,y=1,2,...,k_2N G(x,y),x=1,2,...,k1M,y=1,2,...,k2N
  • G ( x , y ) = F ( c 1 ⋅ x , c 2 ⋅ y ) , c 1 = 1 k 1 , c 2 = 1 k 2 G(x,y)=F(c_1\cdot x,c_2\cdot y),c_1=\frac {1}{k_1},c_2=\frac {1}{k_2} G(x,y)=F(c1x,c2y),c1=k11,c2=k21
    在这里插入图片描述

图像的成倍放大效果示例:
在这里插入图片描述

图像大比例放大时的马赛克效应:
在这里插入图片描述


6.3、灰度级插值方法

思考问题:
如果放大倍数太大,按照前面的方法处理会出现马赛克效应。如果这个问题交给你,有没有办法解决?或者想办法至少使之有所改善?

  • 灰度级插值法
    • 最邻近插值法
    • 双线性插值法(一阶插值)
    • 高阶插值

最邻近插值法(nearest neighbor interpolation)

  • 最简单的插值方法是最邻近插值,即选择离它所映射到的位置最近的输入像素的灰度值为插值结果。
  • 数学表示为: f ( x ) = f ( x k ) f(x)=f(x_k) f(x)=f(xk)
  • 1 2 ( x k − 1 + x k ) < x < 1 2 ( x k + x k + 1 ) \frac 1 2(x_{k-1}+x_k)<x<\frac 1 2(x_{k}+x_{k+1}) 21(xk1+xk)<x<21(xk+xk+1)

双线性插值(bilinear interpolation)

  • 双线性插值法是对最邻近插值法的一种改进,即用线性内插方法,根据点的四个相邻点的灰度值,分别在x和y方向上进行两次线性插值,如下图:
    在这里插入图片描述
    基本算法思想:
  • 假设输出图像的宽度为W,高度为H;
  • 输入图像的宽度为w,高度为h;
  • 要将输入图像的尺度拉伸或压缩变换至输出图像的尺度;
  • 按照线性插值的方法,将输入图像的宽度方向分为W等份,高度方向分为H等份,那么输出图像中任意一点 ( u 0 , v 0 ) (u_0,v_0) (u0,v0)的灰度值就应该由输入图像中四点 ( u , v ) (u,v) (u,v) ( u + 1 , v ) (u+1,v) (u+1,v) ( u , v + 1 ) (u,v+1) (u,v+1) ( u + 1 , v + 1 ) (u+1,v+1) (u+1,v+1)的灰度值来确定。
    在这里插入图片描述
    横坐标轴是y轴
    按比例放大图像:
    在这里插入图片描述

插值算法示例:
在这里插入图片描述

代码如下:

zoom_image_size(Image, ImageZoom, Width1, Height1, Interpolation)
/*参数Interpolation用于指定插值的方法,几种可选值为:
'nearest_neighbor',最邻近插值法
'constant',(默认值)
'bilinear',双线性插值
'weighted'
*/

在这里插入图片描述


七、图像的旋转变换

一般图像的旋转是以图像的中心为原点,旋转一定的角度,即将图像上的所有像素都旋转一个相同的角度。

在这里插入图片描述

图像的旋转变换也可用矩阵变换表示。设点 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) P0(x0,y0)旋转角 β \beta β后的对应点为 P ( x , y ) P(x,y) P(x,y)。如下图所示:
在这里插入图片描述

在这里插入图片描述

旋转前: { x 0 = r c o s α y 0 = r s i n α \begin{cases} {x_0=rcos\alpha} \\ {y_0=rsin\alpha}\end{cases} {x0=rcosαy0=rsinα
旋转后: { x 1 = r c o s ( α − β ) = r c o s α c o s β + r s i n α s i n β y 1 = r s i n ( α − β ) = r s i n α c o s β − r c o s α s i n β \begin{cases}{x_1=rcos(\alpha-\beta)=rcos\alpha cos\beta+rsin\alpha sin\beta}\\{y_1=rsin(\alpha-\beta)=rsin\alpha cos\beta-rcos\alpha sin\beta}\end{cases} {x1=rcos(αβ)=rcosαcosβ+rsinαsinβy1=rsin(αβ)=rsinαcosβrcosαsinβ
代入得: { x 1 = x 0 c o s β + y 0 s i n β y 1 = − x 0 s i n β + y 0 c o s β \begin{cases}{x_1=x_0cos\beta+y_0sin\beta}\\{y_1=-x_0sin\beta+y_0cos\beta}\end{cases} {x1=x0cosβ+y0sinβy1=x0sinβ+y0cosβ
矩阵形式为: [ x 1 y 1 1 ] = [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] [ x 0 y 0 1 ] \begin{bmatrix}{x_1}\\{y_1}\\{1}\end{bmatrix}=\begin{bmatrix}cos\beta & sin\beta & 0\\-sin\beta & cos\beta & 0\\0 & 0 & 1\end{bmatrix}\begin{bmatrix}{x_0}\\{y_0}\\{1}\end{bmatrix} x1y11 = cosβsinβ0sinβcosβ0001 x0y01

代码如下:

rotate_image(Image, ImageRotate, Phi, Interpolation)
//Phi:角度

图像示例:
在这里插入图片描述
代码示例如下:

// 以中心为基准点进行旋转
rotate_image(Image, ImageRotate, 45, 'constant')

//以(200,200)为基准点进行旋转
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_rotate(HomMat2DIdentity, 0.78, 200, 200, HomMat2DRotate)
affine_trans_image(Image, ImageAffinTrans, HomMat2DRotate, 'weighted', 'false')

结束!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

禁筱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值