From d9c952ba2cec34aeb310a16ea81c9efb28da14f4 Mon Sep 17 00:00:00 2001 From: GivralNguyen Date: Fri, 16 Jul 2021 09:40:22 +0700 Subject: [PATCH] Fix align face bug for odd cases --- recognition/_tools_/cpp_align/face_align.h | 28 ++++++++++------------ 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/recognition/_tools_/cpp_align/face_align.h b/recognition/_tools_/cpp_align/face_align.h index aee9ec9..afef20b 100644 --- a/recognition/_tools_/cpp_align/face_align.h +++ b/recognition/_tools_/cpp_align/face_align.h @@ -93,9 +93,9 @@ namespace FacePreprocess { d.at(dim - 1, 0) = -1; } - Mat T = cv::Mat::eye(dim + 1, dim + 1, CV_32F); + cv::Mat T = cv::Mat::eye(dim + 1, dim + 1, CV_32F); cv::Mat U, S, V; - SVD::compute(A, S,U, V); + cv::SVD::compute(A, S,U, V); // the SVD function in opencv differ from scipy . @@ -108,18 +108,14 @@ namespace FacePreprocess { if (cv::determinant(U) * cv::determinant(V) > 0) { T.rowRange(0, dim).colRange(0, dim) = U * V; } else { -// s = d[dim - 1] -// d[dim - 1] = -1 -// T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V)) -// d[dim - 1] = s int s = d.at(dim - 1, 0) = -1; d.at(dim - 1, 0) = -1; T.rowRange(0, dim).colRange(0, dim) = U * V; cv::Mat diag_ = cv::Mat::diag(d); cv::Mat twp = diag_*V; //np.dot(np.diag(d), V.T) - Mat B = Mat::zeros(3, 3, CV_8UC1); - Mat C = B.diag(0); + cv::Mat B = cv::Mat::zeros(3, 3, CV_8UC1); + cv::Mat C = B.diag(0); T.rowRange(0, dim).colRange(0, dim) = U* twp; d.at(dim - 1, 0) = s; } @@ -128,20 +124,20 @@ namespace FacePreprocess { cv::Mat diag_ = cv::Mat::diag(d); cv::Mat twp = diag_*V.t(); //np.dot(np.diag(d), V.T) cv::Mat res = U* twp; // U - T.rowRange(0, dim).colRange(0, dim) = -U.t()* twp; + T.rowRange(0, dim).colRange(0, dim) = U * diag_ * V; } cv::Mat var_ = varAxis0(src_demean); float val = cv::sum(var_).val[0]; cv::Mat res; cv::multiply(d,S,res); float scale = 1.0/val*cv::sum(res).val[0]; - T.rowRange(0, dim).colRange(0, dim) = - T.rowRange(0, dim).colRange(0, dim).t(); - cv::Mat temp1 = T.rowRange(0, dim).colRange(0, dim); // T[:dim, :dim] - cv::Mat temp2 = src_mean.t(); //src_mean.T - cv::Mat temp3 = temp1*temp2; // np.dot(T[:dim, :dim], src_mean.T) - cv::Mat temp4 = scale*temp3; - T.rowRange(0, dim).colRange(dim, dim+1)= -(temp4 - dst_mean.t()) ; - T.rowRange(0, dim).colRange(0, dim) *= scale; + cv::Mat temp1 = T.rowRange(0, dim).colRange(0, dim) * src_mean.t(); + cv::Mat temp2 = scale * temp1; + cv::Mat temp3 = dst_mean - temp2.t(); + T.at(0,2) = temp3.at(0); + T.at(1,2) = temp3.at(1); + T.rowRange(0, dim).colRange(0, dim) *= scale; // T[:dim, :dim] *= scale + return T; }