[转]一个人脸检测器

 

//本文使用到Emgu.CV库,该库是C#语言对OpenCV的封装,以下是一个列子程序的改正版本。
using System; using System.Collections.Generic; using System.Text; using Emgu.CV.Structure; using Emgu.CV; namespace VSL.Plugin.TrackingSystem.SimpleTrackingSystemExample { public class FaceDetector { //private HaarCascade _faceCascade; Emgu.CV.HaarCascade face;// = new HaarCascade(".\\haarcascades\\haarcascade_frontalface_alt_tree.xml"); Emgu.CV.HaarCascade eye;// = new HaarCascade(".\\haarcascades\\haarcascade_frontaleye.xml"); public FaceDetector() { // _faceCascade = new HaarCascade(".\\haarcascades\\haarcascade_frontalface_alt_tree.xml"); face = new Emgu.CV.HaarCascade(".\\haarcascades\\haarcascade_frontalface_alt_tree.xml"); eye = new Emgu.CV.HaarCascade(".\\haarcascades\\haarcascade_frontaleye.xml"); } public List<Face<D>> Detect<D>(Emgu.CV.Image<Emgu.CV.Bgr, D> img) { using (Emgu.CV.Image<Emgu.CV.Gray, D> gray = img.Convert<Emgu.CV.Gray, D>()) { MCvAvgComp[][] objects = gray.DetectHaarCascade(face); List<Face<D>> res = new List<Face<D>>(); System.Drawing.Rectangle rect = img.ROI; //保存操作区域 //通过判断脸部是否含有眼睛来进一步检测是否是正确的人脸 foreach (MCvAvgComp f in objects[0]) { //检测眼睛 gray.ROI = f.rect; MCvAvgComp[][] eyesDetected = gray.DetectHaarCascade(eye, 1.1, 1, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE. DO_CANNY_PRUNING, new System.Drawing.Size(20, 20)); gray.ROI = System.Drawing.Rectangle.Empty; //if there is no eye in the specific region, the region shouldn't contains a face //note that we might not be able to recoginize a person who ware glass in this case if (eyesDetected[0].Length == 0) continue; img.ROI = f.rect; //设定操作区域 res.Add(new Face<D>(img.Copy(), f.rect)); } img.ROI = rect; //恢复操作区域 return res; } } public void Dispose() { face.Dispose(); } } public class Eye<D> { private Emgu.CV.Image<Emgu.CV.Bgr, D> _image; public Eye(Emgu.CV.Image<Emgu.CV.Bgr, D> img, System.Drawing.Rectangle rect) { _image = img; } public Emgu.CV.Image<Emgu.CV.Bgr, D> RGB { get { return _image; } } } public class Face<D> { private Emgu.CV.Image<Emgu.CV.Bgr, D> _image; private Emgu.CV.Image<Emgu.CV.Gray, D> _imageGray; private Emgu.CV.Image<Emgu.CV.Hsv, D> _imageHSV; private Emgu.CV.Image<Emgu.CV.Gray, D> _h; private Emgu.CV.Image<Emgu.CV.Gray, D> _s; private Emgu.CV.Image<Emgu.CV.Gray, D> _v; private Emgu.CV.Histogram _hueHtg; //private Seq<MCvContour> _skinContour; private System.Drawing.Rectangle _rect; private Emgu.CV.HaarCascade _eyeCascade; public Face(Emgu.CV.Image<Emgu.CV.Bgr, D> img, System.Drawing.Rectangle rect) { _image = img; _rect = rect; _eyeCascade = new Emgu.CV.HaarCascade(".\\haarcascades\\eye_12.xml"); } public List<Eye<D>> DetectEye() { MCvAvgComp[][] objects = Gray.DetectHaarCascade(_eyeCascade); List<Eye<D>> res = new List<Eye<D>>(); foreach (MCvAvgComp o in objects[0]) { _image.ROI = o.rect; res.Add(new Eye<D>(_image.Copy(), o.rect)); } _image.ROI = System.Drawing.Rectangle.Empty; return res; } public System.Drawing.Rectangle Rectangle { get { return _rect; } } public Emgu.CV.Image<Emgu.CV.Bgr, D> Bgr { get { return _image; } } public Emgu.CV.Image<Emgu.CV.Gray, D> Gray { get { if (_imageGray == null) _imageGray = _image.Convert<Emgu.CV.Gray, D>(); return _imageGray; } } public Emgu.CV.Image<Emgu.CV.Hsv, D> Hsv { get { if (_imageHSV == null) _imageHSV = _image.Convert<Emgu.CV.Hsv, D>(); return _imageHSV; } } public Emgu.CV.Image<Emgu.CV.Gray, D> H { get { if (_h == null) { Emgu.CV.Image<Gray, D>[] imgs = Hsv.Split(); _h = imgs[0]; _s = imgs[1]; _v = imgs[2]; } return _h; } } public Image<Gray, D> S { get { if (_s == null) { Image<Gray, D>[] imgs = Hsv.Split(); _h = imgs[0]; _s = imgs[1]; _v = imgs[2]; } return _s; } } public Image<Gray, D> V { get { if (_h == null) { Image<Gray, D>[] imgs = Hsv.Split(); _h = imgs[0]; _s = imgs[1]; _v = imgs[2]; } return _v; } } public Histogram HueHistogram { get { if (_hueHtg == null) { int size = 60; _hueHtg = new Histogram(new int[1] { size }, new float[1] { 0.0f }, new float[1] { 180.0f }); } return _hueHtg; } } public Image<Gray, D> SkinMask { get { Image<Gray, D> skinMask = Gray.CopyBlank(); //skinMask.Draw(SkinContour, new Gray(255.0), new Gray(120.0), -1); return skinMask; } } /* public Seq<MCvContour> SkinContour { get { if (_skinContour == null) { Histogram htg = HueHistogram; htg.Accumulate(new Image<Gray, D>[1] { H }); double[] arr = new double[htg.BinSize[0]]; for (int i = 0; i < htg.BinSize[0]; i++) arr[i] = htg.Query(new int[1] { i }); System.Array.Sort<double>(arr); System.Array.Reverse(arr); htg.Threshold(arr[2]); using (Image<Gray, D> bpj = htg.BackProject(new Image<Gray, D>[1] { H })) { Seq<MCvContour> cList = bpj.FindContours( CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, new MemStorage()); Seq<MCvContour> maxAreaContour = cList; foreach (Seq<MCvContour> ct in cList) { if (ct.Area > maxAreaContour.Area) maxAreaContour = ct; } _skinContour = GRAY.Snake(maxAreaContour, 1.0f, 1.0f, 1.0f, new Point2D<int>(5, 5), new Emgu.CV.MCvTermCriteria(20, 1.0), new MemStorage()); } } return _skinContour; } }*/ public void Dispose() { _image.Dispose(); if (_imageGray != null) _imageGray.Dispose(); if (_imageHSV != null) _imageHSV.Dispose(); if (_h != null) _h.Dispose(); if (_s != null) _s.Dispose(); if (_v != null) _v.Dispose(); //if (_skinContour != null) _skinContour.Dispose(); } } }

 

 

文章源地址: http://www.cnblogs.com/zengqs/archive/2009/02/01/1382024.html

posted @ 2010-10-12 15:19  M'  阅读(1747)  评论(0编辑  收藏  举报