SKimage-transform.SimilarityTransform 相似變換 及其 人臉對齊的應用


相似變換

相似變換:等距變換+均勻尺度縮放;

等距變換:平移+旋轉,所謂平移旋轉其實就是 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  從零開始搭建人臉識別系統(二):人臉對齊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM