别人没那么重要,我也没那么重要,好好活着,把能做的小事做好,够不到的东西就放弃,承认就好。做一个心情好能睡着的人,你所有事情都会在正轨上。

PythonOpenCV-图像变换-几何变换

1. 缩放

函数原型

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

参数说明

dst:转换后的图像

src:用于缩放的图像

dsize:转换后的图像大小

fx:水平方向的缩放比例

fy:垂直方向的缩放比例

interpolation:插值方式。由于在转换过程中,可能存在一些不能通过转换算法确定值的像素,插值方式决定了如何获取这些像素的值。

  cv2.INTER_NEAREST:最近邻插值

  cv2.INTER_LINEAR:双线性插值,默认方式

  cv2.INTER_CUBIC:3次样条插值

  cv2.INTER_AREA:区域差值

  cv2.INTER_LANCZOS4:Lanczos插值

  cv2.INTER_LINEAR_EXACT:位精确双线性插值

  cv2.INTER_MAX:插值编码掩码

  cv2.WARP_FILL_OUTLIERS:标志,填充目标图像中的所有像素

  cv2.WARP_INVERSE_MAP:标志,逆变换

  • cv2.resize()函数在转换图像时,目标图像的类型和大小与转换之前dst表示的图像无关。目标图像的类型与src表示的原图像一致,其大小可通过参数dsize、fx、fy来确定。
  • 当dsize不为None时,不管是否设置参数fx、fy,都由dsize来确定目标图像的大小。
  • dsize是一个二元组,其格式为"(width, height)"width表示目标图像的宽度,height表示目标图像的高度。
  • 当dsize为None时,参数fx、fy都不能为0,此时图像的宽度为"round(原图像的宽度 * fx)",目标图像的高度为"round(原图像的高度 * fy)"。

代码示例

import cv2 as cv

src = cv.imread(r"D:\PersonalFile\Picture\flower.jpg")
cv.imshow("src", src)
sc = [1, 0.2, 0.5, 1.5, 2]    # 设置缩放比例
while True:
    key = cv.waitKey()
    if 48 <= key <= 52:    # 按键[0][1][2][3]或[4]
        x = y = sc[key-48]   # 获取缩放比例
        dst = cv.resize(src, None, fx=x, fy=y)   #缩放图像
        cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

2. 翻转

函数原型

dst = cv2.flip(src, flipCode)

参数说明

dst:转换后的图像

src:用于翻转的图像

flipCode:翻转类型

flipCode为0时表示绕x轴翻转(垂直翻转),flipCode大于0的整数时表示绕y轴翻转(水平翻转),flipCode为小于0的整数时表示同时绕x和y轴翻转。

代码示例

import cv2 as cv

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
while True:
    key = cv.waitKey()
    if key == 48:
        dst = src   # 按键[0] 显示原图
    elif key == 49:
        dst = cv.flip(src, 0)  # 按键[1] 垂直翻转
    elif key == 50:
        dst = cv.flip(src, 1)  # 按键[2] 水平翻转
    elif key == 51:
        dst = cv.flip(src, -1)  # 按键[3] 垂直、水平同时翻转
    cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

3. 仿射

  放射变换包含了平移、旋转、缩放等操作,其主要特点是:原图像中的所有平行线在转换后的图像中仍然平行。

函数原型

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

参数说明

dst:转换后的图像,图像类型与原图一致,大小由dsize决定

src:原图像

dsize:转换后的图像大小

M:一个大小为2 * 3的转换矩阵,使用不同的转换矩阵可实现平移、旋转等多种操作

flags:插值方式,默认是cv2.INTER_LINEAR

borderMode:边类型,默认为cv2.BORDER_CONSTANT

borderValue:边界值,默认为0

在cv2.warpAffine()函数省略可选参数时,图像转换的矩阵运算公式如下:

 

3.1 平移

  将图像沿水平方向或垂直方向移动一定的像素。假设将图像水平移动m个像素,垂直移动n个像素,则图像转换的矩阵运算公式如下:

 

  等价于如下公式:

  所以,转换矩阵为:   

 

代码示例

import cv2 as cv
import numpy as np

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
# 获取图像高度、宽度
height = src.shape[0]
width = src.shape[1]
dsize = (width, height)

# 创建转换矩阵
m = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv.warpAffine(src, m, dsize)   # 平移

cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

3.2 缩放

  假设图像的宽度缩放比例为h,高度缩放比例为v,根据图像转换的矩阵运算公式可得出执行缩放的转换矩阵

 

代码示例

import cv2 as cv
import numpy as np

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
# 获取图像高度、宽度
height = src.shape[0]
width = src.shape[1]
dsize = (width, height)

# 创建转换矩阵
m = np.float32([[0.5, 0, 0], [0, 0.5, 0]])
dst = cv.warpAffine(src, m, dsize)   # 缩放

cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

3.3 旋转

  OpenCV中的cv2.getRotationMatrix2D()函数可用于计算执行旋转操作的转换矩阵。

函数原型

m = cv2.getRotationMatrix2D(center, angle, scale)

参数说明

center:原图中作为旋转中心的坐标

angle:旋转角度。正数表示逆时针旋转,负数表示顺时针旋转

scale:目标图像与原图像的大小比例

代码示例

import cv2 as cv

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
# 获取图像高度、宽度
height = src.shape[0]
width = src.shape[1]
dsize = (width, height)

# 创建转换矩阵
m = cv.getRotationMatrix2D((width/2, height/2), -60, 0.5)  # 顺时针旋转60°
dst = cv.warpAffine(src, m, dsize)   # 旋转

cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

3.4 三点映射变换

  三点映射变换会将图像转换为任意的平行四边形,cv2.getAffineTransform()函数用于计算其转换矩阵。
函数原型

m =cv2.getAffineTransform(src, dst)

参数说明

src:原图像中3个点的坐标

dst:原图像中3个点在目标图像中的对应坐标。

  cv2.getAffineTransform()函数将src和dst中的3个点作为平行四边形左上角、右上角和左下角的3个点,按原图和目标图与3个点之间的坐标关系计算所有像素的转换矩阵。
代码示例

import cv2 as cv
import numpy as np

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
# 获取图像高度、宽度
height = src.shape[0]
width = src.shape[1]
dsize = (width, height)

# 创建转换矩阵
mat1 = np.float32([[0, 0], [width-15, 0], [0, height-5]])
mat2 = np.float32([[50, 50], [width-150, 50], [100, height-50]])
m = cv.getAffineTransform(mat1, mat2)

dst = cv.warpAffine(src, m, dsize)
cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

3.5 透视

  透视会将图像转换为任意的四边形,主要特点:原图像中的所有直线在转换后的图像中仍然是直线。

  cv2.warpPerspective()函数用于执行透视变换操作
函数原型

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

参数说明

dst:转换后的图像,图像类型与原图一致,大小由dsize决定

src:原图像

dsize:转换后的图像大小

M:一个大小为3 * 3的转换矩阵,使用不同的转换矩阵可实现平移、旋转等多种操作

flags:插值方式,默认是cv2.INTER_LINEAR

borderMode:边类型,默认为cv2.BORDER_CONSTANT

borderValue:边界值,默认为0

  OpenCV的cv2.getPerspectiveTransform()函数用于计算其转换矩阵.
函数原型

cv2.getPerspectiveTransform(src, dst)

参数说明

src:原图像中4个点的坐标

dst:原图像中4个点在目标图像中的对应坐标。

代码示例

import cv2 as cv
import numpy as np

src = cv.imread(r"D:\PersonalFile\Picture\lena.jpg")
cv.imshow("src", src)
# 获取图像高度、宽度
height = src.shape[0]
width = src.shape[1]
dsize = (width, height)

# 创建转换矩阵
mat1 = np.float32([[0, 0], [width-10, 0], [0, height-10], [width-1, height-1]])
mat2 = np.float32([[50, 50], [width-50, 80], [50, height-100], [width-100, height-00]])
m = cv.getPerspectiveTransform(mat1, mat2)

dst = cv.warpPerspective(src, m, dsize)
cv.imshow("dst", dst)
cv.waitKey(0)

运行结果

 

/*-------------------------------------------------------------------------------------------------------

笔者说明:

  该笔记来源于本人学习Python + OpenCv时的资料,

  分享出来只是为了供大家学习,并且为了自己以后想要用的时候方便寻找。

时间:2023年4月16日

------------------------------------------------------------------------------------------------------------*/

 

posted @ 2023-04-16 18:14  一路狂奔的乌龟  阅读(133)  评论(0)    收藏  举报
返回顶部