OpenCV Python 几何变换
【目标】
- 学习平移、旋转、缩放、仿射变换、透视变换
- cv2.getPerspectiveTransform
仿射变换是平面内的,是多次线性变换的结果,保留了平行性,用3个点就可得到对应的变换矩阵。
透视变换 2D-3D,必须用4个点才能得到变换矩阵;
- 平移
- 缩放
- 旋转
- 错切
- 仿射变换
- 透视变换
其中,假定
从上述公式可以看出,需要4个点
【代码】
- OpenCV Python 图像缩放
import numpy as np
import cv2
img = cv2.imread('messi5.jpg')
res = cv2.resize(img, None, fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
# #OR
# height, width = img.shape[:2]
# res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)
cv2.imshow("img", img)
cv2.imshow("res", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
- OpenCV Python 图像平移
import numpy as np
import cv2
img = cv2.imread('messi5.jpg', 0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img, M, (cols,rows))
cv2.imshow('img',img)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
- OpenCV Python 图像旋转
import numpy as np
import cv2
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv2.warpAffine(img,M,(cols, rows))
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
- OpenCV Python 仿射变换
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[20,20],[110,20],[50,110]])
pts2 = np.float32([[10,50],[120,40],[30,150]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
- OpenCV Python 图像透视变换
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.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 = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.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()
【接口说明】
- cv2.warpAffine(img, M, (cols,rows))
void cv::warpAffine ( InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
);
cv2.warpAffine( src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]] ) -> dst
对一个图像进行仿射变换
src: 输入图像
dst: 输出图像,像素类型和源图像一致,尺寸可以指定
M: 2x3的变换矩阵
dsize: 输出图像的尺寸
flags: 插值方法,见InterpolationFlags
borderMode: 边缘模式,见下面的BorderTypes
borderValue: 默认为0,当边缘模式为 constant时,填充的值
InterpolationFlags
BorderTypes
- cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
Mat cv::getRotationMatrix2D ( Point2f center,
double angle,
double scale
);
cv2.getRotationMatrix2D( center, angle, scale ) -> retval
通过
中心点,旋转角度和尺度
来计算仿射变换矩阵
center: 源图像的旋转中心
angle: 旋转角度
scale: 各项同性变化因子
- cv2.getAffineTransform(pts1,pts2)
//
Mat cv::getAffineTransform(const Point2f src[],
const Point2f dst[]
);
Mat cv::getAffineTransform(InputArray src,
InputArray dst
);
cv2.getAffineTransform( src, dst ) -> retval
通过变换前的点和变换后的点计算仿射变换矩阵,提供3对点就可以了
src: 源图像的顶点
dst: 仿射变换后的顶点
- cv2.getPerspectiveTransform(pts1, pts2)
Mat cv::getPerspectiveTransform ( InputArray src,
InputArray dst,
int solveMethod = DECOMP_LU
);
Mat cv::getPerspectiveTransform ( const Point2f src[],
const Point2f dst[],
int solveMethod = DECOMP_LU
);
cv2.getPerspectiveTransform( src, dst[, solveMethod] ) -> retval
计算透射变换矩阵, 至少4个点
src: 输入点集
dst: 变换后的点集
solveMethod: 矩阵分解类型
DecompTypes
- cv2.warpPerspective(img, M, (300, 300))
void cv::warpPerspective ( InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
);
cv2.warpPerspective( src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]] ) -> dst
透视变换
src: 输入图像
dst: 输出图像,像素类型和源图像一致,尺寸可以指定
M: 2x3的变换矩阵
dsize: 输出图像的尺寸
flags: 插值方法,见InterpolationFlags
borderMode: 边缘模式,见下面的BorderTypes
borderValue: 默认为0,当边缘模式为 constant时,填充的值
【参考】