Opencv-python官方文档个人学习(五)

Image Processing in OpenCV

Geometric Transformations of Images

图像几何变换

学习目标

  1. 学习对图像应用不同的几何变换,如平移、旋转、仿射变换等。
  2. cv.getPerspectiveTransform函数

Transformations转换

OpenCV提供了两个变换函数,cv.warpAffine和cv.warpPerspective,用它们可以执行各种变换。cv.warpAffine采用2*3变换矩阵,而cv.warpPerspective采用3*3变换矩阵作为输入。

Scaling(缩放)

缩放就是图像的resize,OpenCV为此提供了一个函数cv.resize(),该函数可以手动指定图像的大小,也可以指定缩放因子。resize使用不同的插值方法。首选插值方法是用于缩小的cv.INTER_AREA(即缩小图片使用该方法效果最好)和用于缩放的cv.INTER_CUBIC(效果好但慢)和cv.INTER_LINEAR(中庸)。默认情况下,插值方法cv.INTER_LINEAR用于所有调整大小的目的。你可以使用以下任意方法调整输入图像的大小。

cv.resize(

        InputArray src,

        OutputArray dst,(一般省略,直接用变量来接cv.resize返回的图片)

        Size dsize,

        double fx=0,

        double fy=0,

        int interpolation = INTER_LINEAR

)

参数说明:

src:输入,原图像,即待改变大小的图像;
dst:输出,改变大小之后的图像,这个图像和原图像具有相同的内容,只是大小和原图像不一样而已;
dsize:输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数为0,那么原图像缩放之后的大小就要通过下面的公式来计算:
       dsize = Size(round(fx*src.cols), round(fy*src.rows))

       其中,fx和fy就是下面要说的两个参数,是图像width方向和height方向的缩放比例。

fx:width方向的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算;
fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;

注:dsize和fx,fy按我的理解是互斥的,如果用了dsize就不用指定fx,fy了,反之亦然。
interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:
      INTER_NEAREST - 最邻近插值
      INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
      INTER_AREA -区域插值 resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
      INTER_CUBIC - 4x4像素邻域内的双立方插值
      INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值

--------此处参数说明转自

OpenCV图像缩放resize各种插值方式的比较_opencv图像缩放resize各种插值方式的比较实现-CSDN博客

import numpy as np
import cv2 as cv

img = cv.imread('messi5.jpg',1)
assert img is not None,'file could not be load,please check with os.path.exists()'

#缩小到原来的1/2
res1 = cv.resize(img,None,fx=0.5,fy=0.5,interpolation = cv.INTER_AREA)

#放大到原来的2倍
height,width= img.shape[:2]
res2 = cv.resize(img,(2*width,2*height),interpolation = cv.INTER_CUBIC)

#使用cv.INFER_LINEAR来进行插值
res3 = cv.resize(img,None,fx=0.5,fy=0.5,interpolation = cv.INTER_LINEAR)
res4 = cv.resize(img,None,fx=2,fy=2,interpolation=cv.INTER_LINEAR)

cv.imshow('res1',res1)
cv.imshow('res2',res2)
cv.imshow('res3',res3)
cv.imshow('res4',res4)

cv.waitKey(0)
cv.destroyAllWindows()
Translation(平移)

平移就是物体位置的移动。

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
assert img is not None, "file could not be read, check with os.path.exists()"
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

M矩阵第一个元素[1,0,tx]表示x方向上的变换。其中1表示不改变X坐标的比例,0表示Y坐标的变换不影响X坐标,tx是X方向的平移量。
第二个元素[0,1,ty]表示y方向上的变换。其中0表示x坐标变换不影响y坐标,1表示不改变y坐标的比例,ty是y方向的平移量。

Rotation(旋转)

图像旋转一个角度是通过变换矩阵实现的,变换矩阵形式为

M = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}

但是,OpenCV 提供了可调整旋转中心的缩放旋转功能,因此您可以在您喜欢的任何位置进行旋转。修改后的变换矩阵如下

\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot center.x - \beta \cdot center.y \\ - \beta & \alpha & \beta \cdot center.x + (1- \alpha ) \cdot center.y \end{bmatrix}

img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
assert img is not None, "file could not be read, check with os.path.exists()"
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

Affine Transformation(仿射变换)

在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。要找到变换矩阵,我们需要输入图像中的三个点及其在输出图像中的对应位置。然后,cv.getAffineTransform 将创建一个 2x3 矩阵,并将其传递给 cv.warpAffine。

img = cv.imread('drawing.png')
assert img is not None, "file could not be read, check with os.path.exists()"
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')

Perspective Transformation(视角变换)

透视变换需要一个 3x3 变换矩阵。即使在变换后,直线仍然是直线。要找到这个变换矩阵,需要输入图像上的 4 个点和输出图像上的相应点。在这 4 个点中,有 3 个点不应相交。然后就可以通过函数 cv.getPerspectiveTransform 找到变换矩阵。然后利用这个 3x3 变换矩阵应用 cv.warpPerspective。

img = cv.imread('sudoku.png')
assert img is not None, "file could not be read, check with os.path.exists()"
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 = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

总结:

本章节中学习了图像的几何变换相关操作

  • 30
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值