// ************************************************************************************************* // @fn Recognizer // @brief // @return // ************************************************************************************************* public static double Recognizer(SVSystem Template, SVSystem Tester) { double Score = 0; double[] D = new double[FeatureNum]; //-- Feature std double X_std_T = CalculateFeatureStd(Template.Feature_X); double Y_std_T = CalculateFeatureStd(Template.Feature_Y); double P_std_T = CalculateFeatureStd(Template.Feature_P); double Vx_std_T = CalculateFeatureStd(Template.Feature_Vx); double Vy_std_T = CalculateFeatureStd(Template.Feature_Vy); double Ax_std_T = CalculateFeatureStd(Template.Feature_Ax); double Ay_std_T = CalculateFeatureStd(Template.Feature_Ay); double A_std_T = CalculateFeatureStd(Template.Feature_A); double R_std_T = CalculateFeatureStd(Template.Feature_R); //-- 辨識器 D[0] = ELCSS(Template.Feature_X, Tester.Feature_X, Math.Abs(X_std_T) * 0.65, 5); D[1] = ELCSS(Template.Feature_Y, Tester.Feature_Y, Math.Abs(Y_std_T) * 0.5, 5); D[2] = ELCSS(Template.Feature_P, Tester.Feature_P, Math.Abs(P_std_T) * 0.9, 5); D[3] = ELCSS(Template.Feature_Vx, Tester.Feature_Vx, Math.Abs(Vx_std_T) * 0.55, 5); D[4] = ELCSS(Template.Feature_Vy, Tester.Feature_Vy, Math.Abs(Vy_std_T) * 0.65, 5); // 0.4 D[5] = ELCSS(Template.Feature_Ax, Tester.Feature_Ax, Math.Abs(Ax_std_T) * 0.95, 5); // 0.9 D[6] = ELCSS(Template.Feature_Ay, Tester.Feature_Ay, Math.Abs(Ay_std_T) * 0.6, 5); // 0.5 D[7] = ELCSS(Template.Feature_A, Tester.Feature_A, Math.Abs(A_std_T) * 0.65, 5); Similarity = D; Score = D.Sum() * FeatureNum * 100 / Math.Pow(SVSystem.FeatureNum, 2);; return(Score); }
// ************************************************************************************************* // @fn SignatureTemplateSelection // @brief // @return // ************************************************************************************************* public static double[] SignatureTemplateSelection(SVSystem[] Database, ref SVSystem TemplateData, ref List <int> BadSig) { //-- 安全分數設定 - 隨機仿冒者分數落在60-70分居多 //int SerurityScore_Norm = 80; int SerurityScore_Min = 70; //-- Each person entroll fixed signatures to choose template int Entrollment = Database.Length; //-- BestTemplate double[] BestTemplate = new double[10 + 2 * Entrollment]; //-- Training data int TrainData_startPos = 0; //-- Record all signature inner score double[,] Score_All = new double[Entrollment, Entrollment - 1]; //-- Final score to select which best double[] TemplateScore = new double[Entrollment]; double[] TemplateScoreMean = new double[Entrollment]; double[] TemplateScoreStd = new double[Entrollment]; for (int i = TrainData_startPos; i < (TrainData_startPos + Entrollment); i++) { int cnt = 0; for (int j = TrainData_startPos; j < (TrainData_startPos + Entrollment); j++) { if (i == j) { continue; } double Score_t = 0; double[] D = new double[FeatureNum]; Score_t = Recognizer(Database[i], Database[j]); Score_All[i, cnt++] = Score_t; } } for (int i = TrainData_startPos; i < (TrainData_startPos + Entrollment); i++) { //-- 取平均值 double mean = 0; for (int j = 0; j < (Entrollment - 1); j++) { mean += Score_All[i, j]; } mean = mean / (Entrollment - 1); //-- 計算平方和 double sum = 0; for (int k = 0; k < (Entrollment - 1); k++) { sum += Math.Pow(Score_All[i, k] - mean, 2); } //-- 計算標準差 double std = 0; std = Math.Sqrt(sum / (Entrollment - 2)); TemplateScore[i] = mean - std; TemplateScoreMean[i] = mean; TemplateScoreStd[i] = std; BestTemplate[2 * i + 10] = mean; BestTemplate[2 * i + 1 + 10] = std; } //-- 選擇最大樣板分數,與最大標準差 double ScoreMax = 0, StdMax = 0; ScoreMax = TemplateScore.Max(); StdMax = TemplateScoreStd.Max(); for (int i = 0; i < Entrollment; i++) { if (TemplateScore[i] == ScoreMax) { BestTemplate[0] = i + 1; BestTemplate[1] = ScoreMax; BestTemplate[2] = TemplateScoreMean[i]; BestTemplate[3] = TemplateScoreStd[i]; BestTemplate[4] = TemplateScoreMean[i] + 2 * TemplateScoreStd[i]; BestTemplate[5] = TemplateScoreMean[i] - 2 * TemplateScoreStd[i]; //BestTemplate[4] = TemplateScoreMean[i] + StdMax; //BestTemplate[5] = TemplateScoreMean[i] - StdMax; BestTemplate[6] = Database[i].CostTime; break; } } //-- 將相似度分數轉換至0-100分範圍 for (int i = 1; i < BestTemplate.Length; i++) { //-- 書寫時間跳過 if (i == 6) { continue; } BestTemplate[i] = BestTemplate[i] * 100 / Math.Pow(SVSystem.FeatureNum, 2); //-- 小於 最低安全分數者 分當作絕對仿冒者 or 不好的簽名 if (BestTemplate[i] < SerurityScore_Min && i >= 10 && (i % 2 == 0)) { BestTemplate[i] = 0; BestTemplate[i + 1] = 0; } //else if (BestTemplate[i] > SerurityScore_Min && BestTemplate[i] < SerurityScore_Norm && i >= 10 && (i % 2 == 0)) //{ // BestTemplate[i] = ((BestTemplate[i] - SerurityScore_Min) / (SerurityScore_Norm - SerurityScore_Min)) * (SerurityScore_Norm - 50) + 50; //} } double Upper = 0; double lower = 0; double Mean = 0; double Std = 0; Mean = BestTemplate[2]; Std = BestTemplate[3]; Upper = Mean + Std; lower = Mean - Std; //-- 樣板標準判斷 if (Std >= 3.5) { bool BigBadSig_flag = false; for (int i = 0; i < Entrollment; i++) { if (i == (BestTemplate[0] - 1)) { continue; } if (Math.Abs(BestTemplate[2 * i + 10] - Mean) > 5) { BadSig.Add(i + 1); BigBadSig_flag = true; } } if (BigBadSig_flag == false) { for (int i = 0; i < Entrollment; i++) { if (i == (BestTemplate[0] - 1)) { continue; } //-- 設定標準差小於閥值建議重新簽名 if (Math.Abs(BestTemplate[2 * i + 1 + 10]) > 5) { BadSig.Add(i + 1); } //-- 設定小於最佳樣版的最低分數者且該標準差大於閥值,建議重新簽名 //if ((BestTemplate[2 * i + 10] - BestTemplate[2 * i + 1 + 10]) < lower && BestTemplate[2 * i + 1 + 10] >= 3) //{ // BadSig.Add(i + 1); //} } } } //-- 取得最新樣板並回傳 TemplateData = Database[(int)BestTemplate[0] - 1]; return(BestTemplate); }