【2】python-opencv3教程:图像的几何变化(放射变化:平移,旋转,缩放等,投影变化,极坐标变化)
第二节:几何变化
一:仿射变换(平移,缩放,旋转等)
1:缩放
表示的(x, y)坐标通过那个矩阵变为 x波浪,y波浪。 为什么每个坐标最下面还有一维是1,它是齐次的写法,这样的写法对将接下来的平移有些帮助。。 首先把等号右边的两个矩阵相乘,你就会发现:将图像放大,缩小,不就是让Sx和Sy取不同的值,对x缩放就是让Sx取不同的值,对y缩放就是让Sy取不同的值。。
import cv2
import numpy as np
# 仿射变换
image = cv2.imread('p1.jpg')
# 获取原图像的高,宽
h, w = image.shape[:2]
# 仿射变换矩阵, 缩小为原来的两倍
A1 = np.array([[0.5, 0, 0], [0, 0.5, 0]], np.float32) # 相当于长宽都变为原来的1/2
d1 = cv2.warpAffine(image, A1, (w, h), borderValue=125)
# 当图片缩小后, 你的长宽还是w, h那么就会有多余的空间 上面125是指定多余空间的像素值
cv2.imshow('img1', d1)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
2:平移
同理,将等号右边的两个矩阵进行相乘,你就会发现tx, ty取不同的值,可以让x和y坐标进行不同程度的偏移,这就是平移的道理。
# 先缩小两倍,在平移
A2 = np.array([[0.5, 0, w/4], [0, 0.5, h/4]], np.float32)
d2 = cv2.warpAffine(image, A2, (w, h), borderValue=125)
cv2.imshow('img2', d2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
3:旋转
A2 = np.array([[0.5, 0, w/4], [0, 0.5, h/4]], np.float32)
d2 = cv2.warpAffine(image, A2, (w, h), borderValue=125)
# 在d2的基础上绕中心点做旋转
A3 = cv2.getRotationMatrix2D((w/2.0, h/2.0), 30, 1)
d3 = cv2.warpAffine(d2, A3, (w, h), borderValue=125)
cv2.imshow('img3', d3)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
二: 投影变化
# 从一种坐标转换为另一种坐标 求转换的矩阵
src = np.array([[0, 0], [200, 0], [0, 200], [200, 200]], np.float32)
dst = np.array([[100, 20], [200, 20], [50, 70], [250, 70]], np.float32)
P = cv2.getPerspectiveTransform(src, dst)
print('坐标转换矩阵:', P)
输出结果:
# 我们读取一张图片做投影变化
image = cv2.imread('p1.jpg')
h, w = image.shape[:2]
src = np.array([[0, 0], [w-1, 0], [0, h-1], [w-1, h-1]], np.float32)
dst = np.array([[50, 50], [w/3, 50], [50, h-1], [w-1, h-1]], np.float32)
# 计算投影变换的矩阵
p = cv2.getPerspectiveTransform(src, dst)
# 利用计算出的矩阵对图片做投影
r = cv2.warpPerspective(image, p, (w, h), borderValue=125)
# 显示原图像和投影效果
cv2.imshow('image', image)
cv2.imshow('warpPerspective', r)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
三:极坐标变化
# 极坐标变化
# (11, 13)以(3, 5)为中心进行极坐标变化
import math
r = math.sqrt(math.pow(11-3, 2)+math.pow(13-5, 2))
theta = math.atan2(13-5, 11-3) / math.pi * 180
print(r, theta) # r是模长, theta是角度大小
# 上面是直接用Python做的, 我们接下来采用opencv提供的函数
x = np.array([[0, 1, 2], [0, 1, 2], [0, 1, 2]], np.float32) - 1
y = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]], np.float32) - 1
r, theta = cv2.cartToPolar(x, y, angleInDegrees=True) # 当angleInDegrees是True时,返回值为angle角度,否则为弧度
print(r, theta)
# 将极坐标转化为笛卡尔坐标(30, 10), (31, 10), (30, 11), (31, 11)这些坐标是在极坐标系下的坐标
angle = np.array([[30, 31], [30, 31]], np.float32)
r = np.array([[10, 10], [11, 11]], np.float32)
x, y = cv2.polarToCart(r, angle, angleInDegrees=True)
print(x, y) # 这样得出的是以(0, 0)为变换中心, 我们想让变换中心在(-12, 15)
x += -12
y += 15
print(x, y)
输出结果: