3dmm计算特征向量,c++读写txt和二进制记录
生活随笔
收集整理的這篇文章主要介紹了
3dmm计算特征向量,c++读写txt和二进制记录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
頭文件 read.h
#ifndef READ_H_ #define READ_H_ class Read { public:Read();void cal();double** get_vec();double* get_val();double* get_M(); };#endifread.cpp
#include <iostream> #include <fstream> #include "Eigen/Dense" #include "read.h" using namespace std; using namespace Eigen; const int n = 11510 * 3, m = 150; double **vec, *val, *M;Read::Read() {}void Read::cal() {double tp;ifstream in("D:\\hx\\data\\result.dat", ios::in | ios::binary);vec = (double**)new double*[n];for (int i = 0; i < n; i++) {*(vec + i) = new double[m];for (int j = 0; j < m; j++) {in.read((char*)& tp, sizeof(tp));vec[i][j] = tp;}}val = new double[m];for (int i = 0; i < m; i++) {in.read((char*)& tp, sizeof(tp));val[i] = tp;}M = new double[n];for (int i = 0; i < n; i++) {in.read((char*)& tp, sizeof(tp));M[i] = tp;} }double** Read::get_vec() {return vec; }double* Read::get_val() {return val; }double* Read::get_M() {return M; }其他各個操作...
3dMM計算特征值特征向量存在二進制文件中,封裝上面這個read類用來訪問。read部分是測試讀取,test部分是測試特征向量有沒有設置對(隨便取幾組參數看看人臉形狀)。
#include<iostream> #include<algorithm> #include<cstdlib> #include<fstream> #include "Eigen/Dense" #include <ctime> #include <cstdio> #include "read.h" using namespace std; using namespace Eigen; const int n = 11510*3, m = 150; MatrixXd X(n, m), C(m, m); VectorXd M,A,B; MatrixXd vec, val; double** ans_vec; double *ans_val, *ans_M;string s = "D:\\hx\\data\\FaceWarehouse_Data_0\\Tester_"; void featurenormalize(MatrixXd &X, VectorXd &M) {//計算每一維度均值MatrixXd meanval = X.rowwise().mean();M = meanval; //VectorXd 就是列向量 RowVectorXd 是行向量//樣本均值化為0X.colwise() -= M; } void computeCov(MatrixXd &X, MatrixXd &C) {//計算協方差矩陣C = XTX / (m-1);C = X.adjoint() * X;C = C.array() / (m-1); } void computeEig(MatrixXd &C, MatrixXd &vec, MatrixXd &val) {//計算特征值和特征向量,使用selfadjont按照對稱矩陣的算法去計算,可以讓產生的vec和val按照有序排列SelfAdjointEigenSolver<MatrixXd> eig(C);vec = eig.eigenvectors();val = eig.eigenvalues(); }int main() {clock_t start, finish;start = clock();//讀取數據for (int i = 1; i <= m; i++) {stringstream ss;ss << i;string num = ss.str();string file = s + num + "\\Blendshape\\shape_0.obj";ifstream in(file);string a;double x,y,z;int k = 0;while (!in.eof()) {in >> a;if (a[0] == 'v' && a.length()==1) {in >> x;X(k++, i - 1) = x;in >> y;X(k++, i - 1) = y;in >> z;X(k++, i - 1) = z;}}}//零均值化featurenormalize(X, M);//計算協方差computeCov(X, C);//計算特征值和特征向量computeEig(C, vec, val);vec = X * vec;ofstream out("D:\\hx\\data\\result.dat", ios::out | ios::binary);for (int j = 0; j < n; j++) {for (int i = m-1; i >=0; i--) {out.write((char*)& vec(j,i), sizeof(double));}}for (int i = m-1; i>=0; i--) {out.write((char*)& val(i), sizeof(double));}for (int i = 0; i < n; i++) {out.write((char*)& M(i), sizeof(double));}cout << "finish" << endl;finish = clock();cout << "time:" << (double)(finish - start) / CLOCKS_PER_SEC << endl;//readRead r;r.cal();ans_val = r.get_val();for (int i = 0; i < m; i++) {cout << ans_val[i] << endl;}//teststring obj_M = "D:\\hx\\data\\meanS.obj";string obj_A = "D:\\hx\\data\\A.obj";string obj_B = "D:\\hx\\data\\B.obj";ofstream out_objM(obj_M);ofstream out_objA(obj_A);for (int i = 0; i < n; i += 3) {out_objM << "v " << M(i) << " " << M(i + 1) << " " << M(i + 2) << endl;}int change = m - 5;A = M;for (int i = 0; i < n; i ++) {for (int j = 1; j < change; j++) {A(i) += (0.1/148)*vec(i, j);}A(i) += 0.9*vec(i, change);for (int k = change+1; k < m; k++) {A(i) += (0.1 / 148)*vec(i, k);}}for (int i = 0; i < n; i += 3) {out_objA << "v " << A(i) << " " << A(i + 1) << " " << A(i + 2) << endl;}string get_face = "D:\\hx\\data\\1.txt";ifstream read(get_face);while (!read.eof()) {string tmp;read >> tmp;char flag = tmp[0];out_objA << tmp <<" ";read >> tmp;out_objA << tmp << " ";read >> tmp;out_objA << tmp << " ";if (flag == 'f') {read >> tmp;out_objA << tmp << " ";read >> tmp;out_objA << tmp << " ";}out_objA << endl;}int K = 1;while (K++) {cin >> change;stringstream ss;ss << K;string num = ss.str();string s = "D:\\hx\\data\\B"+num+".obj";ofstream out_objB(s);B = M;for (int i = 0; i < n; i++) {for (int j = 1; j < change; j++) {B(i) += (0.1 / 148)*vec(i, j);}B(i) += 0.9*vec(i, change);for (int k = change + 1; k < m; k++) {B(i) += (0.1 / 148)*vec(i, k);}}for (int i = 0; i < n; i += 3) {out_objB << "v " << B(i) << " " << B(i + 1) << " " << B(i + 2) << endl;}ifstream read1(get_face);while (!read1.eof()) {string tmp;read1 >> tmp;char flag = tmp[0];out_objB << tmp << " ";read1 >> tmp;out_objB << tmp << " ";read1 >> tmp;out_objB << tmp << " ";if (flag == 'f') {read1 >> tmp;out_objB << tmp << " ";read1 >> tmp;out_objB << tmp << " ";}out_objB << endl;}read1.close();read1.clear();out_objB.close();cout << "done" << endl;}return 0; }?
總結
以上是生活随笔為你收集整理的3dmm计算特征向量,c++读写txt和二进制记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IT信息业、金融业从业人员悲歌
- 下一篇: .net 2.0 制作 柱状图