Example #1
0
        public static bool LoadImageSource(Image img, string filename, bool bResize, int maxsize = 700)
        {
            try
            {
                using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    using (var bm = System.Drawing.Bitmap.FromStream(file))
                    {
                        // ((System.Drawing.Bitmap)bm).SetResolution(96, 96);
                        if (((bm.Width > maxsize) || (bm.Height > maxsize)) && bResize)
                        {
                            //resize the image
                            double ratio              = (double)bm.Width / bm.Height;
                            int    newwidth           = ratio > 1 ? maxsize : (int)(maxsize * ratio);
                            int    newheight          = (int)(newwidth / ratio);
                            System.Drawing.Bitmap bm2 = new System.Drawing.Bitmap(newwidth, newheight, System.Drawing.Imaging.PixelFormat.Format32bppArgb /*bm.PixelFormat*/);

                            System.Drawing.Graphics  gbm2     = System.Drawing.Graphics.FromImage(bm2);
                            System.Drawing.Rectangle srcRect  = new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height);
                            System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(0, 0, bm2.Width, bm2.Height);
                            gbm2.DrawImage(bm, destRect, srcRect, System.Drawing.GraphicsUnit.Pixel);
                            gbm2.Dispose();
                            img.Source = CCommon.Bitmap2BitmapImage((System.Drawing.Bitmap)bm2);
                            bm2.Dispose();
                            bm2 = null;
                        }
                        else
                        {
                            img.Source = CCommon.Bitmap2BitmapImage((System.Drawing.Bitmap)bm);
                            bm.Dispose();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return(false);
            }

            return(true);
        }
Example #2
0
        private void RenderMesh()
        {
            if (_TextureCoordinates == null)
            {
                return;
            }

            double minx = 1.0, maxx = 0, miny = 1, maxy = 0;

            for (int i = 0; i < _TextureCoordinates.Count; i++)
            {
                if (_TextureCoordinates[i].X < minx)
                {
                    minx = _TextureCoordinates[i].X;
                }
                if (_TextureCoordinates[i].Y < miny)
                {
                    miny = _TextureCoordinates[i].Y;
                }
                if (_TextureCoordinates[i].X > maxx)
                {
                    maxx = _TextureCoordinates[i].X;
                }
                if (_TextureCoordinates[i].Y > maxy)
                {
                    maxy = _TextureCoordinates[i].Y;
                }
            }

            //2. normalize
            int width  = (int)((maxx - minx) * 1920) + 1;
            int height = (int)((maxy - miny) * 1080) + 1;
            List <System.Drawing.PointF> meshpoints = new List <System.Drawing.PointF>();

            for (int i = 0; i < _TextureCoordinates.Count; i++)
            {
                meshpoints.Add(new System.Drawing.PointF((float)(_TextureCoordinates[i].X - minx) * 1920,
                                                         (float)(_TextureCoordinates[i].Y - miny) * 1080)
                               );
            }

            ////The bitmap must have ARGB Pixel format to support transparency
            System.Drawing.Bitmap bm = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            ///////////////////////////////////////////////////////

            System.Drawing.Graphics gbm = System.Drawing.Graphics.FromImage(bm);
            gbm.Clear(System.Drawing.Color.Transparent);


            //Draw the points
            System.Drawing.Brush brush;
            for (int i = 0; i < _TextureCoordinates.Count; i++)
            {
                FacePointMapping mapping = _Mappings.Find(p => p.index == i);
                brush = (mapping.side == "R") ? System.Drawing.Brushes.Red : System.Drawing.Brushes.Blue;
                if (mapping.side == "C")
                {
                    brush = System.Drawing.Brushes.Cyan;
                }

                gbm.FillRectangle(brush, new System.Drawing.RectangleF(
                                      meshpoints[i].X,
                                      meshpoints[i].Y,
                                      3, 3));
            }



            if ((bool)chkMesh.IsChecked)
            {
                for (int i = 0; i < _TriangleIndices.Count; i = i + 3)
                {
                    System.Drawing.Pen pen  = new System.Drawing.Pen(_MeshColor);
                    System.Drawing.Pen pen2 = new System.Drawing.Pen(System.Drawing.Color.FromArgb(255, System.Drawing.Color.YellowGreen));

                    //Use different pen for these triangles connected to these points
                    //10 (center of base of upper lip)
                    if (_TriangleIndices[i] == 10 || _TriangleIndices[i + 1] == 10 || _TriangleIndices[i + 2] == 10)
                    {
                        pen = pen2;
                    }

                    //14 (nose tip)
                    if (_TriangleIndices[i] == 14 || _TriangleIndices[i + 1] == 14 || _TriangleIndices[i + 2] == 14)
                    {
                        pen = pen2;
                    }
                    //0 (chin)
                    if (_TriangleIndices[i] == 0 || _TriangleIndices[i + 1] == 0 || _TriangleIndices[i + 2] == 0)
                    {
                        pen = pen2;
                    }
                    //328-1105 (right eye is between this 2 points)
                    if (_TriangleIndices[i] == 1105 || _TriangleIndices[i + 1] == 1105 || _TriangleIndices[i + 2] == 1105)
                    {
                        pen = pen2;
                    }
                    //883-1092 (left eye is between these 2 points)
                    if (_TriangleIndices[i] == 1092 || _TriangleIndices[i + 1] == 1092 || _TriangleIndices[i + 2] == 1092)
                    {
                        pen = pen2;
                    }

                    if (CCommon.ArePointsClockwise(
                            meshpoints[_TriangleIndices[i]],
                            meshpoints[_TriangleIndices[i + 1]],
                            meshpoints[_TriangleIndices[i + 2]])
                        )
                    {
                        gbm.DrawPolygon(pen, new System.Drawing.PointF[]
                        {
                            meshpoints[_TriangleIndices[i]],
                            meshpoints[_TriangleIndices[i + 1]],
                            meshpoints[_TriangleIndices[i + 2]]
                        }
                                        );
                    }
                }
            }
            gbm.Dispose();

            Image1.Source = CCommon.Bitmap2BitmapImage(bm);
            bm.Dispose();
            bm = null;
        }
Example #3
0
        //Loading of facial points markers
        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            for (int i = Canvas1.Children.Count - 1; i >= 0; i--)
            {
                if (Canvas1.Children[i].GetType() == typeof(System.Windows.Shapes.Ellipse))
                {
                    Canvas1.Children.Remove(Canvas1.Children[i]);
                }
            }

            var fps = ((MainWindow)this.Owner).ImageFacePoints;

            double imagewidth  = ((BitmapImage)(Image1.Source)).PixelWidth;
            double imageheight = ((BitmapImage)(Image1.Source)).PixelHeight;

            this.UpdateLayout();
            double wpfimagewidth  = Image1.ActualWidth;
            double wpfimageheight = Image1.ActualHeight;
            double ratio          = imageheight / wpfimageheight;

            for (int i = 0; i < _numfacepoints; i++)
            {
                System.Windows.Shapes.Ellipse ep = new System.Windows.Shapes.Ellipse();
                ep.Name            = "EP" + i;
                ep.Width           = 30;
                ep.Height          = 30;
                ep.StrokeThickness = 2;
                ep.Stroke          = System.Windows.Media.Brushes.Red;

                ep.Fill = new SolidColorBrush(Color.FromArgb(10, 255, 255, 255));
                ep.HorizontalAlignment = HorizontalAlignment.Left;
                ep.VerticalAlignment   = VerticalAlignment.Top;
                ep.Uid = ep.Name;
                Canvas1.Children.Add(ep);

                Canvas.SetTop(ep, Canvas.GetTop(Grid1) + i * ep.Height + Image1.ActualHeight / 2);
                Canvas.SetLeft(ep, Canvas.GetLeft(Grid1) + 50);//(Image1.ActualWidth + ep.Width) / 2);

                ep.Focusable  = true;
                ep.MouseDown += ep_MouseDown;
                ep.MouseMove += ep_MouseMove;
                ep.KeyDown   += ep_KeyDown;
            }



            try
            {
                System.Drawing.Rectangle   facerect = System.Drawing.Rectangle.Empty;
                System.Drawing.Rectangle[] eyesrect = null;

                string strfaceindex    = "";
                bool   bFromCacheRects = false;
                if (sender != null && sender.GetType() == winSelectFace.GetType())     //Load face from cache
                {
                    bFromCacheRects = true;
                }
                else
                {
                    strfaceindex = CCommon.FindFaceAndEyes(Image1.Source.Clone() as BitmapImage, out facerect, out eyesrect);
                }

                //for implementation of multiple faces image
                //c is for cache
                if (strfaceindex == "c" || bFromCacheRects)
                {
                    if (strfaceindex == "c")
                    {
                        if (winSelectFace != null)
                        {
                            winSelectFace = null;
                        }

                        // if (winSelectFace == null)
                        winSelectFace = new Window4();

                        winSelectFace.Title         = "Double click to select a face";
                        winSelectFace.Image1.Source = Image1.Source.Clone();
                        winSelectFace.FaceRects     = CCommon.cacheRects.ToArray();
                        winSelectFace.Owner         = this;
                        winSelectFace.Show();
                    }

                    try
                    {
                        //wait for face to be selected
                        while (!winSelectFace.IsFaceSelected)
                        {
                            System.Windows.Forms.Application.DoEvents();
                        }
                    }
                    catch     //fires if winSelectFace is closed without making a selection
                    {
                        return;
                    }

                    //get the index of the face from winSelectFace
                    strfaceindex = "" + winSelectFace.FaceSelectedIndex;
                    facerect     = CCommon.cacheRects.ElementAt(winSelectFace.FaceSelectedIndex);
                    CCommon.FindEyesFromCache(winSelectFace.FaceSelectedIndex, out eyesrect);
                }
                else     //for single face image, we close winSelectFace
                {
                    if (winSelectFace != null)
                    {
                        winSelectFace.Close();
                        winSelectFace = null;
                    }
                }

                //store the index of face selected
                //note that for single face image, this is ""
                FaceIndexString = strfaceindex;
                /////////////////////////
                //Crop Image1.Source based on facerect
                if (facerect != System.Drawing.Rectangle.Empty)
                {
                    //Rescaling

                    if (bFromCacheRects)
                    {
                        //load default unscaled
                        Image1.Source = CCommon.Bitmap2BitmapImage(CCommon.cacheBm);
                    }

                    //scale and reload if image is too large
                    if (facerect.Height > 500)
                    {
                        double rescale = 500.0 / facerect.Height;
                        int    newsize = ((BitmapImage)Image1.Source).PixelWidth > ((BitmapImage)Image1.Source).PixelHeight ?
                                         (int)(rescale * ((BitmapImage)Image1.Source).PixelWidth) :
                                         (int)(rescale * ((BitmapImage)Image1.Source).PixelHeight);

                        CCommon.LoadImageSource(Image1, CurrentFile, true, newsize);
                        //rescale face
                        facerect = new System.Drawing.Rectangle((int)(facerect.X * rescale),
                                                                (int)(facerect.Y * rescale),
                                                                (int)(facerect.Width * rescale),
                                                                (int)(facerect.Height * rescale));
                        //rescale all the eyepoints
                        for (int i = 0; i < eyesrect.Length; i++)
                        {
                            eyesrect[i] = new System.Drawing.Rectangle((int)(eyesrect[i].X * rescale),
                                                                       (int)(eyesrect[i].Y * rescale),
                                                                       (int)(eyesrect[i].Width * rescale),
                                                                       (int)(eyesrect[i].Height * rescale));
                        }
                    }



                    int newtop = (int)(facerect.Top) - (int)(0.3 * facerect.Height);
                    if (newtop < 0)
                    {
                        newtop = 0;
                    }
                    int deltatop = facerect.Top - newtop;

                    int newleft = (int)(facerect.Left) - (int)(0.3 * facerect.Width);
                    if (newleft < 0)
                    {
                        newleft = 0;
                    }
                    int deltaleft = facerect.Left - newleft;

                    int maxheight = ((BitmapImage)Image1.Source).PixelHeight - newtop - 1;
                    facerect.Height = (int)(facerect.Height * 1.6);
                    if (facerect.Height > maxheight)
                    {
                        facerect.Height = maxheight;
                    }

                    int maxwidth = ((BitmapImage)Image1.Source).PixelWidth - newleft - 1;
                    facerect.Width = (int)(facerect.Width * 1.6);
                    if (facerect.Width > maxwidth)
                    {
                        facerect.Width = maxwidth;
                    }

                    facerect = new System.Drawing.Rectangle(newleft, newtop, facerect.Width, facerect.Height);

                    CroppedBitmap crop = new CroppedBitmap(
                        Image1.Source.Clone() as BitmapImage,
                        new Int32Rect(facerect.Left, facerect.Top, facerect.Width, facerect.Height)
                        );
                    System.Drawing.Bitmap bm = CCommon.BitmapImage2Bitmap(crop);
                    bm.Save(AppDomain.CurrentDomain.BaseDirectory + "temp\\~cropface.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    bm.Dispose();
                    bm = null;
                    CCommon.LoadImageSource(Image1, AppDomain.CurrentDomain.BaseDirectory + "temp\\~cropface.jpg", false);

                    imagewidth  = ((BitmapImage)(Image1.Source)).PixelWidth;
                    imageheight = ((BitmapImage)(Image1.Source)).PixelHeight;
                    this.UpdateLayout();
                    wpfimagewidth  = Image1.ActualWidth;
                    wpfimageheight = Image1.ActualHeight;
                    //find the new ratio
                    ratio = imageheight / wpfimageheight;

                    facerect = new System.Drawing.Rectangle(deltaleft, deltatop, facerect.Width, facerect.Height);
                }

                //////////////////
                //strfaceindex!="" implies face is from a multiple faces image
                if (strfaceindex != "")
                {
                    var    fileparts      = this.CurrentFile.Split('\\');
                    string facepointsfile = AppDomain.CurrentDomain.BaseDirectory + "temp\\" + fileparts[fileparts.Length - 1] + strfaceindex + ".info.txt";
                    //check if we have the cached face points in file
                    if (File.Exists(facepointsfile))
                    {
                        //read these face points and update the face points markers

                        using (var file = File.OpenText(facepointsfile))
                        {
                            List <FeaturePointType> facepoints = new List <FeaturePointType>();
                            string s     = file.ReadToEnd();
                            var    lines = s.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                            for (int i = 0; i < lines.Length; i++)
                            {
                                var parts           = lines[i].Split('=');
                                FeaturePointType fp = new FeaturePointType();
                                fp.desp = parts[0];
                                fp.pt   = ExtractPoint(parts[1]);
                                facepoints.Add(fp);
                            }
                            ((MainWindow)this.Owner).ImageFacePoints = facepoints;
                        }
                        LoadFacePointsFromCache = true;
                        fps = ((MainWindow)this.Owner).ImageFacePoints;
                    }
                    else
                    {
                        LoadFacePointsFromCache = false;
                    }
                }

                ////////////////
                if (facerect != System.Drawing.Rectangle.Empty && LoadFacePointsFromCache)
                {
                    List <UIElement> list = Canvas1.Children.Cast <UIElement>().ToList();
                    for (int i = 0; i < _numfacepoints; i++)
                    {
                        System.Windows.Shapes.Ellipse ep = (System.Windows.Shapes.Ellipse)list.Single(s => s.Uid == "EP" + i);
                        Canvas.SetTop(ep, fps[i].pt.Y / ratio + Canvas.GetTop(Grid1) - ep.Height / 2);
                        Canvas.SetLeft(ep, fps[i].pt.X / ratio + Canvas.GetLeft(Grid1) - ep.Width / 2);
                    }
                }


                if (facerect != System.Drawing.Rectangle.Empty && eyesrect != null && !LoadFacePointsFromCache)
                {
                    List <UIElement> list = Canvas1.Children.Cast <UIElement>().ToList();

                    //For elimination of overlapping eyes detected
                    System.Drawing.Bitmap   bmtemp   = new System.Drawing.Bitmap((int)imagewidth, (int)imageheight /*,System.Drawing.Imaging.PixelFormat.Format24bppRgb*/);
                    System.Drawing.Graphics gbmptemp = System.Drawing.Graphics.FromImage(bmtemp);
                    gbmptemp.Clear(System.Drawing.Color.Black);

                    int nmaxeyes = (eyesrect.Length > _numfacepoints) ? _numfacepoints  : eyesrect.Length;
                    int n        = 0;
                    for (int i = 0; i < nmaxeyes; i++)
                    {
                        //valid eye pos relative to facerect top
                        //var normalized_eye_y = ((double)eyesrect[i].Y +((double)eyesrect[i].Height/2)) / facerect.Height;
                        //var normalized_eye_x_to_mid_face =
                        //     Math.Abs((eyesrect[i].X + (double)eyesrect[i].Width / 2) - ((double)facerect.Width / 2)) / ((double)facerect.Width / 2);

                        //System.Diagnostics.Debug.Print("{0} {1}", normalized_eye_y,normalized_eye_x_to_mid_face);

                        System.Windows.Shapes.Ellipse ep = (System.Windows.Shapes.Ellipse)list.Single(s => s.Uid == "EP" + i);

                        double top  = (eyesrect[i].Y + facerect.Y + (double)eyesrect[i].Height / 2) / ratio + Canvas.GetTop(Grid1) - ep.Height / 2;
                        double left = (eyesrect[i].X + facerect.X + (double)eyesrect[i].Width / 2) / ratio + Canvas.GetLeft(Grid1) - ep.Width / 2;

                        int argb = (bmtemp.GetPixel(facerect.X + eyesrect[i].X, facerect.Y + eyesrect[i].Y)).ToArgb();
                        if (argb == System.Drawing.Color.Black.ToArgb())
                        {
                            if (n >= 2)
                            {
                                break;          //we already got 2 eyes, dont need any more
                            }
                            Canvas.SetTop(ep, top);
                            Canvas.SetLeft(ep, left);
                            _currentEllipseIndex = (++n) % _numfacepoints;
                        }

                        gbmptemp.FillEllipse(System.Drawing.Brushes.White, facerect.X + eyesrect[i].X, facerect.Y + eyesrect[i].Y, eyesrect[i].Width, eyesrect[i].Height);

                        System.Diagnostics.Debug.Print("Get {0},{1}", Canvas.GetLeft(ep), Canvas.GetTop(ep));
                    }

                    bmtemp.Save(AppDomain.CurrentDomain.BaseDirectory + "temp\\~eploc.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
                    gbmptemp.Dispose();
                    bmtemp.Dispose();
                    bmtemp = null;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }