zoukankan      html  css  js  c++  java
  • SKimage

    相似变换

    相似变换:等距变换+均匀尺度缩放;

    等距变换:平移+旋转,所谓平移旋转其实就是 wx+b,w 和 b 组成变换矩阵

    在等距变换中,角度、平行性、垂直性 不发生变换 

    SimilarityTransform 用法

    这是一个类

    class SimilarityTransform(EuclideanTransform):
        def __init__(self, matrix=None, scale=None, rotation=None,
                     translation=None):

    参数解释:

    matrix:可选,(3,3)齐次变换矩阵,即 相似变换矩阵

        Has the following form::
    
            X = a0 * x - b0 * y + a1 =
              = s * x * cos(rotation) - s * y * sin(rotation) + a1
            Y = b0 * x + a0 * y + b1 =
              = s * x * sin(rotation) + s * y * cos(rotation) + b1
    
        where ``s`` is a scale factor and the homogeneous transformation matrix is::
            [[a0  b0  a1]
             [b0  a0  b1]
             [0   0    1]]

    scale:缩放因子

    rotation:旋转角度,逆时针,以弧度表示角度

    translation: 平移参数(tx, ty)

    相关方法

        def estimate(self, src, dst):
            """
            Parameters
            ----------
            src : (N, 2) array
                Source coordinates.
            dst : (N, 2) array
                Destination coordinates.
    
            Returns
            -------
            success : bool
                True, if model estimation succeeds.
            """

    从一组对应点(源点、目标点)估计变换矩阵

    示例代码1

    from skimage import transform as trans
    import numpy as np
    src = np.array([
        [38.2946, 51.6963],
        [73.5318, 51.5014],
        [56.0252, 71.7366],
        [41.5493, 92.3655],
        [70.7299, 92.2041] ], dtype=np.float32)
    dst = np.array([
        [38.2946, 51.6963],
        [73.5318, 51.5014],
        [56.0252, 71.7366],
        [41.5493, 92.3655],
        [70.7299, 92.2041] ], dtype=np.float32)
    tform = trans.SimilarityTransform()
    res =tform.estimate(dst, src)
    M = tform.params
    print(res)
    print(M)

    获取变换矩阵用 params

    [[ 1.00000004e+00  0.00000000e+00 -2.47753889e-06]
     [ 0.00000000e+00  1.00000004e+00 -3.17953211e-06]
     [ 0.00000000e+00  0.00000000e+00  1.00000000e+00]]

    示例代码2

    from skimage import io,data
    from skimage import transform as tf
    import matplotlib.pylab as plt
    
    ### 原图
    img = data.camera()
    io.imshow(img)
    plt.show()
    
    ### 相似变换
    tform = tf.SimilarityTransform(scale=1.5,rotation=np.deg2rad(10),translation=(10,12))
    img1 = tf.warp(img,tform)
    io.imshow(img1)
    plt.show()

    人脸对齐

    在人脸识别时,有时候 检测到的人脸是 倾斜的,此时需要把脸扶正,这就叫人脸对齐

    人脸对齐有很多方法,相似变换只是最简单的一种;

    大体思路

    人脸检测时会识别到 人脸关键点,这是 相似变换的源点

    假设我们最后要截取一张(112,96)大小的正脸,那么人脸的五个关键点分别在什么位置才算是正脸呢?所以我们需要五个参考点,作为 目标点

    根据 N 组 源点、目标点得到变换矩阵;

    把整张脸 乘以 变换矩阵 得到 变换后的 正脸;

    import numpy as np
    import cv2
    import matplotlib.pylab as plt
    from skimage import transform
    
    ################### 人脸关键点标注 ###################
    landmark = np.array([[153, 244, 215, 214, 292, 252, 196, 292, 346, 300]])
    landmark = np.reshape(landmark, (2, 5)).T
    print(landmark)
    
    img = cv2.imread('wt.jpg')
    for point in landmark:
        cv2.circle(img, tuple(point), 2, (0, 0, 255))
    
    cv2.imshow('img', img)
    cv2.waitKey(10000)
    
    ################### 标准脸的关键点 ###################
    REFERENCE_FACIAL_POINTS = np.array([
        [30.29459953,  51.69630051],
        [65.53179932,  51.50139999],
        [48.02519989,  71.73660278],
        [33.54930115,  92.3655014],
        [62.72990036,  92.20410156]
    ], np.float32)
    
    # Lets create a empty image|
    empty_img = np.zeros((112,96,3), np.uint8)
    
    for point in REFERENCE_FACIAL_POINTS:
        cv2.circle(empty_img, tuple(point), 2, (0, 0, 255))
    
    plt.figure(figsize=(5, 5))
    plt.imshow(empty_img)
    plt.show()
    
    ################### 把人脸1和标准脸对齐 ###################
    #### 变换矩阵
    trans = transform.SimilarityTransform()
    res = trans.estimate(landmark, REFERENCE_FACIAL_POINTS)
    M = trans.params
    print(res)          # True
    print(M)        # 变换矩阵
    # [[  0.29581306  -0.16732268  28.26420688]
    #  [  0.16732268   0.29581306 -47.51195016]
    #  [  0.           0.           1.        ]]
    
    #### 人脸对齐
    print(M[:2, :])
    new_img = cv2.warpAffine(img, M[:2, :], dsize=(120, 120))
    cv2.imshow('new_img', new_img)
    cv2.waitKey(1000000)

     最后一张就是 对齐后 的人脸

    参考资料:

    https://blog.csdn.net/C_chuxin/article/details/100546657  skimage库的transform.SimilarityTransform()用法

    https://www.jianshu.com/p/57c440af5760  人脸对齐

    https://zhuanlan.zhihu.com/p/61343643  从零开始搭建人脸识别系统(二):人脸对齐

  • 相关阅读:
    队列与堆栈
    Python中的内置函数
    Centos 7 最小化部署svn版本控制(svn协议)
    Android中的一些简单的adb命令
    liunx服务程序的安装及配置
    liunx中安装包及其应用
    liunx网络基本命令
    liunx系统和其它的基本命令
    liunx用户管理的基本命令
    liunx的磁盘管理的基本命令
  • 原文地址:https://www.cnblogs.com/yanshw/p/13673063.html
Copyright © 2011-2022 走看看