phash
この記事のリファレンス実装は次のとおりです。https://blog.csdn.net/sunhuaqiang1/article/details/70232679
元のコードには4つのforループがあります。
private double[][] applyDCT(double[][] f) {
int N = size;
double[][] F = new double[N][N];
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
double sum = 0.0;
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
sum+=Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*(f[i][j]);
}
}
sum*=((c[u]*c[v])/4.0);
F[u][v] = sum;
}
}
return F;
}
この記事では、CPUを使用して行列乗算の最適化を高速化するなど、いくつかの改善を行いました。コードは次のとおりです。効果は約20%増加します。
private SimpleMatrix getMatrixA(int NN){
//获取备用矩阵 A
SimpleMatrix a_array = new SimpleMatrix(NN, NN);
for(int i = 0; i< NN; i++){
for(int j = 0; j < NN; j++){
a_array.set(i,j,Math.cos(((2*j+1)/(2.0*NN))*i*Math.PI));
}
}
return a_array;
}
private double[][] applyDCT_1(double[][] f) {
int N = size;
SimpleMatrix f_array = new SimpleMatrix(f);
SimpleMatrix a_array = getMatrixA(N);
SimpleMatrix a_array_T = a_array.transpose();
double[][] F = new double[N][N];
for (int u=0;u<N;u++) {
for (int v = 0; v < N; v++) {
SimpleMatrix a_row_u = a_array.rows(u,u+1);
SimpleMatrix a_col_v = a_array_T.cols(v,v+1);
SimpleMatrix mult_res = a_col_v.mult(a_row_u);
double sum = mult_res.elementMult(f_array).elementSum();
sum*=((c[u]*c[v])/4.0);
F[v][u] = sum;//转置关系
}
}
return F;
}