opencv python的warpAffine()函数代码底层实现

目录

    • 参考
    • 代码

参考

  1. opencv官方文档

  2. github代码地址

代码

函数接口请自行查看opencv官方文档。
以下为warpAffine()接口的简单实现版本,默认borderMode=None, borderValue=(114, 114, 114)

# Author: Jintao Huang
# Email: [email protected]
# Date: 2021-6-16

import numpy as np
import cv2 as cv
from numpy.linalg import inv


def _invertAffineTransform(matrix):
    """cv.invertAffineTransform(). 本质是求逆

    :param matrix: shape[2, 3]. float32
    :return: shape[2, 3]
    """
    matrix = np.concatenate([matrix, np.array([0, 0, 1], dtype=matrix.dtype)[None]])  # for求逆
    return inv(matrix)[:2]


# test
# matrix = np.array([[0.5, 1, 2], [0.4, 2, 1]])
# print(_invertAffineTransform(matrix))
# print(cv.invertAffineTransform(matrix))


def _warpAffine(x, matrix, dsize=None, flags=None):
    """cv.warpAffine(borderMode=None, borderValue=(114, 114, 114))

    :param x: shape[H, W, C]. uint8
    :param matrix: 仿射矩阵. shape[2, 3]. float32
    :param dsize: Tuple[W, H]. 输出的size
    :param flags: cv.WARP_INVERSE_MAP. 唯一可选参数
    :return: shape[dsize[1], dsize[0], C]. uint8
    """
    dsize = dsize or (x.shape[1], x.shape[0])  # 输出的size
    borderValue = np.array((114, 114, 114), dtype=x.dtype)  # 背景填充
    if flags is None or flags & cv.WARP_INVERSE_MAP == 0:  # flags无cv.WARP_INVERSE_MAP参数
        matrix = _invertAffineTransform(matrix)
    grid_x, grid_y = np.meshgrid(np.arange(dsize[0]), np.arange(dsize[1]))  # np.int32
    src_x = (matrix[0, 0] * grid_x + matrix[0, 1] * grid_y + matrix[0, 2]).round().astype(np.int32)  # X
    src_y = (matrix[1, 0] * grid_x + matrix[1, 1] * grid_y + matrix[1, 2]).round().astype(np.int32)  # Y
    src_x_clip = np.clip(src_x, 0, x.shape[1] - 1)  # for索引合法
    src_y_clip = np.clip(src_y, 0, x.shape[0] - 1)
    output = np.where(((0 <= src_x) & (src_x < x.shape[1]) & (0 <= src_y) & (src_y < x.shape[0]))[:, :, None],
                      x[src_y_clip, src_x_clip], borderValue[None, None])  # 广播机制
    return output


# test
# x0 = np.random.randint(0, 256, (600, 800, 3), dtype=np.uint8)
# matrix = np.array([[1, 1, 100], [1, 2, 80.]], dtype=np.float32)
# y = _warpAffine(x0, matrix, (500, 1000))
# y_ = cv.warpAffine(x0, matrix, (500, 1000), borderValue=(114, 114, 114))
# print(np.all(y == y_))

测试代码打印True, 说明复现正确。
(自己测试时,可能因为浮点数精确度、round()等带来打印为False的情况,这是正常的。
可以通过读入真实图片,并cv.imshow()的方式查看)

你可能感兴趣的:(深度学习,python,opencv,numpy,仿射)