Esempio n. 1
0
        private void flandmark_detect(ref Mat img, int[] bbox, ref FlandmarkModel model, out double[] landmarks, int[] bw_margin = null)
        {
            landmarks = new double[model.Data.Options.M * 2];

            if (bw_margin != null)
            {
                model.Data.Options.bw_margin[0] = bw_margin[0];
                model.Data.Options.bw_margin[1] = bw_margin[1];
            }

            if (!flandmark_get_normalized_image_frame(ref img, bbox, ref model.bb, ref model.NormalizedImageFrame, ref model))
            {
                landmarks = null;
                return;
            }

            flandmark_detect_base(model.NormalizedImageFrame, model, landmarks);

            model.sf[0] = (float)(model.bb[2] - model.bb[0]) / model.Data.Options.bw[0];
            model.sf[1] = (float)(model.bb[3] - model.bb[1]) / model.Data.Options.bw[1];

            for (int i = 0; i < 2 * model.Data.Options.M; i += 2)
            {
                landmarks[i]     = landmarks[i] * model.sf[0] + model.bb[0];
                landmarks[i + 1] = landmarks[i + 1] * model.sf[1] + model.bb[1];
            }
        }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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");
        }
Esempio n. 4
0
        private bool flandmark_get_normalized_image_frame(ref Mat input, int[] bbox, ref double[] bb, ref byte[] face_img, ref FlandmarkModel model)
        {
            bool flag;

            int[]    d = new int[2];
            double[] c = new double[2], nd = new double[2];

            // extend bbox by bw_margin
            d[0]  = bbox[2] - bbox[0] + 1; d[1] = bbox[3] - bbox[1] + 1;
            c[0]  = (bbox[2] + bbox[0]) / 2.0f; c[1] = (bbox[3] + bbox[1]) / 2.0f;
            nd[0] = d[0] * model.Data.Options.bw_margin[0] / 100.0f + d[0];
            nd[1] = d[1] * model.Data.Options.bw_margin[1] / 100.0f + d[1];

            bb[0] = (c[0] - nd[0] / 2.0f);
            bb[1] = (c[1] - nd[1] / 2.0f);
            bb[2] = (c[0] + nd[0] / 2.0f);
            bb[3] = (c[1] + nd[1] / 2.0f);

            //flag = bb[0] > 0 && bb[1] > 0 && bb[2] < input.Width && bb[3] < input.Height
            //    && bbox[0] > 0 && bbox[1] > 0 && bbox[2] < input.Width && bbox[3] < input.Height;
            //if (!flag)
            //    return false;

            Rect region = new Rect((int)bb[0], (int)bb[1], (int)bb[2] - (int)bb[0] + 1, (int)bb[3] - (int)bb[1] + 1);

            flag = input.Width <= 0 || input.Height <= 0 || region.Width <= 0 || region.Height <= 0;
            if (flag)
            {
                return(false);
            }

            Rect clipRegion = new Rect(
                Util.Clamp(region.X, 0, input.Width - 1), Util.Clamp(region.Y, 0, input.Height - 1),
                Util.Clamp(region.Width, 0, input.Width), Util.Clamp(region.Height, 0, input.Height));

            using (var resizedImage = new Mat(input, clipRegion.ToCvRect()))
            {
                double scalefactor = model.Data.Options.bw[0] / region.Width;
                //resizedImage.Resize(new Size(model.Data.Options.bw[0], model.Data.Options.bw[1]), 0, 0, Inter);
                resizedImage.Resize(new Size(clipRegion.Width * scalefactor, clipRegion.Height * scalefactor), 0, 0, Inter);
                resizedImage.EqualizeHistogram();

                // TODO: parallized
                int    step = model.Data.Options.bw[1];
                byte[] face_img_tmp = face_img;
                double regX = region.X, regY = region.Y, inpW = input.Width, inpH = input.Height;
                Parallel.For(0, model.Data.Options.bw[0] * model.Data.Options.bw[1], new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, (ind) =>
                {
                    int x       = ind / step;
                    int y       = ind % step;
                    double preX = x / scalefactor + regX;
                    double preY = y / scalefactor + regY;
                    byte value;
                    // TODO: padding
                    if (preX < 0 || preX >= inpW || preY < 0 || preY >= inpH)
                    {
                        value = 1;
                    }
                    else
                    {
                        int newY = (int)((Util.Clamp(preY, 0, inpH) - clipRegion.Y) * scalefactor);
                        int newX = (int)((Util.Clamp(preX, 0, inpW) - clipRegion.X) * scalefactor);
                        value    = resizedImage.At <byte>(newY, newX);
                    }
                    face_img_tmp[x * step + y] = value;
                });
                face_img = face_img_tmp;
                //for (int x = 0; x < model.Data.Options.bw[0]; ++x)
                //{
                //    for (int y = 0; y < model.Data.Options.bw[1]; ++y)
                //    {
                //        face_img[GetIndex(y, x, model.Data.Options.bw[1])] = resizedImage.At<byte>(y, x);
                //    }
                //}
            }

            return(true);
        }
Esempio n. 5
0
        public Flandmark(FileNode filename)
        {
            int[] p_int;
            int   tsize = -1, tmp_tsize = -1;

            Stream       fin    = filename.Open();
            StreamReader reader = new StreamReader(fin);

            FlandmarkModel tst = new FlandmarkModel();

            fin.Position = 0;

            ReadUntilSpace(reader);
            tst.Data.Options.M = (byte)ReadUntilSpace(reader)[0];

            ReadUntilSpace(reader);
            tst.Data.Options.bw[0] = Convert.ToInt32(ReadUntilSpace(reader));
            tst.Data.Options.bw[1] = Convert.ToInt32(ReadUntilSpace(reader));

            ReadUntilSpace(reader);
            tst.Data.Options.bw_margin[0] = Convert.ToInt32(ReadUntilSpace(reader));
            tst.Data.Options.bw_margin[1] = Convert.ToInt32(ReadUntilSpace(reader));

            ReadUntilSpace(reader);
            tst.WRows = Convert.ToInt32(ReadUntilSpace(reader));
            tst.WCols = Convert.ToInt32(ReadUntilSpace(reader));

            ReadUntilSpace(reader);
            tst.Data.ImSize[0] = Convert.ToInt32(ReadUntilSpace(reader));
            tst.Data.ImSize[1] = Convert.ToInt32(ReadUntilSpace(reader));

            int M = tst.Data.Options.M;

            tst.Data.LBP = new FlandmarkLBP[M];

            for (int i = 0; i < M; i++)
            {
                ReadUntilSpace(reader);

                var lbp = new FlandmarkLBP();

                lbp.WinsRows = (uint)Convert.ToInt32(ReadUntilSpace(reader));
                lbp.WinsCols = (uint)Convert.ToInt32(ReadUntilSpace(reader));

                tst.Data.LBP[i] = lbp;
            }

            for (int i = 0; i < 3; i++)
            {
                ReadUntilSpace(reader);
                tst.Data.Options.PsiGRows[i] = Convert.ToInt32(ReadUntilSpace(reader));
                tst.Data.Options.PsiGCols[i] = Convert.ToInt32(ReadUntilSpace(reader));
            }

            fin.Dispose();
            reader.Dispose();

            fin = filename.Open();
            //TODO: fix position
            fin.Position = 111;
            BinaryReader breader = new BinaryReader(fin);

            // load model.W
            tst.W = new double[tst.WRows];

            for (int i = 0; i < tst.WRows; i++)
            {
                tst.W[i] = breader.ReadDouble();
            }

            // load model.data.mapTable
            p_int             = new int[M * 4];
            tst.Data.MapTable = new int[M * 4];

            for (int i = 0; i < M * 4; i++)
            {
                p_int[i] = breader.ReadInt32();
            }

            for (int i = 0; i < M * 4; i++)
            {
                tst.Data.MapTable[i] = p_int[i];
            }
            p_int = null;

            // load model.data.lbp
            for (int i = 0; i < M; i++)
            {
                // lbp{idx}.winSize
                p_int = new int[2];

                p_int[0] = breader.ReadInt32();
                p_int[1] = breader.ReadInt32();

                tst.Data.LBP[i].WinSize[0] = p_int[0];
                tst.Data.LBP[i].WinSize[1] = p_int[1];

                p_int = null;

                // lbp{idx}.hop
                tst.Data.LBP[i].HOP = breader.ReadByte();

                // lbp{idx}.wins
                tsize = (int)(tst.Data.LBP[i].WinsRows * tst.Data.LBP[i].WinsCols);

                tst.Data.LBP[i].Wins = new uint[tsize];
                for (int r = 0; r < tsize; r++)
                {
                    tst.Data.LBP[i].Wins[r] = breader.ReadUInt32();
                }
            }

            // load model.options.S
            tst.Data.Options.S = new int[4 * M];

            for (int i = 0; i < 4 * M; i++)
            {
                tst.Data.Options.S[i] = breader.ReadInt32();
            }
            p_int = null;

            // load model.options.PsiG
            FlandmarkPsiG[] PsiGi = null;

            for (int psigs_ind = 0; psigs_ind < 3; psigs_ind++)
            {
                tsize = tst.Data.Options.PsiGRows[psigs_ind] * tst.Data.Options.PsiGCols[psigs_ind];

                switch (psigs_ind)
                {
                case 0:
                    tst.Data.Options.PsiGS0 = new FlandmarkPsiG[tsize];
                    PsiGi = tst.Data.Options.PsiGS0;
                    break;

                case 1:
                    tst.Data.Options.PsiGS1 = new FlandmarkPsiG[tsize];
                    PsiGi = tst.Data.Options.PsiGS1;
                    break;

                case 2:
                    tst.Data.Options.PsiGS2 = new FlandmarkPsiG[tsize];
                    PsiGi = tst.Data.Options.PsiGS2;
                    break;
                }

                int temp = 0;
                for (int i = 0; i < tsize; i++)
                {
                    PsiGi[i] = new FlandmarkPsiG();

                    // disp ROWS
                    temp = breader.ReadInt32();

                    PsiGi[i].Rows = temp;

                    // disp COLS
                    temp = breader.ReadInt32();

                    PsiGi[i].Cols = temp;

                    // disp
                    tmp_tsize = PsiGi[i].Rows * PsiGi[i].Cols;

                    PsiGi[i].Disp = new int[tmp_tsize];

                    for (int r = 0; r < tmp_tsize; r++)
                    {
                        PsiGi[i].Disp[r] = breader.ReadInt32();
                    }
                }
            }

            fin.Dispose();
            breader.Dispose();

            tst.NormalizedImageFrame = new byte[tst.Data.Options.bw[0] * tst.Data.Options.bw[1]];
            tst.bb = new double[4];
            tst.sf = new float[2];

            Model = tst;
        }