OpenCV-Python——第10章:图像的几何变换(移动、旋转、仿射及透视)

目录

1 扩展缩放    2 平移    3 旋转    4 仿射变换    5 透视变换


1 扩展缩放

cv2.resize(src, dsize, dst, fx, fy, interpolation)

  • src:原图像
  • dsize:目标尺寸,注意必须为整型
  • dst:目标图像
  • fx:水平轴缩放比例
  • fy:竖直轴缩放比例
  • interpolation:插值方法,共有5种:
INTER_NEAREST最近邻插值法
INTER_LINEAR双线性插值法(默认)
INTER_AREA基于局部像素的重采样
INTER_CUBIC基于4x4像素邻域的3次插值法
INTER_LANCZOS4基于8x8像素邻域的Lanczos插值

例如:

import cv2
import numpy as np
img = cv2.imread('test.jpg')
# 方法一 设置缩放比例
dst1 = cv2.resize(img, None, fx=0.8, fy=0.8, interpolation=cv2.INTER_CUBIC)

# 方法二 直接设置输出尺寸,注意输出尺寸必须为整型
height, width = img.shape[:2]  # 获得原尺寸
dst2 = cv2.resize(img, (int(0.5*width), int(0.5*height)), interpolation=cv2.INTER_CUBIC)
while(1):
    cv2.imshow('dst1', dst1)
    cv2.imshow('dst2', dst2)
    cv2.imshow('img', img)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cv2.destroyAllWindows()

结果如下:

 

2 平移

平移和旋转都是仿射变换的特例,所用函数都是cv2.warpAffine,只是转换矩阵M有所不同。

cv2.warpAffine(src, M, dsize, dst, flags, borderMode, borderValue)

  • src:原图像
  • M:变换矩阵
  • dsize:输出图像的大小
  • flags:插值方法,如上表所示
  • borderMode:边界像素模式,默认为BORDER_CONSTANT ,边界按常数填充。

–cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。

– cv2.BORDER_REFLECT边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb

– cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba

– cv2.BORDER_REPLICATE重复最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh

– cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh| abcdefgh|abcdefg

效果可在这篇文章中看到:https://blog.csdn.net/yukinoai/article/details/86423937

  • borderValue:边界填充值; 默认为0,所以默认情况下填充为黑色

对于平移,变换矩阵M如下所示:

由于比较简单,直接使用 Numpy 数组构建这个矩阵(数据类型是 np.float32)即可,然后把它传给函数 cv2.warpAffine()。

例如:

import cv2
import numpy as np

img = cv2.imread('test.jpg', 0)  # 以单通道灰度图像读入
rows, cols = img.shape
# 平移矩阵M:[[1,0,x],[0,1,y]]
M = np.float32([[1, 0, 200], [0, 1, 100]])
dst = cv2.warpAffine(img, M, (cols, rows))

while(1):
    cv2.imshow('dst', dst)
    cv2.imshow('img', img)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cv2.destroyAllWindows()

结果如下:

 

3 旋转

平移和旋转都是仿射变换的特例,所用函数都是cv2.warpAffine,只是转换矩阵M有所不同。对于旋转,变换矩阵M可通过cv2.getRotationMatrix2D函数获得。

cv2.getRotationMatrix2D(center, angle, scale)

  • center: 原图像的旋转中心 
  • angle: 图像旋转角度,角度为正则表示逆时针旋转
  • scale: 缩放系数

输出矩阵如下所示

其中α = scale · cosθβ = scale· sinθ, 表示绕 center.x,center.y 旋转 θ

例如:

import cv2
import numpy as np

img = cv2.imread('test.jpg', 0)  # 以单通道灰度图像读入
rows, cols = img.shape
# 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
# 第三个参数是输出图像的尺寸中心
dst = cv2.warpAffine(img, M, (cols, rows))
while(1):
    cv2.imshow('src', img)
    cv2.imshow('dst', dst)
    if cv2.waitKey(1) & 0xFF == 27:
        break
cv2.destroyAllWindows()

结果如下:

 

4 仿射变换

一般的仿射变换的转换矩阵M也可以通过 cv2.getAffineTransform获得,这个方法更加简便直观。

 cv2.getAffineTransform(src,dst)

  • src:原图中3个点所组成的矩阵,数据类型为np.float32
  • dst:目标图中对应的3个点所组成的矩阵,数据类型为np.float32

变换过程如下图所示,3个点一 一对应映射

è¿éåå¾çæè¿°

例如:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('test8.jpg')
rows, cols, ch = img.shape
img1 = cv2.imread('test.jpg')
rows1, cols1, ch1 = img1.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))
dst1 = cv2.warpAffine(img1, M, (cols, rows))

plt.subplot(221), plt.imshow(img), plt.title('Input')
plt.subplot(222), plt.imshow(dst), plt.title('Output')
plt.subplot(223), plt.imshow(img1), plt.title('Input')
plt.subplot(224), plt.imshow(dst1), plt.title('Output')
plt.show()

结果如下:

 

5 透视变换

cv2.warpPerspective(src, M, dsize, dst, flags, borderMode, borderValue)

  • src:原图像
  • M:变换矩阵
  • dsize:输出图像的大小
  • flags:插值方法,如上表所示
  • borderMode:边界像素模式,默认为BORDER_CONSTANT ,边界按常数填充。

–cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。

– cv2.BORDER_REFLECT边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb

– cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba

– cv2.BORDER_REPLICATE重复最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh

– cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh| abcdefgh|abcdefg

效果可在这篇文章中看到:https://blog.csdn.net/yukinoai/article/details/86423937

  • borderValue:边界填充值; 默认为0,所以默认情况下填充为黑色

转换矩阵M可通过以下函数获得:

cv2.getPerspectiveTransform(src, dst)

  • src:原图中4个点所组成的矩阵,数据类型为np.float32
  • dst:目标图中对应的4个点所组成的矩阵,数据类型为np.float32

例如:

import cv2
import numpy as np
import matplotlib.pylab as plt

img = cv2.imread('test10.jpg')
rows, cols, ch = img.shape

# 设置标记点和目标点
markpoint = [[93, 651], [20, 197], [788, 540], [665, 20]]
dstpoint = [[0, 0], [352, 0], [0, 500], [352, 500]]

# 强调标记点
for i in markpoint:
    cv2.circle(img, tuple(i), 10, (0, 255, 0), -1)

# 转换点的格式
pts1 = np.float32(markpoint)
pts2 = np.float32(dstpoint)

# 生成透视矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)

# 转换
dst = cv2.warpPerspective(img, M, (352, 500))

plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

结果如下:

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值