OpenCV Python学习笔记(七)

时间:2022-02-08 06:41:27
# -*-coding:utf-8

# 几何变换
# 目标:
# 几个变换,移动,旋转,仿射变换等
# 函数:cv2.getPerspectiveTransform()
# 变换 OpenCV提供了两个变换函数,cv2.warpAffine和cv2.warpPerspective
# 使用这两个函数你可以实现所有类型的变换
# cv2.warpAffine 接收的参数是 2×3 的变换矩阵
# cv2.warpPerspective 接收的参数是 3×3 的变换矩阵


# 扩展缩放:cv2.resize()
import cv2
import numpy as np

# img = cv2.imread("02.jpg")
# # print img.shape
# # # (1378L, 960L, 3L)
#
# # # 下面的None本应该是输出图像的尺寸,但是因为后边我们设置了缩放因子(fx,fy)
# # # 因此这里为None
# res = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
# # # 另一种表达方式
# # width, height = img.shape[:2]
# # res = cv2.resize(img, (0.5*width, 0.5*height),interpolation=cv2.INTER_CUBIC)
# print res.shape
# # (689L, 480L, 3L)
# cv2.imshow("img", img)
# cv2.imshow("res", res)
# if cv2.waitKey(0) & 0xFF == 27:
# cv2.destroyAllWindows()

# 平移

# 平移就是将对象换一个位置。如果你要沿(x,y)方向移动,移动的距离 是(tx,ty),
# 你可以以下面的方式构建移动矩阵:
# |1 0 tx|
# M = | |
# |0 1 ty| 
# 你可以使用 Numpy 数组构建这个矩阵(数据类型是 np.float32)
# 然后把它传给函数 cv2.warpAffine()
# img = cv2.imread("02.jpg")
# rows, cols, ch = img.shape
# M = np.float32([[1, 0 , 100],[0, 1, 50]]) # 构建矩阵
# res = cv2.warpAffine(img, M, (cols, rows))
# cv2.imshow("img", img)
# cv2.imshow("res", res)
# if cv2.waitKey(0)&0xFF == 27:
# cv2.destroyAllWindows()

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

# 旋转
# 对一个图像旋转角度 θ, 需要使用到下面形式的旋转矩阵。
# M = cosθ −sinθ
# sinθ cosθ  
# 但是 OpenCV 允许你在任意地方进行旋转,但是旋转矩阵的形式应该修
# 改为  
# M = α β (1−α)·center.x−β ·center.y
# −β α β ·center.x + (1−α)·center.x  
# 其中:
# α = scale·cosθ
# β = scale·sinθ
# 为了构建这个旋转矩阵,OpenCV提供了一个函数:cv2.getRotationMatrix2D。
#
# f_img = cv2.imread("02.jpg")
# img = cv2.resize(f_img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
# rows, cols, ch = img.shape
# # 这里的第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
# # 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
# M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)
# # 第三个参数是输出图像的尺寸中心
# dst=cv2.warpAffine(img,M,(2*cols,2*rows))
# while(1):
# cv2.imshow('img',dst)
# if cv2.waitKey(1)&0xFF==27:
# break
# cv2.destroyAllWindows()

# 仿射变换(Affine Transformation或 Affine Map)是一种二维坐标到二维坐标之间的线性变换,
# 它保持了二维图形的“平直性”(即:直线经过变换之后依然是直线)和
# “平行性”(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。
# 放射变换可以写为如下的形式:
# x1 = a1*x0 + b1*y0 + c1
# y1 = a2*x0 + b2*y0 + c2
# 或者用矩阵表示(意思一下)
# |x1| |a1 b1 c1| |x|
# | | = | |* |y|
# |y1| |a2 b2 c2| |1|
# 仿射变换简单点说可以是有平移、错切、缩放、反转、旋转复合而成
# 在OpenCV中为了创建这个矩阵需要从原图像中找到三个点以及他们在输出图像中的位置
# 然后 cv2.getAffineTransform 会创建一个 2x3 的矩阵
# 最后这个矩阵会被传给函数 cv2.warpAffine()

# img = cv2.imread("02.jpg")
# rows, cols, ch = img.shape
#
# pos1 = np.float32([[50, 50], [200, 50], [50, 200]]) # 原始图像中的点
# pos2 = np.float32([[10, 100], [200, 50], [100, 250]]) # 变换后原图中的点应该在的位置
#
# M = cv2.getAffineTransform(pos1, pos2)
#
# dst = cv2.warpAffine(img, M, (cols, rows)) # (宽, 高)的形式
# cv2.imshow("img", img)
# cv2.imshow("dst", dst)
# if cv2.waitKey(0)&0xFF == 27:
# cv2.destroyAllWindows()


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

img = cv2.imread("02.jpg")
rows, cols, ch = img.shape

pos1 = np.float32([[56, 65], [368, 52], [28, 387], [398, 390]]) # 原图像的点
pos2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]]) # 变换后pos1点在新图上点的位置

M = cv2.getPerspectiveTransform(pos1, pos2) # 形成透视变换的矩阵

dst = cv2.warpPerspective(img, M, (cols, rows))

cv2.imshow("img", img)
cv2.imshow("dst", dst)
if cv2.waitKey(0)&0xFF == 27:
cv2.destroyAllWindows()