private void flandmark_get_psi_mat_sparse(ref FlandmarkPSISparse Psi, ref FlandmarkModel model, int lbpidx) { //uint[] Features; byte[] Images = model.NormalizedImageFrame; uint im_H = (uint)model.Data.ImSize[0]; uint im_W = (uint)model.Data.ImSize[1]; uint[] Wins = model.Data.LBP[lbpidx].Wins; UInt16 win_H = (UInt16)model.Data.LBP[lbpidx].WinSize[0]; UInt16 win_W = (UInt16)model.Data.LBP[lbpidx].WinSize[1]; UInt16 nPyramids = model.Data.LBP[lbpidx].HOP; uint nDim = LibLBP.PyrGetDim(win_H, win_W, nPyramids) / 256; uint nData = model.Data.LBP[lbpidx].WinsCols; uint cnt0, mirror, x, x1, y, y1, idx; uint[] win; if (Psi.Idxs == null) // Psi.idxs.Length != nDim * nData) { Psi.Idxs = new uint[nDim * nData]; } win = new uint[win_H * win_W]; for (uint i = 0; i < nData; ++i) { idx = Wins[GetIndex(0, (int)i, 4)] - 1; x1 = Wins[GetIndex(1, (int)i, 4)] - 1; y1 = Wins[GetIndex(2, (int)i, 4)] - 1; mirror = Wins[GetIndex(3, (int)i, 4)]; int img_ptr = (int)(idx * im_H * im_W); cnt0 = 0; if (mirror == 0) { for (x = x1; x < x1 + win_W; x++) { for (y = y1; y < y1 + win_H; y++) { win[cnt0++] = Images[img_ptr + GetIndex((int)y, (int)x, (int)im_H)]; } } } else { for (x = x1 + win_W - 1; x >= x1; x--) { for (y = y1; y < y1 + win_H; y++) { win[cnt0++] = Images[img_ptr + GetIndex((int)y, (int)x, (int)im_H)]; } } } LibLBP.PyrFeaturesSparse(ref Psi.Idxs, nDim, win, win_H, win_W, nDim * i); } Psi.PsiCols = nData; Psi.PsiRows = nDim; //Psi.idxs = Features; }
private void flandmark_detect_base(byte[] face_image, FlandmarkModel model, double[] landmarks) { Profiler.Start("flandmark_detect_base"); int M = model.Data.Options.M; double[] W = model.W; int tsize = -1, cols = -1, rows = -1; int[] mapTable = model.Data.MapTable; if (model.NormalizedImageFrame == null) { model.NormalizedImageFrame = face_image; } if (Cached_Psi_sparse == null) { Cached_Psi_sparse = new FlandmarkPSISparse[M]; } Profiler.Start("flandmark_get_psi_mat_sparse"); Parallel.For(0, M, new ParallelOptions() { MaxDegreeOfParallelism = M }, (idx) => { if (Cached_Psi_sparse[idx] == null) { Cached_Psi_sparse[idx] = new FlandmarkPSISparse(); } flandmark_get_psi_mat_sparse(ref Cached_Psi_sparse[idx], ref model, idx); }); Profiler.End("flandmark_get_psi_mat_sparse"); //for (int idx = 0; idx < M; idx++) //{ // Psi_sparse[idx] = new FLANDMARK_PSI_SPARSE(); // flandmark_get_psi_mat_sparse(ref Psi_sparse[idx], ref model, idx); //} List <double[]> q = new List <double[]>(M); for (int i = 0; i < M; i++) { q.Add(null); } List <double[]> g = new List <double[]>(M - 1); for (int i = 0; i < M - 1; i++) { g.Add(null); } int idx_qtemp = 0; for (int idx = 0; idx < M; ++idx) { tsize = mapTable[GetIndex(idx, 1, M)] - mapTable[GetIndex(idx, 0, M)] + 1; if (q_temp == null) { q_temp = new double[tsize]; } else { if (q_temp.Length < tsize) { q_temp = new double[tsize]; } } Array.Copy(W, mapTable[GetIndex(idx, 0, M)] - 1, q_temp, 0, tsize); // sparse dot product <W_q, PSI_q> cols = (int)Cached_Psi_sparse[idx].PsiCols; rows = (int)Cached_Psi_sparse[idx].PsiRows; uint[] psi_temp = Cached_Psi_sparse[idx].Idxs; //q[idx] = new double[cols]; double[] qind = new double[cols]; for (int i = 0; i < cols; ++i) { double dotprod = 0.0f; for (int j = 0; j < rows; ++j) { idx_qtemp = (int)psi_temp[(rows * i) + j]; dotprod += q_temp[idx_qtemp]; } qind[i] = dotprod; } q[idx] = qind; if (idx > 0) { tsize = mapTable[GetIndex(idx, 3, M)] - mapTable[GetIndex(idx, 2, M)] + 1; g[idx - 1] = new double[tsize]; Array.Copy(W, mapTable[GetIndex(idx, 2, M)] - 1, g[idx - 1], 0, tsize); } } Profiler.Start("flandmark_argmax"); flandmark_argmax(landmarks, ref model.Data.Options, mapTable, Cached_Psi_sparse, q, g); Profiler.End("flandmark_argmax"); g.Clear(); q.Clear(); Profiler.End("flandmark_detect_base"); }