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); }
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; }
//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()); } }