//static void RunDetection(string filename, Rect rect, Point leftEye, Point rightEye, ref byte [] facePix, Rect faceRect) static void RunDetection(string filename, Rect rect, FaceDisp.FaceData faceData, ref byte [] facePix, Rect faceRect) { EyeDetect eyeDetect = new EyeDetect(); int byteCountPerPix = (int)(facePix.Length / faceRect.Width / faceRect.Height); bool isSuccess = eyeDetect.SetAlgorithm(_algo, _algoData); if (true == isSuccess) { EyeDetectResult eyeResult = eyeDetect.Detect(facePix, (int)_faceDisplayWidth, (int)_faceDisplayWidth); _outStream.WriteLine("{0}", filename); _outStream.Write("{0} {1} {2} {3} ", (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height); if (faceData.TrueLeftEye.X > 1.0) { Point leftEye = FaceFeatureToScaledPoint(faceData.TrueLeftEye, rect); Point rightEye = FaceFeatureToScaledPoint(faceData.TrueRightEye, rect); _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", leftEye.X, leftEye.Y, rightEye.X, rightEye.Y); } else { _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", faceData.TrueLeftEye.X, faceData.TrueLeftEye.Y, faceData.TrueRightEye.X, faceData.TrueRightEye.Y); } _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", eyeResult.LeftEye.X / _faceDisplayWidth, eyeResult.LeftEye.Y / _faceDisplayWidth, eyeResult.RightEye.X / _faceDisplayWidth, eyeResult.RightEye.Y / _faceDisplayWidth); FaceFeatureResult res = eyeResult as FaceFeatureResult; if (null != res) { if (faceData.Nose.X > 1.0) { Point nose = FaceFeatureToScaledPoint(faceData.Nose, rect); Point leftMouth = FaceFeatureToScaledPoint(faceData.LeftMouth, rect); Point rightMouth = FaceFeatureToScaledPoint(faceData.RightMouth, rect); _outStream.Write("{0:F3} {1:F3} ", nose.X, nose.Y); _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", leftMouth.X, leftMouth.Y, rightMouth.X, rightMouth.Y); } else { _outStream.Write("{0:F3} {1:F3} ", faceData.Nose.X, faceData.Nose.Y); _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", faceData.LeftMouth.X, faceData.LeftMouth.Y, faceData.RightMouth.X, faceData.RightMouth.Y); } _outStream.Write("{0:F3} {1:F3} ", res.Nose.X / _faceDisplayWidth, res.Nose.Y / _faceDisplayWidth); _outStream.Write("{0:F3} {1:F3} {2:F3} {3:F3} ", res.LeftMouth.X / _faceDisplayWidth, res.LeftMouth.Y / _faceDisplayWidth, res.RightMouth.X / _faceDisplayWidth, res.RightMouth.Y / _faceDisplayWidth); } if (_maxTransformCount > 0) { _outStream.Write("{0:F3} {1:F3} {2:F3}", _transform.Theta, _transform.X, _transform.Y); } _outStream.WriteLine(); } else { _outStream.WriteLine("Detection failed on {0}", filename); } }
static private FaceDisp.FaceData RotateFaceFeats(FaceDisp.FaceData faceData, TransformSample trans) { Rect faceRect = new Rect(faceData.faceRect.X, faceData.faceRect.Y, faceData.faceRect.Width, faceData.faceRect.Height); return(new FaceDisp.FaceData(RotateRawEye(faceData.TrueLeftEye, faceRect, trans), RotateRawEye(faceData.TrueRightEye, faceRect, trans), RotateRawEye(faceData.Nose, faceRect, trans), RotateRawEye(faceData.LeftMouth, faceRect, trans), RotateRawEye(faceData.RightMouth, faceRect, trans))); }
static private int GenerateData(string imageFileName, List <FeaturePts> featureList) { if (null == imageFileName) { return(0); } DetectionResult detectionResult = _detector.DetectObject(imageFileName); List <ScoredRect> scoredResultList = detectionResult.GetMergedRectList(0.0F); int imageCount = 0; if (null != featureList && scoredResultList.Count > 0) { foreach (FeaturePts features in featureList) { System.Drawing.PointF point = (System.Drawing.PointF)features.ptLeftEye; Point leftEye = new Point(point.X, point.Y); point = (System.Drawing.PointF)features.ptRightEye; Point rightEye = new Point(point.X, point.Y); foreach (ScoredRect scoredRect in scoredResultList) { Rect rect = new Rect(); rect.X = scoredRect.X; rect.Y = scoredRect.Y; rect.Width = scoredRect.Width; rect.Height = scoredRect.Height; if (rect.Contains(leftEye) && rect.Contains(rightEye)) { leftEye.X = (leftEye.X - rect.X) / rect.Width; leftEye.Y = (leftEye.Y - rect.Y) / rect.Width;; rightEye.X = (rightEye.X - rect.X) / rect.Width;; rightEye.Y = (rightEye.Y - rect.Y) / rect.Width;; FaceDisp.FaceData faceData = new FaceDisp.FaceData(features.ptLeftEye, features.ptRightEye, features.ptNose, features.ptLeftMouth, features.ptRightMouth, rect); //ProcessFace(imageFileName, rect, leftEye, rightEye, 0); ProcessFace(imageFileName, rect, faceData, 0); ++imageCount; break; } } } } return(imageCount); }
static void WriteTrainDataAndTargets(byte[] facePix, Rect rect, FaceDisp.FaceData faceData) { Point leftEye = FaceFeatureToScaledPoint(faceData.TrueLeftEye, rect); Point rightEye = FaceFeatureToScaledPoint(faceData.TrueRightEye, rect); Point nose = FaceFeatureToScaledPoint(faceData.Nose, rect); Point leftMouth = FaceFeatureToScaledPoint(faceData.LeftMouth, rect); Point rightMouth = FaceFeatureToScaledPoint(faceData.RightMouth, rect); double[] eyes = { leftEye.X, leftEye.Y, rightEye.X, rightEye.Y, nose.X, nose.Y, leftMouth.X, leftMouth.Y, rightMouth.X, rightMouth.Y }; _outWriter.WriteSample(facePix, eyes); }
//static private bool ProcessFace(string filename, Rect rect, Point leftEye, Point rightEye, int photoId) static private bool ProcessFace(string filename, Rect rect, FaceDisp.FaceData faceData, int photoId) { byte[] dataPixs = null; try { dataPixs = CreateMainBitMap(filename); } catch (Exception) { } if (null == dataPixs) { Console.WriteLine("\nFailed to createBitmap for {0}", filename); return(false); } byte[] facePix = SelectAndNormalizePatch(dataPixs, new Point(rect.X, rect.Y), new Point(rect.X + rect.Width, rect.Y), new Point(0, 0), new Point(_faceDisplayWidth, 0), new Rect(0, 0, _faceDisplayWidth, _faceDisplayHeight)); if (null == facePix) { Console.WriteLine("\nFailed to extract face for {0}", filename); return(false); } Rect faceRect = new Rect(0, 0, _faceDisplayWidth, _faceDisplayHeight); _transform.Reset(); _transform.SetImageSize(rect); //bool retVal = ProcessFaceInstance(facePix, filename, rect, leftEye, rightEye, faceRect, photoId); bool retVal = ProcessFaceInstance(facePix, filename, rect, faceData, faceRect, photoId); if (_maxTransformCount > 0) { Random randGen = new Random(_randSeed); int rotateCount = (int)Math.Round(randGen.NextDouble() * _maxTransformCount); for (int iRot = 0; iRot < rotateCount; ++iRot) { _transform.Generate(); facePix = SelectTransformPatch(dataPixs, rect, _transform); //retVal &= ProcessFaceInstance(facePix, filename, rect, RotateEye(leftEye, _transform), RotateEye(rightEye, _transform), faceRect, // photoId); retVal &= ProcessFaceInstance(facePix, filename, rect, RotateFaceFeats(faceData, _transform), faceRect, photoId); } } return(retVal); }
static void WriteFeaturePatches(Rect rect, FaceDisp.FaceData faceData, ref byte[] facePix) { Point leftEye = FaceFeatureToScaledPoint(faceData.TrueLeftEye, rect); Point rightEye = FaceFeatureToScaledPoint(faceData.TrueRightEye, rect); Point nose = FaceFeatureToScaledPoint(faceData.Nose, rect); Point leftMouth = FaceFeatureToScaledPoint(faceData.LeftMouth, rect); Point rightMouth = FaceFeatureToScaledPoint(faceData.RightMouth, rect); WriteOneEye(leftEye, 0, _numPatchFeatures, ref facePix); WriteOneEye(rightEye, 0, _numPatchFeatures, ref facePix); WriteOneEye(nose, 1, _numPatchFeatures, ref facePix); WriteOneEye(leftMouth, 2, _numPatchFeatures, ref facePix); WriteOneEye(rightMouth, 3, _numPatchFeatures, ref facePix); Rect leftEyeRect = GetPatchRect(leftEye); Rect rightEyeRect = GetPatchRect(rightEye); Rect noseRect = GetPatchRect(nose); Rect leftMouthRect = GetPatchRect(leftMouth); Rect rightMouthRect = GetPatchRect(rightMouth); Rect rightRect = new Rect(Math.Max(0, rightEye.X * _faceDisplayWidth - 3 * _eyePatchWidth / 2 + 1), Math.Max(0, rightEye.Y * _faceDisplayHeight - 3 * _eyePatchHeight / 2 + 1), 2 * _eyePatchWidth - 1, 2 * _eyePatchHeight - 1); Random rand = new Random(_randSeed); Point nonFeat = new Point(); double validFaceWidth = _faceDisplayWidth - _eyePatchWidth; double validFaceHeight = _faceDisplayHeight - _eyePatchHeight; double[] targets = new double[_numPatchFeatures]; // Non positions are all zero for (int i = 0; i < _nonEyePatchCount; ++i) { do { nonFeat.Y = rand.NextDouble() * validFaceHeight; nonFeat.X = rand.NextDouble() * validFaceWidth; } while (true == leftEyeRect.Contains(nonFeat) || true == rightEyeRect.Contains(nonFeat) || true == noseRect.Contains(nonFeat) || true == leftMouthRect.Contains(nonFeat) || true == rightMouthRect.Contains(nonFeat)); Rect patchPos = new Rect(nonFeat.X, nonFeat.Y, _eyePatchWidth, _eyePatchHeight); WriteEyePatch(patchPos, targets, ref facePix); } }
static private int DoPreDetectSuiteFile(string suiteFile) { FaceDisp.FaceDataFile suiteReader = null; try { suiteReader = new FaceDisp.FaceDataFile(suiteFile, FaceDisp.FaceData.FaceDataTypeEnum.EyeDetect); } catch (Exception e) { Console.WriteLine("{0}", e.Message); } if (null == suiteReader) { return(0); } FaceDisp.FaceData faceData = null; int imageCount = 0; while ((faceData = suiteReader.GetNext()) != null) { Rect faceRect = faceData.FaceWindowsRect; if (true == ProcessFace(faceData.Filename, faceRect, faceData, faceData.PhotoId)) { ++imageCount; Console.Write("\rGenerated {0} Images.", imageCount); } else { Console.WriteLine("Failed {0}", faceData.Filename); } } Console.WriteLine(); return(imageCount); }
//static private bool ProcessFaceInstance(byte[] facePix, string filename, Rect rect, Point leftEye, Point rightEye, Rect faceRect, int photoId) static private bool ProcessFaceInstance(byte[] facePix, string filename, Rect rect, FaceDisp.FaceData faceData, Rect faceRect, int photoId) { facePix = ConvertToGreyScale(facePix); //facePix = NormalizeBySum(facePix); facePix = Normalize(facePix, faceRect, 1); if (_action == ProgActions.GenerateEyeFaceData) { byte[] data = MakeFaceData(facePix); WriteTrainDataAndTargets(data, rect, faceData); } else if (_action == ProgActions.FaceDetect) { //RunDetection(filename, rect, FaceFeatureToScaledPoint(faceData.TrueLeftEye, rect), // FaceFeatureToScaledPoint(faceData.TrueRightEye, rect), ref facePix, faceRect); RunDetection(filename, rect, faceData, ref facePix, faceRect); } else if (_action == ProgActions.GenerateEyePatchData) { WriteFeaturePatches(rect, faceData, ref facePix); } //_outStream.Flush(); return(true); }