我试图在C ++中实现特征脸算法。我已经创建了数据库创建部分,现在我正在设置识别部分。
唯一的问题是,即使从文件"prova.txt"
中正确读取了所有变量,一旦将它们传递给函数,就会发生奇怪的事情:整个imd
数组包含的值与预期的(我在Matlab中运行相同的算法以供参考)。
我是python程序员,所以我知道这对C ++用户来说可能是愚蠢的,但是我的代码中找不到错误(可能没有很好地优化并且充满了冗余btw )。我在代码后发布了"prova.txt"
的链接。
U
和omega
是矩阵,我将其线性化,以便能够将它们作为函数的输入参数传递。
#include <iostream>
#include <cmath>
#include <fstream.h>
#include <cstdlib>
using namespace std;
int confrontodb(double*, double, double, double*, double*, double*);
int confrontodb(double* test, double H, double M, double* m, double* U,
double* omega) {
int Urows = M;
int Ulines = H;
double om[Urows];
double imd[Ulines];
double d[Urows][Urows];
double dist[Urows];
double accum;
double minimo;
int ind = 0;
// subtract average "med" from test sample "test"
for (int i = 0; i < Ulines; i++) {
imd[i] = test[i] - m[i];
}
// Project "imd" on the U eigenspace (om = U'*imd)
for (int i = 0; i < Urows; i++) {
for (int j = 0; j < Ulines; j++) {
om[i] += U[Urows * j + i] * imd[j];
};
};
// Generate a matrix in which each column is a copy of om
for (int i = 0; i < Urows; i++) {
for (int j = 0; j < Urows; j++) {
d[i][j] = om[i];
};
};
// subtract omega from d
for (int i = 0; i < Urows; i++) {
for (int j = 0; j < Urows; j++) {
d[i][j] = d[i][j] - omega[i * Urows + j];
};
};
// norm each column of d
for (int i = 0; i < Urows; i++) {
accum = 0;
for (int j = 0; j < Urows; j++) {
accum += d[i][j] * d[i][j];
};
dist[i] = sqrt(accum);
};
// look for minimum and maximum distance
minimo = dist[0];
double massimo = dist[0];
for (int i = 0; i < Urows; i++) {
if (dist[i] < minimo) {
ind = i;
minimo = dist[i];
} else if (dist[i] > massimo) {
massimo = dist[i];
};
};
cout << "minimo " << minimo << endl;
cout << "massimo " << massimo << endl;
return ind;
}
int main(int argc, char* argv[]) {
ifstream f;
f.open("prova.txt");
double* omega;
omega = (double*)calloc(198 * 198, sizeof(double));
for (int i = 0; i < 198 * 198; i++) {
f >> omega[i];
};
for (int i = 0; i < 198; i++) {
for (int j = 0; j < 198; j++) {
cout << " " << omega[i * 198 + j];
}
cout << endl;
}
double* U;
U = (double*)calloc(4001 * 198, sizeof(double));
// float U[4001*198];
for (int i = 0; i < 4001 * 198; i++) {
f >> U[i];
};
double* med;
med = (double*)calloc(4001, sizeof(double));
for (int i = 0; i < 4001; i++) {
f >> med[i];
};
double* test;
test = (double*)calloc(4001, sizeof(double));
for (int i = 0; i < 4001; i++) {
f >> test[i];
};
f.close();
cout << "etichetta riconosciuta "
<< confrontodb(test, 4001, 198, med, U, omega) << endl;
free(med);
free(test);
free(U);
free(omega);
return 0;
}
Link to "prova.txt"
(it's 13 megabytes)
预期结果:
imdmatlab =
-2.5252525e-01
-1.3080808e+00
-1.8080808e+00
-2.7676768e+00
-4.1161616e+00
-3.1969697e+00
-2.5707071e+00
-2.6616162e+00
-3.1616162e+00
-2.3181818e+00
-2.1767677e+00
[...]
使用实际代码,第一个imd
元素是正确的,第二个有1/1000错误然后一切都是随机的,所以这些元素应该足以检查。