public static Bitmap Process(FaceCacheModel cacheItem) { MKParams mkParams = new MKParams(); Bgr from = new Bgr(), to = new Bgr(); GetColorRange(new FourPoint[] { cacheItem.Model.RightCheek, cacheItem.Model.LeftCheek, cacheItem.Model.ChainArea }, cacheItem.Image, out from, out to); Image <Bgr, Double> con = cacheItem.Image.Convert <Bgr, Double>(); cacheItem.Image.ROI = cacheItem.Model.HeadArea; Image <Gray, byte> headColorMask = cacheItem.Image.InRange(from, to); cacheItem.Image.ROI = Rectangle.Empty; Image <Gray, byte> skinMask = new Image <Gray, byte>(cacheItem.Image.Width, cacheItem.Image.Height, new Gray(0)); skinMask.ROI = cacheItem.Model.HeadArea; headColorMask.CopyTo(skinMask); skinMask.ROI = Rectangle.Empty; CvInvoke.DrawContours(skinMask, GetVVP(cacheItem.Model.FaceBoundry), -1, new Bgr(Color.White).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(cacheItem.Model.LeftEyePoints), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(cacheItem.Model.RightEyePoints), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(cacheItem.Model.LipBoundry), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(cacheItem.Model.NoseBottom), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); Image <Bgr, Double> temp = new Image <Bgr, Double>(con.Width, con.Height, new Bgr(mkParams.SkinMaskColor)); con.AccumulateWeighted(temp, mkParams.FaceAlpha, skinMask); con.Draw(cacheItem.Model.HeadArea, new Bgr(Color.Blue), 2); con.Draw(cacheItem.Model.RightCheek.GetBoundingBox(), new Bgr(Color.Red), 2); con.Draw(cacheItem.Model.LeftCheek.GetBoundingBox(), new Bgr(Color.Red), 2); return(con.Bitmap); }
private void button2_Click(object sender, EventArgs e) { int fileId = Directory.GetFiles(Constants.PERSIST_PATH, "*", SearchOption.TopDirectoryOnly).Length; string contents = File.ReadAllText(Constants.PERSIST_PATH + (fileId - 1) + ".json"); mkParams = Newtonsoft.Json.JsonConvert.DeserializeObject <MKParams>(contents); Remakup(); }
public static void test() { Image <Bgr, Byte> image; Image <Gray, byte> grayImage; Image <Bgr, Byte> mainColorImage; Image <Gray, byte> mainGrayImage; FaceModel faceModel; MKParams mkParams = new MKParams(); InitModel(); DirectoryInfo d = new DirectoryInfo(@"D:\Face\Data_Collection\Data_Collection"); FileInfo[] Files = d.GetFiles("*.jpg"); foreach (FileInfo file in Files) { image = new Image <Bgr, byte>(file.FullName); mainColorImage = image.Clone(); grayImage = image.Convert <Gray, byte>(); mainGrayImage = grayImage.Clone(); faceModel = GetFaceModel(image, grayImage); #region Face Skin Bgr from = new Bgr(), to = new Bgr(); GetColorRange(new FourPoint[] { faceModel.RightCheek, faceModel.LeftCheek, faceModel.ChainArea }, image, out from, out to); Image <Bgr, Double> con = image.Convert <Bgr, Double>(); image.ROI = faceModel.HeadArea; Image <Gray, byte> headColorMask = image.InRange(from, to); image.ROI = Rectangle.Empty; Image <Gray, byte> skinMask = new Image <Gray, byte>(image.Width, image.Height, new Gray(0)); skinMask.ROI = faceModel.HeadArea; headColorMask.CopyTo(skinMask); skinMask.ROI = Rectangle.Empty; CvInvoke.DrawContours(skinMask, GetVVP(faceModel.FaceBoundry), -1, new Bgr(Color.White).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(faceModel.LeftEyePoints), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(faceModel.RightEyePoints), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(faceModel.LipBoundry), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); CvInvoke.DrawContours(skinMask, GetVVP(faceModel.NoseBottom), -1, new Bgr(Color.Black).MCvScalar, -1, LineType.EightConnected); Image <Bgr, Double> temp = new Image <Bgr, Double>(con.Width, con.Height, new Bgr(mkParams.SkinMaskColor)); con.AccumulateWeighted(temp, mkParams.FaceAlpha, skinMask); con.Draw(faceModel.HeadArea, new Bgr(Color.Blue), 2); con.Draw(faceModel.RightCheek.GetBoundingBox(), new Bgr(Color.Red), 2); con.Draw(faceModel.LeftCheek.GetBoundingBox(), new Bgr(Color.Red), 2); #endregion con.FillConvexPoly(faceModel.TopLipPoints, new Bgr(mkParams.LipStickColor)); con.FillConvexPoly(faceModel.BottomLipPoints, new Bgr(mkParams.LipStickColor)); DrawPoints(faceModel.TopLipPoints, con); DrawPoints(faceModel.BottomLipPoints, con); con.Save("d:\\skin.jpg"); } }
private void ApplyLipStick(Graphics g, FaceModel faceModel, MKParams mkParams) { Point[] bottomLipPoints = faceModel.BottomLipPoints; Point[] topLipPoints = faceModel.TopLipPoints; Point[] lipLineTop = faceModel.LipLineTop; Point[] lipLineBottom = faceModel.LipLineBottom; //SolidBrush lipLineBrush = new SolidBrush(Color.FromArgb(mkParams.LipLineAlpha, mkParams.LipLineColor)); //Pen lipLinePen = new Pen(lipLineBrush, 1); //g.DrawClosedCurve(lipLinePen, lipLineTop); //g.DrawClosedCurve(lipLinePen, lipLineBottom); SolidBrush lipStickBrush = new SolidBrush(Color.FromArgb(mkParams.LipStickAlpha, mkParams.LipStickColor)); g.FillClosedCurve(lipStickBrush, faceModel.TopLipPoints); g.FillClosedCurve(lipStickBrush, faceModel.BottomLipPoints); }
private void ApplyEyeLinear(Graphics g, FaceModel faceModel, MKParams mkParams) { SolidBrush eyeLineBrush = new SolidBrush(Color.FromArgb(mkParams.EyeLineAlpha, mkParams.EyeLineColor)); Pen eyeLinePen = new Pen(eyeLineBrush, 4); g.DrawCurve(eyeLinePen, faceModel.LeftEyePoints); double leftSlope = faceModel.LeftEyeSlope; double rightSlope = faceModel.RightEyeSlope; leftSlope = leftSlope * mkParams.EyeLineSlope; rightSlope = rightSlope * mkParams.EyeLineSlope; int deltaX = (int)((faceModel.LeftEyeTopPoint.X - faceModel.LeftEyeAnglePoint.X) / 2.5); int deltaY = (int)(leftSlope * deltaX); Point leftPoint = new Point((int)faceModel.LeftEyeAnglePoint.X - deltaX, (int)faceModel.LeftEyeAnglePoint.Y + deltaY); g.DrawLine(eyeLinePen, faceModel.LeftEyeAnglePoint, leftPoint); deltaY = (int)(rightSlope * deltaX); Point rightPoint = new Point((int)faceModel.RightEyeAnglePoint.X + deltaX, (int)faceModel.RightEyeAnglePoint.Y + deltaY); g.DrawLine(eyeLinePen, faceModel.RightEyeAnglePoint, rightPoint); g.DrawCurve(eyeLinePen, faceModel.RightEyePoints); }
private void Makeup(Image <Bgr, Byte> image, Image <Gray, byte> grayImage, FaceModel faceModel, MKParams mkParams) { Graphics g = Graphics.FromImage(image.Bitmap); if (mkParams.SkinEnabled || mkParams.HairEnabled) { ProcessSkin(g, grayImage, image, faceModel, mkParams); } if (mkParams.LipEnabled) { ApplyLipStick(g, faceModel, mkParams); } if (mkParams.EyeLineEnabled) { ApplyEyeLinear(g, faceModel, mkParams); } if (mkParams.EyebrowEnabled) { EyeBrowEffects(g, grayImage, image, faceModel, mkParams); } if (mkParams.EyeEnabled) { ColorEyes(g, grayImage, image, faceModel, mkParams); } }
private Bitmap ColorEyebrow(Rectangle box, Bitmap image, bool right, Image <Gray, byte> grayImage, MKParams mkParams) { grayImage.ROI = box; Image <Gray, byte> cropped = grayImage.Copy(); grayImage.ROI = Rectangle.Empty; double[] minValues; double[] maxValues; Point[] minLocs; Point[] maxLocs; cropped.MinMax(out minValues, out maxValues, out minLocs, out maxLocs); CvInvoke.Threshold(cropped, cropped, (minValues[0] + maxValues[0]) / 2, 255, Emgu.CV.CvEnum.ThresholdType.Binary); for (int i = box.Bottom + (int)(1 * box.Height); i >= box.Top - (0.1 * box.Height); i--) { for (int j = box.Right; j >= box.Left; j--) { int x = j - box.Left; int y = i - box.Top; bool inBounds = x >= 0 && x < cropped.Bitmap.Width; inBounds = inBounds && (y >= 0 && y < cropped.Bitmap.Height); if (inBounds && cropped.Bitmap.GetPixel(x, y).R == 0) { Color oldColor = image.GetPixel(j, i); int oldRed = oldColor.R; int oldGreen = oldColor.G; int oldBlue = oldColor.B; //Color maskColor = image.GetPixel(j, i - 2 * box.Height / 3); Color maskColor = mkParams.EyebrowMaskColor; int maskRed = maskColor.R; int maskGreen = maskColor.G; int maskBlue = maskColor.B; int newRed = (int)(mkParams.EyebrowAlpha * maskRed + (1 - mkParams.EyebrowAlpha) * oldRed); int newGreen = (int)(mkParams.EyebrowAlpha * maskGreen + (1 - mkParams.EyebrowAlpha) * oldGreen); int newBlue = (int)(mkParams.EyebrowAlpha * maskBlue + (1 - mkParams.EyebrowAlpha) * oldBlue); Color newColor = Color.FromArgb(newRed, newGreen, newBlue); image.SetPixel(j, i, newColor); } } } return(image); }
private void EyeBrowEffects(Graphics g, Image <Gray, byte> grayImage, Image <Bgr, Byte> image, FaceModel faceModel, MKParams mkParams) { ColorEyebrow(faceModel.RightEyebrowBox, image.Bitmap, true, grayImage, mkParams); ColorEyebrow(faceModel.LeftEyebrowBox, image.Bitmap, false, grayImage, mkParams); }
private void ColorEyes(Graphics g, Image <Gray, byte> grayImage, Image <Bgr, Byte> image, FaceModel faceModel, MKParams mkParams) { grayImage.ROI = faceModel.LeftEyeBox; CircleF[] leftEye = CvInvoke.HoughCircles(grayImage, HoughType.Gradient, 1, (double)faceModel.LeftEyeBox.Height / 5.0, 10, (double)faceModel.LeftEyeBox.Height / 5.0, faceModel.LeftEyeBox.Height); grayImage.ROI = faceModel.RightEyeBox; CircleF[] rightEye = CvInvoke.HoughCircles(grayImage, HoughType.Gradient, 1, (double)faceModel.RightEyeBox.Height / 5.0, 10, (double)faceModel.RightEyeBox.Height / 5.0, faceModel.RightEyeBox.Height); grayImage.ROI = Rectangle.Empty; SolidBrush solidBrush = new SolidBrush(Color.FromArgb(mkParams.EyeAlpha, mkParams.EyeMaskColor)); if (leftEye.Length > 0) { g.FillEllipse(solidBrush, faceModel.LeftEyeBox.Left + leftEye[0].Center.X - leftEye[0].Radius / 2, faceModel.LeftEyeBox.Top + leftEye[0].Center.Y - leftEye[0].Radius / 2, leftEye[0].Radius, leftEye[0].Radius); } if (rightEye.Length > 0) { g.FillEllipse(solidBrush, faceModel.RightEyeBox.Left + rightEye[0].Center.X - rightEye[0].Radius / 2, faceModel.RightEyeBox.Top + rightEye[0].Center.Y - rightEye[0].Radius / 2, rightEye[0].Radius, rightEye[0].Radius); } }
private Image <Gray, byte> ProcessSkin(Graphics g, Image <Gray, byte> grayImage, Image <Bgr, Byte> image, FaceModel faceModel, MKParams mkParams) { double[] minValues; double[] maxValues; Point[] minLocs; Point[] maxLocs; //int hairY = faceModel.HeadBox.Y - faceModel.HeadBox.Height / 2 + faceModel.HeadBox.Height / 4; //Rectangle hairBox = new Rectangle(faceModel.HeadBox.X + faceModel.HeadBox.Width / 2, hairY > 0 ? hairY : 0, faceModel.HeadBox.Width / 2, faceModel.HeadBox.Height / 2); image.ROI = new Rectangle(faceModel.FaceBox.X + faceModel.FaceBox.Width / 2, faceModel.FaceBox.Y + faceModel.FaceBox.Height / 4, faceModel.FaceBox.Width / 2, faceModel.FaceBox.Height / 2); image.MinMax(out minValues, out maxValues, out minLocs, out maxLocs); image.ROI = Rectangle.Empty; double avg0 = (minValues[0] + maxValues[0]) * mkParams.SkinRatio; double avg1 = (minValues[0] + maxValues[0]) * mkParams.SkinRatio; double avg2 = (minValues[0] + maxValues[0]) * mkParams.SkinRatio; Image <Gray, byte> skinMask = image.InRange(new Bgr(minValues[0], minValues[1], minValues[2]), new Bgr(avg0, avg1, avg2)); for (int i = faceModel.FaceBox.Bottom - 1; i >= faceModel.FaceBox.Top; i--) { for (int j = faceModel.FaceBox.Right - 1; j >= faceModel.FaceBox.Left; j--) { Color oldColor = image.Bitmap.GetPixel(j, i); int oldRed = oldColor.R; int oldGreen = oldColor.G; int oldBlue = oldColor.B; bool inFace = isInBox(i, j, faceModel.FaceBox); if (skinMask[i, j].MCvScalar.V0 == 0 && inFace && mkParams.SkinEnabled) { Color maskColor = mkParams.SkinMaskColor; int maskRed = maskColor.R; int maskGreen = maskColor.G; int maskBlue = maskColor.B; int newRed = (int)(mkParams.FaceAlpha * maskRed + (1 - mkParams.FaceAlpha) * oldRed); int newGreen = (int)(mkParams.FaceAlpha * maskGreen + (1 - mkParams.FaceAlpha) * oldGreen); int newBlue = (int)(mkParams.FaceAlpha * maskBlue + (1 - mkParams.FaceAlpha) * oldBlue); Color newColor = Color.FromArgb(newRed, newGreen, newBlue); image.Bitmap.SetPixel(j, i, newColor); } } } return(skinMask); }