图片仿射变换原理与实现

图像仿射变换共有“旋转”、“平移”、“错切(shear)”、“缩放”、“翻转”5种。本文结合keras-retinanet的实现进行分析。之所以采用keras-retinanet进行分析,是因为该实现较为典型,比较容易理解。

keras-retinanet官方地址:https://github.com/fizyr/keras-retinanet.git

以上五种仿射变换位于utils/transform.py中。仿射变换在代码中被用于目标检测任务的图像倍增。(PS:其实只有平移、缩放、翻转可以用于目标检测任务,因为旋转与错切后物体的boundingbox可能变大,我认为这可能造成boundingbox回归任务不准确)

1.旋转,相较于opencv实现的图片旋转,retinanet中自带的图片实现更为简单,更多的应该是从效率角度考虑。使用numpy实现可以同时处理多组图片。但opencv的图片旋转更为复杂,除了围绕图片中心旋转外,还可以围绕图片任意一点旋转,并调整缩放比例。

def rotation(angle):
    """ Construct a homogeneous 2D rotation matrix.
    Args
        angle: the angle in radians
    Returns
        the rotation matrix as 3 by 3 numpy array
    """
    return np.array([
        [np.cos(angle), -np.sin(angle), 0],
        [np.sin(angle),  np.cos(angle), 0],
        [0, 0, 1]
    ])

其实仅需要2*2矩阵既可以解决,使用3*3矩阵为将旋转矩阵表示为齐次形式。

2.平移

def translation(translation):
    """ Construct a homogeneous 2D translation matrix.
    # Arguments
        translation: the translation 2D vector
    # Returns
        the translation matrix as 3 by 3 numpy array
    """
    return np.array([
        [1, 0, translation[0]],
        [0, 1, translation[1]],
        [0, 0, 1]
    ])

3.错切

def shear(angle):
    """ Construct a homogeneous 2D shear matrix.
    Args
        angle: the shear angle in radians
    Returns
        the shear matrix as 3 by 3 numpy array
    """
    return np.array([
        [1, -np.sin(angle), 0],
        [0,  np.cos(angle), 0],
        [0, 0, 1]
    ])

4.缩放

def scaling(factor):
    """ Construct a homogeneous 2D scaling matrix.
    Args
        factor: a 2D vector for X and Y scaling
    Returns
        the zoom matrix as 3 by 3 numpy array
    """
    return np.array([
        [factor[0], 0, 0],
        [0, factor[1], 0],
        [0, 0, 1]
    ])

5.翻转

翻转同样是用scaling实现的,直接与“+1/-1”相乘即可以实现翻转。

def random_flip(flip_x_chance, flip_y_chance, prng=DEFAULT_PRNG):
    """ Construct a transformation randomly containing X/Y flips (or not).
    Args
        flip_x_chance: The chance that the result will contain a flip along the X axis.
        flip_y_chance: The chance that the result will contain a flip along the Y axis.
        prng:          The pseudo-random number generator to use.
    Returns
        a homogeneous 3 by 3 transformation matrix
    """
    flip_x = prng.uniform(0, 1) < flip_x_chance
    flip_y = prng.uniform(0, 1) < flip_y_chance
    # 1 - 2 * bool gives 1 for False and -1 for True.
    return scaling((1 - 2 * flip_x, 1 - 2 * flip_y))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章