static public IntelImage CreateIntelImageFromBitmap(System.Drawing.Bitmap bm) { var intelImage = new IntelImage(bm.Width, bm.Height, bm.PixelFormat != System.Drawing.Imaging.PixelFormat.Format8bppIndexed); byte[] pixelBuffer = new byte[bm.Height * intelImage.Stride]; CopyPixelsFromBitmap(bm, pixelBuffer); intelImage.CopyPixels(pixelBuffer); return(intelImage); }
static public IntelImage CreateIntelImageFromBitmapSource(BitmapSource bitmapSource) { var intelImage = new IntelImage(bitmapSource.PixelWidth, bitmapSource.PixelHeight, bitmapSource.Format != PixelFormats.Gray8); // int stride = bitmapSource.PixelWidth * ((bitmapSource.Format.BitsPerPixel + 7) / 8); byte[] pixelBuffer = new byte[bitmapSource.PixelHeight * intelImage.Stride]; bitmapSource.CopyPixels(pixelBuffer, intelImage.Stride, 0); intelImage.CopyPixels(pixelBuffer); return(intelImage); }
static public IntelImage FlipYIntelImage(IntelImage img) { Bitmap tempbm = new Bitmap(img.IplImageStruc().width, img.IplImageStruc().height, img.IplImageStruc().widthStep, System.Drawing.Imaging.PixelFormat.Format24bppRgb, img.IplImageStruc().imageData); tempbm.RotateFlip(RotateFlipType.RotateNoneFlipY); IntelImage _img = CreateIntelImageFromBitmap(tempbm); tempbm.Dispose(); tempbm = null; return(_img); }
static public IntPtr HistEqualize(IntelImage isrc) { try { //image for processing IntelImage iimg = new IntelImage(isrc.IplImageStruc().width, isrc.IplImageStruc().height); //convert src image to ycrcb format NativeMethods.CvCvtColor(isrc.IplImage(), iimg.IplImage(), NativeMethods.CV_BGR2YCrCb); //converted src image structure IplImage iimg_iplimage = iimg.IplImageStruc(); //get all the channels from the IntPtr y = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 1); IplImage yimg = (IplImage)Marshal.PtrToStructure(y, typeof(IplImage)); IntPtr cr = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 1); IplImage crimg = (IplImage)Marshal.PtrToStructure(cr, typeof(IplImage)); IntPtr cb = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 1); IplImage cbimg = (IplImage)Marshal.PtrToStructure(cb, typeof(IplImage)); NativeMethods.CvSplit(ref iimg_iplimage, ref yimg, ref crimg, ref cbimg); //**************************** //*******Equalized for y plane only //the ydest intel image // IntelImage iydest = new IntelImage(yimg); // IntPtr ydest = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 1); // NativeMethods.CvEqualizeHist(y, ydest); NativeMethods.CvSaveImage(AppDomain.CurrentDomain.BaseDirectory + "\\temp\\~eq.y1.bmp", y); // NativeMethods.CvSaveImage(AppDomain.CurrentDomain.BaseDirectory + "\\temp\\~eq.cr1.bmp", cr); // NativeMethods.CvSaveImage(AppDomain.CurrentDomain.BaseDirectory + "\\temp\\~eq.cb1.bmp", cb); // NativeMethods.CvSaveImage(AppDomain.CurrentDomain.BaseDirectory + "\\temp\\~eq.ydest.bmp", ydest); // IplImage ydest_iplimage = iydest.IplImageStruc(); //merge back into processing image // NativeMethods.CvMerge(ref ydest_iplimage, ref crimg, ref cbimg, ref iimg_iplimage); // IntPtr presult = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 3); // IntPtr presult = NativeMethods.cvCreateImage(new CvSize(iimg_iplimage.width, iimg_iplimage.height), 8, 1); // NativeMethods.CvCvtColor(iimg.IplImage(), presult, NativeMethods.CV_YCrCb2BGR); // IplImage result_img = (IplImage)Marshal.PtrToStructure(presult, typeof(IplImage)); // NativeMethods.CvCopy(ref ydest_iplimage, ref result_img); // NativeMethods.CvSaveImage(AppDomain.CurrentDomain.BaseDirectory + "\\temp\\~eq.bmp", presult); // NativeMethods.cvReleaseImage(ref y); NativeMethods.cvReleaseImage(ref cb); NativeMethods.cvReleaseImage(ref cr); //NativeMethods.cvReleaseImage(ref presult); iimg.Dispose(); iimg = null; // iydest.Dispose(); // iydest = null; // return presult; return(y); // return ydest; }catch (Exception ex) { System.Windows.MessageBox.Show(ex.ToString()); } return(IntPtr.Zero); }
//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); }
//Load from cache CCommon cacheBm and cacheRects public static void FindEyesFromCache(int faceindex, out System.Drawing.Rectangle[] eyesrect) { String eyeFileName = AppDomain.CurrentDomain.BaseDirectory + "haarcascade_eye.xml"; using (HaarClassifier haareye = new HaarClassifier(eyeFileName)) { var face = cacheRects.ElementAt(faceindex); var facerect = new System.Drawing.Rectangle((int)(face.X), (int)(face.Y), (int)(face.Width), (int)(face.Height)); 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 = cacheBm.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; } } }