public override bool Track(List <AbstractTrackPoint> _previousPoints, Bitmap _CurrentImage, long _t, out AbstractTrackPoint _currentPoint) { //--------------------------------------------------------------------- // The input informations we have at hand are: // - The current bitmap we have to find the point into. // - The coordinates of all the previous points tracked. // - Previous tracking infos, stored in the TrackPoints tracked so far. //--------------------------------------------------------------------- bool bMatched = false; TrackPointSURF lastTrackPoint = (TrackPointSURF)_previousPoints[_previousPoints.Count - 1]; // Create a point centered on last match. // This will find and register all the SURF features located in the search zone. // Test with grayscale image. Bitmap grayCurrentImage = Grayscale.CommonAlgorithms.BT709.Apply(_CurrentImage); _currentPoint = CreateTrackPoint(false, lastTrackPoint.X, lastTrackPoint.Y, 1.0f, _t, grayCurrentImage, _previousPoints); if (_currentPoint == null) { // Untrackable area. } else { if (((TrackPointSURF)_currentPoint).FoundFeatures.Count > 0) { // Feature matching. // Look for the nearest neighbour to the previous match, in the list of newly found features. Match m = null; COpenSURF.MatchPoint(lastTrackPoint.MatchedFeature, ((TrackPointSURF)_currentPoint).FoundFeatures, out m); // Also look for a match of the first feature, to compensate for occlusion and drift). Match m2 = null; TrackPointSURF firstTrackPoint = (TrackPointSURF)_previousPoints[0]; COpenSURF.MatchPoint(firstTrackPoint.MatchedFeature, ((TrackPointSURF)_currentPoint).FoundFeatures, out m2); // Take the best match out of the two. Match matchedFeature = (m.Distance2 < m2.Distance2) ? m : m2; // TODO: // check if distance (match similarity) is over a given threshold. // 3. Store the new matched feature with associated data. ((TrackPointSURF)_currentPoint).MatchedFeature = matchedFeature.Ipt2; _currentPoint.X = ((TrackPointSURF)_currentPoint).SearchWindow.X + (int)matchedFeature.Ipt2.x; _currentPoint.Y = ((TrackPointSURF)_currentPoint).SearchWindow.Y + (int)matchedFeature.Ipt2.y; log.Debug(String.Format("Tracking result: [{0};{1}]", _currentPoint.X, _currentPoint.Y)); bMatched = true; } if (m_bMonitoring) { log.Debug(_currentPoint.ToString()); } // Problems: // The user did not choose a feature, so we have extra work to do to keep the correspondance between // the feature saved in the track point and the actual coordinates the user is looking for. // Currently we just discard the user's point entirely and try to track the closest feature. } return(bMatched); }
public override AbstractTrackPoint CreateTrackPoint(bool _manual, int _x, int _y, double _fSimilarity, long _t, Bitmap _CurrentImage, List <AbstractTrackPoint> _previousPoints) { // Creates a TrackPoint from the input image at the given coordinates. // Find features in the search window. // Scale-space image of the search window. int searchLeft = _x - (m_SearchWindowSize.Width / 2); int searchTop = _y - (m_SearchWindowSize.Height / 2); Rectangle searchZone = new Rectangle(searchLeft, searchTop, m_SearchWindowSize.Width, m_SearchWindowSize.Height); Bitmap searchImage = new Bitmap(m_SearchWindowSize.Width, m_SearchWindowSize.Height, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(searchImage); Rectangle rDst = new Rectangle(0, 0, m_SearchWindowSize.Width, m_SearchWindowSize.Height); g.DrawImage(_CurrentImage, rDst, searchZone, GraphicsUnit.Pixel); //g.Dispose(); IplImage pIplImage = IplImage.LoadImage(searchImage); pIplImage = pIplImage.BuildIntegral(null); List <Ipoint> ipts = new List <Ipoint>(); CFastHessian pCFastHessian = new CFastHessian(pIplImage, ref ipts, m_iOctaves, m_iIntervals, m_iInitSample, m_fThreshold, m_iInterpolationSteps); // Fill the scale-space image with actual data and finds the local extrema. pCFastHessian.getIpoints(); // Fill the descriptor field, orientation and laplacian of the feature. Surf pSurf = new Surf(pIplImage, ipts); pSurf.getDescriptors(m_bUpright); // Save algorithm-related data in the point. TrackPointSURF tps = new TrackPointSURF(_x, _y, _t); tps.FoundFeatures = ipts; tps.SearchWindow = new Point(searchLeft, searchTop); if (_previousPoints.Count == 0 || _manual) { // Find the closest point from the user's point. int iClosest = -1; double fBestDistance = double.MaxValue; if (ipts.Count > 0) { Point userPoint = new Point(_x, _y); for (int i = 0; i < ipts.Count; i++) { double fDistance = CalibrationHelper.PixelDistance(new PointF((float)_x, (float)_y), new PointF(ipts[i].x + searchLeft, ipts[i].y + searchTop)); if (fDistance < fBestDistance) { fBestDistance = fDistance; iClosest = i; } } tps.MatchedFeature = tps.FoundFeatures[iClosest]; tps.X = (int)(tps.MatchedFeature.x + searchLeft); tps.Y = (int)(tps.MatchedFeature.y + searchTop); log.Debug(String.Format("Initializing of the tracking. Closest feature to user's point : {0:0.00}", fBestDistance)); log.Debug(String.Format("Tracking result (init): [{0};{1}], user selection was: [{2};{3}]", tps.X, tps.Y, _x, _y)); } else { // Ouch! The point selected by the user is in a no-feature zone. tps = null; log.Debug(String.Format("Tracking impossible from this point. Selected point is in No-feature zone.")); } } return(tps); }