The transform I am trying to get to is a 5 points facial landmark alignment.
Meaning I am trying to generate a transform using all 5 points of the input and dest.
Code:
import cv2
import numpy as np
from skimage import transform as trans
REFERENCE_FACIAL_POINTS = [
[30.29459953, 51.69630051],
[65.53179932, 51.50139999],
[48.02519989, 71.73660278],
[33.54930115, 87],
[62.72990036, 87],
]
Test_FACIAL_POINTS = [
[191.29459953, 330.69630051],
[362.53179932, 341.50139999],
[290.02519989, 414.73660278],
[206.54930115, 500],
[360.72990036, 507],
]
DEFAULT_CROP_SIZE = (96, 112)
face_size = (112, 112)
def trans1():
tfm, _ = cv2.estimateAffinePartial2D(np.array(Test_FACIAL_POINTS), REFERENCE_FACIAL_POINTS)
face_img = cv2.warpAffine(pic, tfm, face_size)
return face_img
def trans2():
M = trans.estimate_transform("similarity", np.array(Test_FACIAL_POINTS), REFERENCE_FACIAL_POINTS)
face_img = cv2.warpAffine(pic, M.params[0:2, :], face_size)
return face_img
box1 = trans1()
box2 = trans2()
Loading any random pic and applying both transforms, comparing the results, you will see that there is a problem. Playing with the Test points, the skimage is consistently correct and the cv2 version is consistently incorrect to various degree depending on the input. Both scale and rotation are wrong and don’t correspond to the destination except for the first 2 points.
The comment I am seeing from the function code on github and the code itself is consistent: “only two points are needed to estimate the transform”. Incorrect if input has more than two points.