/// <summary> /// Rotate eyes in raw co-ords. First normalize then rotate then nunormalize /// </summary> /// <param name="eye"></param> /// <param name="faceRect"></param> /// <param name="trans"></param> /// <returns></returns> static private Point RotateRawEye(System.Windows.Point eye, Rect faceRect, TransformSample trans) { Point point = FaceFeatureToScaledPoint(eye, faceRect); point = RotateEye(point, trans); return(ScalePointToFaceFeature(point, faceRect)); }
static private Point RotateEye(System.Windows.Point eye, TransformSample trans) { double theta = trans.ThetaRad; System.Windows.Point newCentre = new System.Windows.Point(); newCentre.X = (eye.X - 0.5) * Math.Cos(theta) - (0.5 - eye.Y) * Math.Sin(theta) + 0.5 - trans.X; newCentre.Y = 0.5 - ((0.5 - eye.Y) * Math.Cos(theta) + (eye.X - 0.5) * Math.Sin(theta)) - trans.Y; return(newCentre); }
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))); }
/// <summary> /// Select a transformed FacePatch from current image /// Amount of rotation specified in degrees /// </summary> /// <param name="dataPixs">Byte data from current image</param> /// <param name="faceRect">Where the faceRect is in the the image</param> /// <param name="theta">Amount to rotate (degrees)</param> /// <returns></returns> static private byte[] SelectTransformPatch(byte[] dataPixs, Rect faceRect, TransformSample trans) { int bytePerPixel = _bitmap.Format.BitsPerPixel / 8; int dataStride = _bitmap.PixelWidth * bytePerPixel; Rect sourceRect = new Rect(0, 0, _bitmap.PixelWidth, _bitmap.PixelHeight); Rect destRect = new Rect(0, 0, _faceDisplayWidth, _faceDisplayHeight); int destStride = (int)destRect.Width * bytePerPixel; byte[] facePixs = TransformSample.ExtractTransformNormalizeFace(dataPixs, sourceRect, bytePerPixel, dataStride, faceRect, destRect, destStride, trans); return(facePixs); }
static public byte[] ExtractTransformNormalizeFace(byte[] origImage, Rect origRect, int bytePerPix, int origStride, Rect mapFrom, Rect faceRect, int faceStride, TransformSample trans) { // Sanity check eye location double[,] affineMat = new double[2, 3]; double scaleX = mapFrom.Width / faceRect.Width; double scaleY = mapFrom.Height / faceRect.Height; double theta = trans.ThetaRad; affineMat[0, 0] = scaleX * Math.Cos(theta); affineMat[0, 1] = -scaleY *Math.Sin(theta); affineMat[0, 2] = trans.Xpix; affineMat[1, 0] = scaleX * Math.Sin(theta); affineMat[1, 1] = scaleY * Math.Cos(theta); affineMat[1, 2] = trans.Ypix; // Use the Image library routines. These operate 1 channel at a time Image[] outImage = new Image[bytePerPix]; double srcCentreX = mapFrom.X + mapFrom.Width / 2.0; double srcCentreY = mapFrom.Y + mapFrom.Height / 2.0; for (int iChannel = 0; iChannel < bytePerPix; ++iChannel) { Image inChannel = new Image(origImage, iChannel, (int)origRect.Width, (int)origRect.Height, bytePerPix, origStride); outImage[iChannel] = new Image((int)faceRect.Width, (int)faceRect.Height); //Image.AffineTransPad(inChannel, outImage[iChannel], affineMat); Image.AffineTransPadProvideCenter(inChannel, srcCentreX, srcCentreY, outImage[iChannel], affineMat); } byte[] faceBuffer = new byte[faceStride * (int)faceRect.Height]; for (int row = 0; row < faceRect.Height; ++row) { int rowOffSet = row * faceStride; for (int iChannel = 0; iChannel < bytePerPix; ++iChannel) { int iPix = row * (int)faceRect.Width; int col = rowOffSet + iChannel; for (int iCol = 0; iCol < faceRect.Width; ++iCol, col += bytePerPix) { faceBuffer[col] = (byte)Math.Min(Byte.MaxValue, outImage[iChannel].Pixels[iPix++]); } } } return(faceBuffer); }
static public byte[] ExtractTransformNormalizeFace(byte[] origImage, Rect origRect, int bytePerPix, int origStride, Rect mapFrom, Rect faceRect, int faceStride, TransformSample trans) { // Sanity check eye location double[,] affineMat = new double[2, 3]; double scaleX = mapFrom.Width / faceRect.Width; double scaleY = mapFrom.Height / faceRect.Height; double theta = trans.ThetaRad; affineMat[0, 0] = scaleX * Math.Cos(theta); affineMat[0, 1] = -scaleY *Math.Sin(theta); affineMat[0, 2] = trans.Xpix; affineMat[1, 0] = scaleX * Math.Sin(theta); affineMat[1, 1] = scaleY * Math.Cos(theta); affineMat[1, 2] = trans.Ypix; return(DoTransform(origImage, origRect, bytePerPix, origStride, mapFrom, faceRect, faceStride, affineMat)); }