private Byte GetBumpMapPixel(FastBitmap bmp, Int32 x, Int32 y) { // create a single number from R, G and B values at point (x, y) // if point (x, y) lays outside the bitmap, GetBumpMapPixel() // returns the closest pixel within the bitmap if (x < 0) { x = 0; } if (x > _bitmap.Width - 1) { x = _bitmap.Width - 1; } if (y < 0) { y = 0; } if (y > _bitmap.Height - 1) { y = _bitmap.Height - 1; } return(bmp.GetIntensity(x, y)); }
private unsafe CvPoint2D32f GetBestTrackingForEye(FastBitmap sobel, EyeData eyeData, int eyebrowWidth) { const float HeightMultiplier = 0.5f; const float YIncrease = 0.7f; const float WidthMultiplier = 0.5f; float bestScore = float.NegativeInfinity; CvPoint2D32f bestPoint = new CvPoint2D32f(); Rectangle searchArea = new Rectangle(eyeData.boundingBox.X + (int)((eyeData.boundingBox.Width / 2) - (WidthMultiplier * eyebrowWidth / 2)), (int)(eyeData.boundingBox.Y - (eyebrowWidth * YIncrease)), (int)(eyebrowWidth * WidthMultiplier), (int)(eyebrowWidth * HeightMultiplier)); for (int x = searchArea.Left; x < searchArea.Right; ++x) { for (int y = searchArea.Top; y < searchArea.Bottom; ++y) { float score = 0; for (int i = 0; i < TrackingPointWidth; ++i) { for (int j = 0; j < TrackingPointWidth; ++j) { score += sobel.GetIntensity(x + i, y + j); } } if (score > bestScore) { bestScore = score; bestPoint = new CvPoint2D32f(x, y); } } } return(bestPoint); }
private void GetTrackingPoints(FastBitmap img, EyeData leftEye, EyeData rightEye) { const int YDownShift = 30; const int XExpand = 5; const float eyebrowMult = 0.6f; int eyebrowWidth = (int)Math.Abs((leftEye.loc.X - rightEye.loc.X) * eyebrowMult); Rectangle searchArea = new Rectangle(); FastBitmap smoothed = img.GaussianSmooth(5); FastBitmap sobel = smoothed.SobelGradient(); smoothed.Dispose(); searchArea.Y = Math.Max(leftEye.loc.Y, rightEye.loc.Y) + YDownShift; searchArea.X = leftEye.loc.X - XExpand; searchArea.Width = rightEye.loc.X - leftEye.loc.X + (2 * XExpand); searchArea.Height = (int)((rightEye.loc.X - leftEye.loc.X) * 0.6f); float[,] trackingPointScores = new float[searchArea.Width, searchArea.Height]; for (int x = searchArea.Left; x < searchArea.Right; ++x) { for (int y = searchArea.Top; y < searchArea.Bottom; ++y) { float score = 0; for (int i = 0; i < TrackingPointWidth; ++i) { for (int j = 0; j < TrackingPointWidth; ++j) { score += sobel.GetIntensity(x + i, y + j); } } trackingPointScores[x - searchArea.Left, y - searchArea.Top] = score; } } mouseTrackingPoint = GetBestTrackingPointWithinColumn(trackingPointScores, searchArea, (leftEye.loc.X + rightEye.loc.X) / 2); leftEyeTrackingPoint = GetBestTrackingForEye(sobel, leftEye, eyebrowWidth); rightEyeTrackingPoint = GetBestTrackingForEye(sobel, rightEye, eyebrowWidth); sobel.Dispose(); }
private Byte GetBumpMapPixel(FastBitmap bmp, Int32 x, Int32 y) { if (x < 0) { x = 0; } if (x > _bitmap.Width - 1) { x = _bitmap.Width - 1; } if (y < 0) { y = 0; } if (y > _bitmap.Height - 1) { y = _bitmap.Height - 1; } return(bmp.GetIntensity(x, y)); }
private Byte GetBumpMapPixel(FastBitmap bmp, Int32 x, Int32 y) { // create a single number from R, G and B values at point (x, y) // if point (x, y) lays outside the bitmap, GetBumpMapPixel() // returns the closest pixel within the bitmap if (x < 0) x = 0; if (x > _bitmap.Width - 1) x = _bitmap.Width - 1; if (y < 0) y = 0; if (y > _bitmap.Height - 1) y = _bitmap.Height - 1; return bmp.GetIntensity(x, y); }
/* private static unsafe bool FindEyesFromDifferenceImage(FastBitmap img, FastBitmap differenceImage, out EyeData leftEye, out EyeData rightEye) * { * leftEye = null; * rightEye = null; * * try * { * const int DistanceBetweenLabels = 40; * const float MinimumNcc = 0.7f; * FastBitmap.ConnectedComponentsResults ccResults = differenceImage.FindConnectedComponents(100, 2, 10); * * * if( ccResults.NumberOfComponents >= 2 ) * { * int largestLabel = -1; * float largestLabelSize = -1; * int secondLargestLabel = -1; * float secondLargestLabelSize = -1; * * for( int i = 0; i < ccResults.NumberOfComponents; ++i ) * { * if( ccResults.Sizes[i] > largestLabelSize ) * { * largestLabelSize = ccResults.Sizes[i]; * largestLabel = i; * } * } * * * if( largestLabelSize > 600 ) * { * return false; * } * * for( int i = 0; i < ccResults.NumberOfComponents; ++i ) * { * if( ccResults.Sizes[i] > secondLargestLabelSize ) * { * int xDiff = ccResults.Centers[largestLabel].X - ccResults.Centers[i].X; * int yDiff = ccResults.Centers[largestLabel].Y - ccResults.Centers[i].Y; * * float distance = (float)Math.Sqrt(xDiff * xDiff + yDiff * yDiff); * * if( distance > DistanceBetweenLabels ) * { * secondLargestLabelSize = ccResults.Sizes[i]; * secondLargestLabel = i; * } * } * } * * if( secondLargestLabel == -1 ) * { * return false; * } * * * if( ccResults.BoundingBoxes[largestLabel].Height > ccResults.BoundingBoxes[largestLabel].Width ) * { * return false; * } * * if( ccResults.BoundingBoxes[secondLargestLabel].Height > ccResults.BoundingBoxes[secondLargestLabel].Width ) * { * return false; * } * * float FinalXDiff = Math.Abs(ccResults.Centers[largestLabel].X - ccResults.Centers[secondLargestLabel].X); * float FinalYDiff = Math.Abs(ccResults.Centers[largestLabel].Y - ccResults.Centers[secondLargestLabel].Y); * * if( FinalYDiff > 40 ) * { * return false; * } * if( (FinalYDiff / FinalXDiff) > 0.5 ) * { * return false; * } * * float ncc = HorizontalFlipNccTemplateMatch(img, ccResults.Centers[largestLabel], ccResults.Centers[secondLargestLabel]); * * if( ncc < MinimumNcc ) * { * return false; * } * * EyeData tempOne = new EyeData(ccResults.Centers[largestLabel], * ccResults.BoundingBoxes[largestLabel]); * * EyeData tempTwo = new EyeData(ccResults.Centers[secondLargestLabel], * ccResults.BoundingBoxes[secondLargestLabel]); * * if( tempOne.loc.X < tempTwo.loc.X ) * { * leftEye = tempOne; * rightEye = tempTwo; * } * else * { * leftEye = tempTwo; * rightEye = tempOne; * } * * return true; * } * else * { * return false; * } * } * catch( ArgumentOutOfRangeException ) * { * return false; * } * } */ // Makes the template from pOne tries to match it to pTwo private static float HorizontalFlipNccTemplateMatch(FastBitmap img, Point pOne, Point pTwo) { const int TemplateWidth = 31; const int HalfTemplateWidth = (TemplateWidth - 1) / 2; const int TemplateHeight = 21; const int HalfTemplateHeight = (TemplateHeight - 1) / 2; const int SearchWidth = 31; const int HalfSearchWidth = (SearchWidth - 1) / 2; float[,] template = new float[TemplateWidth, TemplateHeight]; float templateMean = 0; float templateSigma = 0; float bestNcc = 0; for (int x = 0; x < TemplateWidth; ++x) { for (int y = 0; y < TemplateHeight; ++y) { template[TemplateWidth - x - 1, y] = img.GetIntensity(pOne.X - HalfTemplateWidth + x, pOne.Y - HalfTemplateHeight + y); templateMean += template[TemplateWidth - x - 1, y]; } } templateMean /= (TemplateWidth * TemplateHeight); for (int x = 0; x < TemplateWidth; ++x) { for (int y = 0; y < TemplateHeight; ++y) { float diff = template[x, y] - templateMean; templateSigma += (diff * diff); } } templateSigma = (float)Math.Sqrt(templateSigma / (TemplateWidth * TemplateHeight)); for (int x = pTwo.X - HalfSearchWidth; x <= pTwo.X + HalfSearchWidth; ++x) { for (int y = pTwo.Y - HalfSearchWidth; y <= pTwo.Y + HalfSearchWidth; ++y) { float mean = 0; float sigma = 0; float ncc = 0; for (int i = 0; i < TemplateWidth; ++i) { for (int j = 0; j < TemplateHeight; ++j) { mean += img.GetIntensity(x - HalfTemplateWidth + i, y - HalfTemplateHeight + j); } } mean /= (TemplateWidth * TemplateHeight); for (int i = 0; i < TemplateWidth; ++i) { for (int j = 0; j < TemplateHeight; ++j) { float diff = img.GetIntensity(x - HalfTemplateWidth + i, y - HalfTemplateHeight + j) - mean; sigma += (diff * diff); } } sigma = (float)Math.Sqrt(sigma / (TemplateWidth * TemplateHeight)); // r = 1/n Σ_i (((s_i - mean(s)) * (m_i- mean(m))) / (σ_s σ_m) for (int i = 0; i < TemplateWidth; ++i) { for (int j = 0; j < TemplateHeight; ++j) { ncc += (mean - img.GetIntensity(x - HalfTemplateWidth + i, y - HalfTemplateHeight + j)) * (templateMean - template[i, j]); } } ncc = Math.Abs(ncc / (TemplateWidth * TemplateHeight * sigma * templateSigma)); if (ncc > bestNcc) { bestNcc = ncc; } } } return(bestNcc); }