图像的几何变换(opencv_python学习)

缩放

使用 cv.resize()函数

import numpy as np
import cv2 as cv

img = cv.imread('messi5.jpg')
res = cv.resize(img, None, fx=2, fy=2, interpolation=cv.INTER_CUBIC)
# 或者
height, width = img.shape[:2]
res = cv.resize(img, (2*width, 2*height), interpolation=cv.INTER_CUBIC)

以上代码示例演示了两种调整图像大小的方法:通过指定缩放比例 fx 和 fy 或直接指定目标图像的高度和宽度来调整图像的大小

在 OpenCV 的 resize() 函数中,可以使用不同的插值方法来进行图像的调整。下面列举了常用的几种插值方法及其效果和适用场景:

  • cv.INTER_NEAREST(最近邻插值):最近邻插值方法会将目标像素的值设置为最接近其相应位置的原始像素的值。该方法执行速度快,适用于对速度要求较高、不关注平滑效果的场景。

  • cv.INTER_LINEAR(双线性插值):双线性插值方法会利用原始图像中最接近目标像素位置的四个像素的加权平均值作为目标像素的值。这种方法可以得到平滑的结果,适用于一般的图像缩放任务。

  • cv.INTER_CUBIC(双立方插值):双立方插值方法会利用原始图像中最接近目标像素位置的 16 个像素的加权平均值来计算目标像素的值。它比双线性插值更精确,可以保留更多的细节,适用于对图像质量要求较高的任务。

  • cv.INTER_AREA(区域插值):区域插值方法是一种特殊的插值方法,主要用于图像缩小操作。它根据目标像素与原始图像像素的关系,在原始图像的局部区域内进行像素值的平均采样。该方法适用于图像缩小时要保留细节的场景。

根据图像处理的需求和场景,可以选择合适的插值方法来调整图像大小。最近邻插值适用于速度要求高、不关注平滑效果的场景;双线性插值是一种常用的默认选择,可以在速度和质量之间取得平衡;双立方插值能够提供更高质量的结果,但计算成本也较高;区域插值适用于图像缩小时需要保留细节的场景。

平移

使用OpenCV 的 cv.warpAffine 函数进行平移变换

import cv2
import numpy as np

# 读取图像
image = cv2.imread('input.jpg')

# 设置平移的偏移量
t_x = 100
t_y = 50

# 创建平移矩阵
M = np.float32([[1, 0, t_x], [0, 1, t_y]])

# 应用平移变换
output = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

# 显示结果
cv2.imshow('Translated Image', output)
cv2.waitKey(0)
cv2.destroyAllWindows()

我们首先读取输入图像,并设置了在 x 和 y 方向上的偏移量 t_x 和 t_y。然后,通过创建一个平移矩阵 M,其中第一行表示 x 方向上的平移值,第二行表示 y 方向上的平移值。

最后,我们使用 cv2.warpAffine 函数应用平移变换到输入图像上。将平移矩阵 M、输入图像的尺寸以及输出图像的尺寸作为参数传递给该函数。
原图
平移后的图像

旋转

使用旋转变化矩阵

import cv2

# 读取图像
img = cv2.imread('messi5.jpg', 0)

# 获取图像尺寸
rows, cols = img.shape

# 计算变换矩阵
center = ((cols-1) / 2.0, (rows-1) / 2.0)
angle = 90
scale = 1
alpha = scale * np.cos(np.deg2rad(angle))
beta = scale * np.sin(np.deg2rad(angle))
M = np.float32([[alpha, beta, (1-alpha) * center[0] - beta * center[1]], 
                [-beta, alpha, beta * center[0] + (1-alpha) * center[1]]])

# 应用旋转变换
dst = cv2.warpAffine(img, M, (cols, rows))

# 显示结果
cv2.imshow('Rotated Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

其中,OpenCV提供了一个函数cv.getRotationMatrix2D可以帮我们找到旋转矩阵

img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
# cols-1 和 rows-1 是坐标限制
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

该示例将图像相对于中心旋转90度而没有任何缩放比例。

仿射变换

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

img = cv.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 = 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')

在这里插入图片描述

透视变换

对于透视变换,您需要3x3变换矩阵。即使在转换后,直线也将保持直线。要找到此变换矩阵,您
需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然
后可以通过函数cv.getPerspectiveTransform找到变换矩阵。然后将cv.warpPerspective
用于此3x3转换矩阵。

img = cv.imread('sudoku.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 = 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()

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值