【opencv3 学习记录】第九章 几何变换

变换 OpenCV 提供了两个变换函数,cv2.warpAffine 和 cv2.warpPerspective, 使用这两个函数你可以实现所有类型的变换。cv2.warpAffine 接收的参数是 2 × 3 的变换矩阵,而 cv2.warpPerspective 接收的参数是 3 × 3 的变换矩阵。

一:扩展缩放

扩展缩放只是改变图像的尺寸大小。OpenCV 提供的函数 cv2.resize() 可以实现这个功能。图像的尺寸可以自己手动设置,你也可以指定缩放因子。我1 们可以选择使用不同的插值方法。

1.函数:cv2.resize(InputArray src, OutputArray dst, Size, fx, fy, interpolation)

2.参数说明:

nputArray src输入图片
OutputArray dst输出图片
Size输出图片尺寸
fx, fy沿x轴,y轴的缩放系数
interpolation插入方式

注:1.参数三size与参数四fx,fy可以二选一

2.参数五interpolation:在缩放时我们推荐使用 cv2.INTER_AREA, 在扩展时我们推荐使用 v2.INTER_CUBIC(慢) 和 v2.INTER_LINEAR。 默认情况下所有改变图像尺寸大小的操作使用的插值方法都是 cv2.INTER_LINEAR

import cv2
import numpy as np
img=cv2.imread(r'F:\picture\demo\ball.jpg')
# 下面的 None 本应该是输出图像的尺寸,但是因为后边我们设置了缩放因子
# 因此这里为 None
res=cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
#OR
# 这里呢,我们直接设置输出图像的尺寸,所以不用设置缩放因子
height,width=img.shape[:2]
res=cv2.resize(img,(2*width,2*height),interpolation=cv2.INTER_CUBIC)
while(1):
    cv2.imshow('res',res)
    cv2.imshow('img',img)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cv2.destroyAllWindows()

二:平移

        平移就是将对象换一个位置。如果你要沿(x,y)方向移动,移动的距离 是(tx,ty),你可以以下面的方式构建移动矩阵:

                                                           

        你可以使用 Numpy 数组构建这个矩阵(数据类型是 np.float32),然 后把它传给函数 cv2.warpAffine()。

1.函数:cv2.warpAffine(src, M, dsize,dst,flags,borderMode,borderValue) → dst

2.参数说明:

参数含义
src输入图像
M换矩阵,一般反映平移或旋转的关系,为InputArray类型的2×3变换矩阵。
dszie输出图像的大小
flags插值方法的组合(int 类型)
borderMode边界像素模式(int 类型)
borderValue  边界填充值; 默认情况下,它为0,也就是边界填充默认是黑色。

其中flags表示插值方式,有以下取值

flags取值含义
cv2.INTER_LINEAR线性插值(默认)
cv2.INTER_NEAREST最近邻插值
cv2.INTER_AREA区域插值
cv2.INTER_CUBIC三次样条插值
cv2.INTER_LANCZOS4Lanczos插值

import cv2
import numpy as np
img = cv2.imread(r'F:\picture\demo\ball.jpg')
height,width=img.shape[0:2]
imgShift = np.float32([[1,0,100],[0,1,200]])# [1,0,100]的意思是,宽右移距离100 [0,1,200]高下移200
dst = cv2.warpAffine(img,imgShift,(width,height))
cv2.imshow('img',dst)
cv2.waitKey(0)

注:函数 cv2.warpAffine() 的第三个参数的是输出图像的大小,它的格式 应该是图像的(宽,高)。应该记住的是图像的宽对应的是列数,高对应的是行 数。 

三:旋转

对一个图像旋转角度 θ, 需要使用到下面形式的旋转矩阵。

但是 OpenCV 允许你在任意地方进行旋转,但是旋转矩阵的形式应该修 改为

          

         为了构建这个旋转矩阵,OpenCV 提供了一个函数:cv2.getRotationMatrix2D。 下面的例子是在不缩放的情况下将图像旋转 90 度。

        因此要实现对一个图像进行旋转操作,就需要先通过cv2.getRotationMatrix2D函数获取旋转矩阵,再使用cv2.warpAffine函数进行旋转变换

1.获取旋转矩阵函数:M=cv2.getRotationMatrix2D(center, angle, scale)

2.参数说明:

参数说明
center图片的旋转中心
angle旋转角度
scale旋转后图像相比原来的缩放比例
M计算得到的旋转矩阵

3.举例:在不缩放的情况下将图像旋转 90 度

#在不缩放的情况下将图像旋转 90 度
import cv2
import numpy as np
img=cv2.imread(r'F:\picture\demo\ball.jpg')
height,width=img.shape[0:2]
M=cv2.getRotationMatrix2D((height/2,width/2),90,1)
dst=cv2.warpAffine(img,M,(width,height))
while(1):
    cv2.imshow('img',img)
    cv2.imshow('dst',dst)
    if cv2.waitKey(1)&0xFF==27:
        break
cv2.destroyAllWindows()

四:仿射变换

       在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这 个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后 cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给 函数 cv2.warpAffine。

1.函数:M=cv2.GetAffineTransform(src, dst)

2.参数说明:

参数说明
src原始图像中的三个点的坐标
dst变换后的这三个点对应的坐标
M根据三个对应点求出的仿射变换矩阵
import cv2
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread('drawing.png')
rows,cols,ch=img.shape
pts1=np.float32([[50,50],[200,50],[50,200]])
pts2=np.float32([[10,100],[200,50],[100,250]])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121,plt.imshow(img),plt.title('Input'))
plt.subplot(121,plt.imshow(img),plt.title('Output'))
plt.show()

 

五:透视变换

      对于视角变换,我们需要一个 3x3 变换矩阵。在变换前后直线还是直线。 要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图 像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有 函数 cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数 cv2.warpPerspective。

1.函数:cv2.getPerspectiveTransform(src, dst)

2.参数说明:

参数说明
src源图像中待测矩形的四点坐标
sdt目标图像中矩形的四点坐标

注:这四个点中的任意三个都不能共线

import cv2
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread('sudokusmall.png')
rows,cols,ch=img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpPerspective(img,M,(300,300))
plt.subplot(121,plt.imshow(img),plt.title('Input'))
plt.subplot(121,plt.imshow(img),plt.title('Output'))
plt.show()

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值