9, opencv核心操作学习- 几何变换

1,342 阅读3分钟

本编文章概念相关参考: www.cnblogs.com/gcczhongdua…

1, 缩放

resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)

参数 含义
src 输入图像
dsize 输出图像的尺寸
dst
fx x轴方向的缩放因子
fy y轴方向的缩放因子
interpolation 插值方法
interpolation
取值 含义
INTER_AREA 基于局部像素的重采样 (缩放推荐)
INTER_BITS
INTER_BITS2
INTER_CUBIC 基于4x4像素邻域的3次插值法 (放大推荐)
INTER_LANCZOS4 基于8x8像素邻域的Lanczos插值
INTER_LINEAR (放大推荐)
INTER_MAX
INTER_NEAREST 双线性插值法 (默认)
INTER_TAB_SIZE
INTER_TAB_SIZE2
# coding:utf-8

import cv2
import numpy as np

def show(img):
    # cv2.namedWindow('aa', cv2.WINDOW_NORMAL)
    cv2.imshow('aa', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':

    img = cv2.imread('./001_720x1080.jpg', cv2.IMREAD_UNCHANGED)
    height, width = img.shape[:2]
    out  = cv2.resize(img,dsize=(width*2, height*2), fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)
    show(out)
    pass

2, 平移

warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

参数 含义
src 输入图像
M 变换矩阵
dsize 输入图像的尺寸
dst
flags 插值方法
borderMode 空白点的插值模式? (None为黑)
borderValue
flags
取值 含义
WARP_FILL_OUTLIERS = 8 填充所有输出图像的象素。如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval.
WARP_INVERSE_MAP = 16 指定 map_matrix 是输出图像到输入图像的反变换,因此可以直接用来做象素插值。否则, 函数从 map_matrix 得到反变换。

构建移动矩阵

沿(x, y)轴方向分别移动了 tx, ty的距离

M =\begin{bmatrix}
    1 & 0 & t_x \\
   0 & 1 & t_y
\end{bmatrix}
# coding:utf-8

import cv2
import numpy as np

def show(img):
    # cv2.namedWindow('aa', cv2.WINDOW_NORMAL)
    cv2.imshow('aa', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':

    img = cv2.imread('./001_720x1080.jpg', cv2.IMREAD_UNCHANGED)
    M = np.array([[1,0,100],[0,1,50]],np.float32)
    height, width = img.shape[:2]
    out = cv2.warpAffine(img, M, (width, height))
    show(out)

3, 旋转

getRotationMatrix2D(center, angle, scale)

获取旋转的矩阵

参数 含义
center 旋转中心点
angle 旋转角度 (顺时针角度为负)
scale 缩放比例(不缩放为1)

构建旋转矩阵, 旋转矩阵略有点复杂, opencv为了简化构建过程, 提供了函数 cv2.getRotationMatrix2D。

在不缩放的情况下, 将图像围绕图片中心点顺时针旋转45° (顺时针角度为负)

# coding:utf-8

import cv2
import numpy as np

def show(img):
    # cv2.namedWindow('aa', cv2.WINDOW_NORMAL)
    cv2.imshow('aa', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':

    img = cv2.imread('./001_720x1080.jpg', cv2.IMREAD_UNCHANGED)
    height, width = img.shape[:2]
    M = cv2.getRotationMatrix2D((width/2, height/2), -45, 1)
    out = cv2.warpAffine(img, M, (width, height))
    show(out)

4, 仿射变换

getAffineTransform(src, dst)

用于计算出放射变换的矩阵

参数 含义
src 原图上的三个点
dst 转换后的三个点

在仿射变换中虽原图中所有的平行线在结果图像中同样平行

# coding:utf-8

import cv2
import numpy as np

def show(img):
    # cv2.namedWindow('aa', cv2.WINDOW_NORMAL)
    cv2.imshow('aa', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':

    img = cv2.imread('./001_720x1080.jpg', cv2.IMREAD_UNCHANGED)
    height, width = img.shape[:2]
    pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
    pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
    M = cv2.getAffineTransform(pts1, pts2)
    out = cv2.warpAffine(img, M, (width, height))
    show(out)

5, 透视变换

getPerspectiveTransform(src, dst)

用于计算出透视变换的矩阵

参数 含义
src 原图上的四个点
dst 转换后的四个点

warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

透视变换

参数 含义
src 输入图像
M 变换矩阵
dsize 输入图像的尺寸
dst
flags 插值方法
borderMode 空白点的插值模式? (None为黑)
borderValue

比如我们拍摄了一张身份证(网络上的图), 我们想要把他变正

# coding:utf-8

import cv2
import numpy as np


def show(img):
    # cv2.namedWindow('aa', cv2.WINDOW_NORMAL)
    cv2.imshow('aa', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == '__main__':
    # 一次从(左上,左下,右下,右上) 取点
    img = cv2.imread('./sfz.jpg', cv2.IMREAD_UNCHANGED)
    height, width = img.shape[:2]
    print("%s, %s" % (width, height))
    pts1 = np.float32([[50, 65], [78, 292], [457, 238], [414, 17]])
    pts2 = np.float32([[0,0], [0, 540], [856, 540], [856, 0]])
    M = cv2.getPerspectiveTransform(pts1, pts2)
    out = cv2.warpPerspective(img, M, (856, 540))
    show(out)