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 btnOK_Click(object sender, RoutedEventArgs e) { //newmesh directory string newmeshdir = AppDomain.CurrentDomain.BaseDirectory + "newmesh\\"; string meshfilename = ""; string texturefilename = ""; string infofilename = ""; string billboardfilename = ""; string configfilename = ""; //find the index and next name for the meshid int index = 0; bool bfound = false; //bool to load new face model try { if (FaceModelTransform.basemodelid != null) { if (MessageBox.Show("Save Edited face model as New face model?", "", MessageBoxButton.YesNo, MessageBoxImage.None, MessageBoxResult.No) != MessageBoxResult.Yes) { bfound = true; index = FaceModelTransform.index; } else { FaceModelTransform = new FaceModelTransformType(); } } while (!bfound) { index++; string testfile = newmeshdir + "mesh" + BaseModelID + index; // meshfilename = testfile + ".x"; //texturefilename = testfile + ".png"; //billboardfilename = testfile + ".jpg"; //infofilename = testfile + ".info.txt"; //configfilename = testfile + ".config.txt"; if (!File.Exists(testfile + ".x")) { bfound = true; } } FaceModelCreatedIndex = index; string basefilename = newmeshdir + "mesh" + BaseModelID + index; meshfilename = basefilename + ".x"; texturefilename = basefilename + ".png"; billboardfilename = basefilename + ".jpg"; infofilename = basefilename + ".info.txt"; configfilename = basefilename + ".config.txt"; //create the texture file var bm = new System.Drawing.Bitmap(1920, 1080, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var gbm = System.Drawing.Graphics.FromImage(bm); gbm.Clear(System.Drawing.Color.FromArgb(BaseColorARGB)); for (int i = 0; i < _TriangleIndices.Count; i = i + 3) { System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(255, System.Drawing.Color.Red)); //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 = System.Drawing.Pens.Green; } //14 (nose tip) if (_TriangleIndices[i] == 14 || _TriangleIndices[i + 1] == 14 || _TriangleIndices[i + 2] == 14) { pen = System.Drawing.Pens.Green; } //0 (chin) if (_TriangleIndices[i] == 0 || _TriangleIndices[i + 1] == 0 || _TriangleIndices[i + 2] == 0) { pen = System.Drawing.Pens.Green; } //328-1105 (right eye is between this 2 points) if (_TriangleIndices[i] == 1105 || _TriangleIndices[i + 1] == 1105 || _TriangleIndices[i + 2] == 1105) { pen = System.Drawing.Pens.Green; } //883-1092 (left eye is between these 2 points) if (_TriangleIndices[i] == 1092 || _TriangleIndices[i + 1] == 1092 || _TriangleIndices[i + 2] == 1092) { pen = System.Drawing.Pens.Green; } var meshpoint0 = new System.Drawing.PointF((float)_TextureCoordinates[_TriangleIndices[i]].X * (1920 - 1), (float)_TextureCoordinates[_TriangleIndices[i]].Y * (1080 - 1)); var meshpoint1 = new System.Drawing.PointF((float)_TextureCoordinates[_TriangleIndices[i + 1]].X * (1920 - 1), (float)_TextureCoordinates[_TriangleIndices[i + 1]].Y * (1080 - 1)); var meshpoint2 = new System.Drawing.PointF((float)_TextureCoordinates[_TriangleIndices[i + 2]].X * (1920 - 1), (float)_TextureCoordinates[_TriangleIndices[i + 2]].Y * (1080 - 1)); gbm.DrawPolygon(pen, new System.Drawing.PointF[] { meshpoint0, meshpoint1, meshpoint2 } ); } gbm.Dispose(); bm.Save(texturefilename, System.Drawing.Imaging.ImageFormat.Png); bm.Dispose(); bm = null; //create the billboard jpg from the display chkMesh.IsChecked = true; BitmapSource imgsrc = Image1.Source as BitmapSource; System.Drawing.Bitmap bm1 = CCommon.BitmapImage2Bitmap(imgsrc); System.Drawing.Bitmap bm2 = new System.Drawing.Bitmap(bm1.Width + 80, bm1.Height + 150, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Graphics gbm2 = System.Drawing.Graphics.FromImage(bm2); gbm2.Clear(System.Drawing.Color.FromArgb(BaseColorARGB)); gbm2.DrawImage(bm1, 40, 150); var sf = new System.Drawing.StringFormat(); sf.Alignment = System.Drawing.StringAlignment.Center; string str = BaseModelID.Substring(0, BaseModelID.Length - 4) + "\n" + index; gbm2.DrawString(str, new System.Drawing.Font("Arial", 50, System.Drawing.FontStyle.Bold), System.Drawing.Brushes.Black, new System.Drawing.RectangleF(20, 10, bm1.Width + 40, 140), sf ); gbm2.Dispose(); bm2.Save(billboardfilename, System.Drawing.Imaging.ImageFormat.Jpeg); bm1.Dispose(); bm1 = null; bm2.Dispose(); bm2 = null; //the xfile using (TextWriter tw = File.CreateText(meshfilename)) { foreach (var vertice in _Positions) { tw.WriteLine("{0}:{1}:{2}", vertice.X.ToString(CultureInfo.InvariantCulture), vertice.Y.ToString(CultureInfo.InvariantCulture), vertice.Z.ToString(CultureInfo.InvariantCulture)); } for (int i = 0; i < _TextureCoordinates.Count; i++) { //if (hidden_indices.IndexOf(i) < 0) //{ // tw.WriteLine("{0}:{1}", _TextureCoordinates[i].X, _TextureCoordinates[i].Y); //} //else //{ // tw.WriteLine("{0}:{1}", 0, 0); //} tw.WriteLine("{0}:{1}", _TextureCoordinates[i].X.ToString(CultureInfo.InvariantCulture), _TextureCoordinates[i].Y.ToString(CultureInfo.InvariantCulture)); } } //the config file if (File.Exists(configfilename)) { File.Delete(configfilename); } using (TextWriter tw = File.CreateText(configfilename)) { tw.WriteLine("basemodelid={0}", BaseModelID); tw.WriteLine("index={0}", index); tw.WriteLine("rotateX={0}", sliderx.Value.ToString(CultureInfo.InvariantCulture)); tw.WriteLine("rotateY={0}", slidery.Value.ToString(CultureInfo.InvariantCulture)); tw.WriteLine("rotateZ={0}", sliderz.Value.ToString(CultureInfo.InvariantCulture)); tw.WriteLine("stretchX={0}", sliderStretchX.Value.ToString(CultureInfo.InvariantCulture)); } //the info.txt file if (File.Exists(infofilename)) { File.Delete(infofilename); } using (TextWriter tw = File.CreateText(infofilename)) { tw.WriteLine("RightEye1={0},{1}", (int)(((_TextureCoordinates[328].X + _TextureCoordinates[1105].X) / 2) * 1920), (int)(((_TextureCoordinates[328].Y + _TextureCoordinates[1105].Y) / 2) * 1080) ); tw.WriteLine("LeftEye1={0},{1}", (int)(((_TextureCoordinates[883].X + _TextureCoordinates[1092].X) / 2) * 1920), (int)(((_TextureCoordinates[883].Y + _TextureCoordinates[1092].Y) / 2) * 1080) ); tw.WriteLine("Nose1={0},{1}", (int)(_TextureCoordinates[14].X * 1920), (int)(_TextureCoordinates[14].Y * 1080) ); tw.WriteLine("Mouth3={0},{1}", (int)(_TextureCoordinates[10].X * 1920), (int)(_TextureCoordinates[10].Y * 1080) ); tw.WriteLine("Chin1={0},{1}", (int)(_TextureCoordinates[0].X * 1920), (int)(_TextureCoordinates[0].Y * 1080) ); } MessageBox.Show(BaseModelID + index + " successfully " + ((FaceModelTransform.basemodelid == null)? "created":"modified") ); FaceIndexAssigned = index; this.DialogResult = true; this.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
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()); } }
private void ButtonSave_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog(); saveFileDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory + "snap\\"; saveFileDialog.Filter = "Jpg files (*.jpg)|*.jpg"; if (saveFileDialog.ShowDialog() != true) { return; } string filename = saveFileDialog.FileName; int imagewidth = (int)Image1.Source.Width; int imageheight = (int)Image1.Source.Height; System.Drawing.Bitmap bm = null; ImageBrush ib = null; if (SourceBrushImage == null) { bm = new System.Drawing.Bitmap(imagewidth, imageheight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } else { ib = (ImageBrush)(TopGrid.Background); if (ib != null) { BitmapSource ibimgsrc = ib.ImageSource as BitmapSource; bm = CCommon.BitmapImage2Bitmap(ibimgsrc); } else { bm = new System.Drawing.Bitmap(imagewidth, imageheight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } } System.Drawing.Graphics gbm = System.Drawing.Graphics.FromImage(bm); if (SourceBrushImage == null || ib == null) { gbm.Clear(System.Drawing.Color.FromArgb(255, 255, 255, 255)); } //Image1 store the image System.Drawing.Bitmap bm2 = CCommon.BitmapImage2Bitmap(Image1.Source as BitmapSource); gbm.DrawImage(bm2, 0, 0); gbm.Dispose(); bm.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg); //default to 24 rgb // bm.Save(filename, System.Drawing.Imaging.ImageFormat.Png); //default to 32 argb bm.Dispose(); bm2.Dispose(); bm = null; bm2 = null; MessageBox.Show("File saved successfully."); } catch { MessageBox.Show("Failed to save file."); } }
//return "0" for single face and "c"(cache) for multiple face //for multiple face, the face rectangles are stored in CCommon.cacheRects //CComon.cacheBm store the 24bit Bitmap for source image public static string FindFaceAndEyes(BitmapSource srcimage, out System.Drawing.Rectangle facerect, out System.Drawing.Rectangle[] eyesrect) { String faceFileName = AppDomain.CurrentDomain.BaseDirectory + "haarcascade_frontalface_alt2.xml"; String eyeFileName = AppDomain.CurrentDomain.BaseDirectory + "haarcascade_eye.xml"; //working with gdi to get 24bit rgb image System.Drawing.Bitmap bmtest = CCommon.BitmapImage2Bitmap(srcimage); System.Drawing.Bitmap bmsrc24 = new System.Drawing.Bitmap(bmtest.Width, bmtest.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); System.Drawing.Graphics gbmsrc24 = System.Drawing.Graphics.FromImage(bmsrc24); gbmsrc24.DrawImageUnscaled(bmtest, 0, 0); gbmsrc24.Dispose(); bmtest.Dispose(); bmtest = null; if (cacheBm != null) { cacheBm.Dispose(); } cacheBm = (System.Drawing.Bitmap)bmsrc24.Clone(); //we do scaling if the source is too large double scale = 1.0; if (bmsrc24.Height > 500) { scale = (double)500 / bmsrc24.Height; } System.Drawing.Bitmap bm = new System.Drawing.Bitmap((int)(bmsrc24.Width * scale), (int)(bmsrc24.Height * scale), System.Drawing.Imaging.PixelFormat.Format24bppRgb); System.Drawing.Graphics gbm = System.Drawing.Graphics.FromImage(bm); //scale down the source image for face dection gbm.DrawImage(bmsrc24, new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), new System.Drawing.Rectangle(0, 0, bmsrc24.Width, bmsrc24.Height), System.Drawing.GraphicsUnit.Pixel); gbm.Dispose(); // bm.Save(AppDomain.CurrentDomain.BaseDirectory +"temp\\~bm.jpg",System.Drawing.Imaging.ImageFormat.Jpeg); ////////////////////////////////////////// IntelImage _img = CDetectFace.CreateIntelImageFromBitmap(bm); //IntPtr p_face = CDetectFace.HistEqualize(_img); bm.Dispose(); bm = null; string strindex = ""; using (HaarClassifier haarface = new HaarClassifier(faceFileName)) using (HaarClassifier haareye = new HaarClassifier(eyeFileName)) { var faces = haarface.DetectObjects(_img.IplImage()); // var faces = haarface.DetectObjects(p_face ); if (faces.Count > 0) { List <System.Drawing.Rectangle> facerects = new List <System.Drawing.Rectangle>(); for (int i = 0; i < faces.Count; i++) { var face = faces.ElementAt(i); System.Drawing.Rectangle rt = new System.Drawing.Rectangle((int)(face.x / scale), (int)(face.y / scale), (int)(face.width / scale), (int)(face.height / scale)); facerects.Add(rt); } cacheRects = facerects; if (faces.Count > 1) { //clean up and return eyesrect = null; facerect = facerect = System.Drawing.Rectangle.Empty; _img.Dispose(); bmsrc24.Dispose(); bmsrc24 = null; return("c"); //cached } } else { cacheRects.Clear(); } //only handle 1 face if (faces.Count == 1) { var face = faces.ElementAt(0); facerect = new System.Drawing.Rectangle((int)(face.x / scale), (int)(face.y / scale), (int)(face.width / scale), (int)(face.height / scale)); int x = facerect.X, y = facerect.Y, h0 = facerect.Height, w0 = facerect.Width; //to handle oversize face area double rescale = 1.0; if (h0 > 300) { rescale = 300.0 / h0; } System.Drawing.Rectangle temprect = new System.Drawing.Rectangle(x, y, w0, 10 * h0 / 16); System.Drawing.Bitmap bm_eyes = bmsrc24.cropAtRect(temprect); bm_eyes.Save(AppDomain.CurrentDomain.BaseDirectory + "temp\\~eye.bmp", System.Drawing.Imaging.ImageFormat.Bmp); IntelImage image_eyes = CDetectFace.CreateIntelImageFromBitmap(bm_eyes); //resize eyes area for better detection IntelImage image_eyes2X = new IntelImage((int)(image_eyes.IplImageStruc().width *2 * rescale), (int)(image_eyes.IplImageStruc().height *2 * rescale)); NativeMethods.CvResize(image_eyes.IplImage(), image_eyes2X.IplImage(), NativeMethods.CV_INTER_CUBIC); IntPtr p_eq_img_eyes = CDetectFace.HistEqualize(image_eyes2X); var eyes = haareye.DetectObjects(p_eq_img_eyes); ////clean up NativeMethods.cvReleaseImage(ref p_eq_img_eyes); image_eyes.Dispose(); image_eyes = null; bm_eyes.Dispose(); image_eyes2X.Dispose(); image_eyes2X = null; if (eyes.Count > 0) { eyesrect = new System.Drawing.Rectangle[eyes.Count]; for (int i = 0; i < eyesrect.Length; i++) { var eye = eyes.ElementAt(i); //note that we had scale the eyes area by 2, so we scale back eyesrect[i] = new System.Drawing.Rectangle((int)(eye.x / (2 * rescale)), (int)(eye.y / (2 * rescale)), (int)(eye.width / (2 * rescale)), (int)(eye.height / (2 * rescale))); } int mineyesize = (h0 / 12); int maxeyesize = (h0 / 3); //sorting var tempeyeslist = eyesrect.ToList(); //dist to center of face // <-1/2 w --> // | | | // |<-x ->o<d>| | // | | | // | | | // | | | // o=center of eye // x= x dist to center of eye // d= difference of 1/2 w and x // = distance of eye center to center of face // the further this distance, the more likely it is an eye int half_facewidth = facerect.Width / 2; tempeyeslist = tempeyeslist.OrderByDescending(eye => Math.Abs(eye.X + eye.Width / 2 - (half_facewidth))).ToList(); //size: should be within min and max eye size tempeyeslist = tempeyeslist.OrderByDescending(eye => (eye.Width > mineyesize)).ToList(); tempeyeslist = tempeyeslist.OrderByDescending(eye => (eye.Width < maxeyesize)).ToList(); eyesrect = tempeyeslist.ToArray(); } else { eyesrect = null; } } else { facerect = System.Drawing.Rectangle.Empty; eyesrect = null; } } //NativeMethods.cvReleaseImage(ref p_face ); _img.Dispose(); bmsrc24.Dispose(); bmsrc24 = null; return(strindex); }
private void Button1_Click(object sender, RoutedEventArgs e) { _bIsBusy = true; Button1.IsEnabled = false; try { bool bCompleteRound = false; Slider slider = ((MainWindow)this.Owner).hscroll; float deltaXDeg = 5f; int nDirChanged = 0; AnimatedGifEncoder enc = new AnimatedGifEncoder(); String outputFilePath = AppDomain.CurrentDomain.BaseDirectory + "temp\\~gif.gif"; enc.Start(outputFilePath); enc.SetDelay(100); //-1:no repeat,0:always repeat enc.SetRepeat(0); int maxwidth = 0; int maxheight = 0; int frameno = 0; string savedTitle = this.Title; while (!bCompleteRound) { var deg = slider.Value; System.Diagnostics.Debug.Print("Deg=" + deg); BitmapSource bms = ((MainWindow)this.Owner).CreateSnap(); Image1.Source = bms; Image1.Refresh(); System.Drawing.Bitmap bm = CCommon.BitmapImage2Bitmap(bms); if (bm.Width > maxwidth) { maxwidth = bm.Width; } if (bm.Height > maxheight) { maxheight = bm.Height; } enc.AddFrame(bm); frameno++; this.Title = "Processing Frame no:" + frameno; if (deg > 50 || deg < -50) { deltaXDeg = -1 * deltaXDeg; nDirChanged++; } slider.Value += deltaXDeg; System.Windows.Forms.Application.DoEvents(); if (nDirChanged >= 2 && slider.Value > 0 && slider.Value < 10) { bCompleteRound = true; } bm.Dispose(); bm = null; } enc.Finish(); this.Title = savedTitle; string path2gif = "file:///" + AppDomain.CurrentDomain.BaseDirectory + "temp/~gif.gif"; int height = 0, width = 0; double ratio = ((double)maxwidth) / maxheight; if (ratio > 1.0) //long { width = (int)WebBrowser1.Width; height = (int)(width / ratio); } else //tall; { height = (int)WebBrowser1.Height; width = (int)(height * ratio); } string imgstr = "<img width=\"" + width + "\" height=\"" + height + "\" src=\"" + path2gif + "\">"; // string imgstr = "<img src=\"" + path2gif + "\">"; string strdiv = "<div style=\"width:100%; text-align:center\">" + imgstr + "</div>"; string navstr = "<html><body style=\"margin: 0px; background: #0e0e0e;\">" + strdiv + "</body></html>"; WebBrowser1.NavigateToString(navstr); } catch { } Button2.IsEnabled = true; _bIsBusy = false; }