Skip to content

Commit 2b74d93

Browse files
committed
add cpp align
1 parent 531bcb7 commit 2b74d93

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

cpp-align/FacePreprocess.h

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//
2+
// Created by Jack Yu on 23/03/2018.
3+
//
4+
5+
#ifndef FACE_DEMO_FACEPREPROCESS_H
6+
#define FACE_DEMO_FACEPREPROCESS_H
7+
8+
#include<opencv2/opencv.hpp>
9+
10+
11+
namespace FacePreprocess {
12+
13+
cv::Mat meanAxis0(const cv::Mat &src)
14+
{
15+
int num = src.rows;
16+
int dim = src.cols;
17+
18+
// x1 y1
19+
// x2 y2
20+
21+
cv::Mat output(1,dim,CV_32F);
22+
for(int i = 0 ; i < dim; i ++)
23+
{
24+
float sum = 0 ;
25+
for(int j = 0 ; j < num ; j++)
26+
{
27+
sum+=src.at<float>(j,i);
28+
}
29+
output.at<float>(0,i) = sum/num;
30+
}
31+
32+
return output;
33+
}
34+
35+
cv::Mat elementwiseMinus(const cv::Mat &A,const cv::Mat &B)
36+
{
37+
cv::Mat output(A.rows,A.cols,A.type());
38+
39+
assert(B.cols == A.cols);
40+
if(B.cols == A.cols)
41+
{
42+
for(int i = 0 ; i < A.rows; i ++)
43+
{
44+
for(int j = 0 ; j < B.cols; j++)
45+
{
46+
output.at<float>(i,j) = A.at<float>(i,j) - B.at<float>(0,j);
47+
}
48+
}
49+
}
50+
return output;
51+
}
52+
53+
54+
cv::Mat varAxis0(const cv::Mat &src)
55+
{
56+
cv:Mat temp_ = elementwiseMinus(src,meanAxis0(src));
57+
cv::multiply(temp_ ,temp_ ,temp_ );
58+
return meanAxis0(temp_);
59+
60+
}
61+
62+
63+
64+
int MatrixRank(cv::Mat M)
65+
{
66+
Mat w, u, vt;
67+
SVD::compute(M, w, u, vt);
68+
Mat1b nonZeroSingularValues = w > 0.0001;
69+
int rank = countNonZero(nonZeroSingularValues);
70+
return rank;
71+
72+
}
73+
74+
// References
75+
// ----------
76+
// .. [1] "Least-squares estimation of transformation parameters between two
77+
// point patterns", Shinji Umeyama, PAMI 1991, DOI: 10.1109/34.88573
78+
//
79+
// """
80+
//
81+
// Anthor:Jack Yu
82+
cv::Mat similarTransform(cv::Mat src,cv::Mat dst) {
83+
int num = src.rows;
84+
int dim = src.cols;
85+
cv::Mat src_mean = meanAxis0(src);
86+
cv::Mat dst_mean = meanAxis0(dst);
87+
cv::Mat src_demean = elementwiseMinus(src, src_mean);
88+
cv::Mat dst_demean = elementwiseMinus(dst, dst_mean);
89+
cv::Mat A = (dst_demean.t() * src_demean) / static_cast<float>(num);
90+
cv::Mat d(dim, 1, CV_32F);
91+
d.setTo(1.0f);
92+
if (cv::determinant(A) < 0) {
93+
d.at<float>(dim - 1, 0) = -1;
94+
95+
}
96+
Mat T = cv::Mat::eye(dim + 1, dim + 1, CV_32F);
97+
cv::Mat U, S, V;
98+
SVD::compute(A, S,U, V);
99+
100+
// the SVD function in opencv differ from scipy .
101+
102+
103+
int rank = MatrixRank(A);
104+
if (rank == 0) {
105+
assert(rank == 0);
106+
107+
} else if (rank == dim - 1) {
108+
if (cv::determinant(U) * cv::determinant(V) > 0) {
109+
T.rowRange(0, dim).colRange(0, dim) = U * V;
110+
} else {
111+
// s = d[dim - 1]
112+
// d[dim - 1] = -1
113+
// T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V))
114+
// d[dim - 1] = s
115+
int s = d.at<float>(dim - 1, 0) = -1;
116+
d.at<float>(dim - 1, 0) = -1;
117+
118+
T.rowRange(0, dim).colRange(0, dim) = U * V;
119+
cv::Mat diag_ = cv::Mat::diag(d);
120+
cv::Mat twp = diag_*V; //np.dot(np.diag(d), V.T)
121+
Mat B = Mat::zeros(3, 3, CV_8UC1);
122+
Mat C = B.diag(0);
123+
T.rowRange(0, dim).colRange(0, dim) = U* twp;
124+
d.at<float>(dim - 1, 0) = s;
125+
}
126+
}
127+
else{
128+
cv::Mat diag_ = cv::Mat::diag(d);
129+
cv::Mat twp = diag_*V.t(); //np.dot(np.diag(d), V.T)
130+
cv::Mat res = U* twp; // U
131+
T.rowRange(0, dim).colRange(0, dim) = -U.t()* twp;
132+
}
133+
cv::Mat var_ = varAxis0(src_demean);
134+
float val = cv::sum(var_).val[0];
135+
cv::Mat res;
136+
cv::multiply(d,S,res);
137+
float scale = 1.0/val*cv::sum(res).val[0];
138+
T.rowRange(0, dim).colRange(0, dim) = - T.rowRange(0, dim).colRange(0, dim).t();
139+
cv::Mat temp1 = T.rowRange(0, dim).colRange(0, dim); // T[:dim, :dim]
140+
cv::Mat temp2 = src_mean.t(); //src_mean.T
141+
cv::Mat temp3 = temp1*temp2; // np.dot(T[:dim, :dim], src_mean.T)
142+
cv::Mat temp4 = scale*temp3;
143+
T.rowRange(0, dim).colRange(dim, dim+1)= -(temp4 - dst_mean.t()) ;
144+
T.rowRange(0, dim).colRange(0, dim) *= scale;
145+
return T;
146+
}
147+
148+
149+
}
150+
#endif //FACE_DEMO_FACEPREPROCESS_H

0 commit comments

Comments
 (0)