public bool testSURF(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage) { bool isFound = false; HomographyMatrix homography = null; SURFDetector surfCPU = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f); using (GpuImage<Gray, Byte> gpuModelImage = new GpuImage<Gray, byte>(modelImage)) //extract features from the object image using (GpuMat<float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null)) using (GpuMat<float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) using (GpuBruteForceMatcher<float> matcher = new GpuBruteForceMatcher<float>(DistanceType.L2)) { modelKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); //watch = Stopwatch.StartNew(); // extract features from the observed image using (GpuImage<Gray, Byte> gpuObservedImage = new GpuImage<Gray, byte>(observedImage)) using (GpuMat<float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null)) using (GpuMat<float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints)) using (GpuMat<int> gpuMatchIndices = new GpuMat<int>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat<float> gpuMatchDist = new GpuMat<float>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat<Byte> gpuMask = new GpuMat<byte>(gpuMatchIndices.Size.Height, 1, 1)) using (Emgu.CV.GPU.Stream stream = new Emgu.CV.GPU.Stream()) { matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream); indices = new Matrix<int>(gpuMatchIndices.Size); mask = new Matrix<byte>(gpuMask.Size); //gpu implementation of voteForUniquess using (GpuMat<float> col0 = gpuMatchDist.Col(0)) using (GpuMat<float> col1 = gpuMatchDist.Col(1)) { GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream); GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream); } observedKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); gpuMask.Download(mask); gpuMatchIndices.Download(indices); if (GpuInvoke.CountNonZero(gpuMask) >= 4) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } } } //Draw the matched keypoints Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #region draw the projected region on the image if (homography != null) { //draw a rectangle along the projected model Rectangle rect = modelImage.ROI; PointF[] pts = new PointF[] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top)}; homography.ProjectPoints(pts); if (CvInvoke.cvCountNonZero(mask) >= 10) isFound = true; result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.LightGreen), 5); } #endregion return isFound; }
public Image <Bgr, Byte> /*void*/ Draw(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, out long matchTime) { Stopwatch watch; HomographyMatrix homography = null; SURFDetector surfCPU = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix <int> indices; Matrix <byte> mask; int k = 2; double uniquenessThreshold = 0.8; if (GpuInvoke.HasCuda) { GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f); using (GpuImage <Gray, Byte> gpuModelImage = new GpuImage <Gray, byte>(modelImage)) //extract features from the object image using (GpuMat <float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null)) using (GpuMat <float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) using (GpuBruteForceMatcher <float> matcher = new GpuBruteForceMatcher <float>(DistanceType.L2)) { modelKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); watch = Stopwatch.StartNew(); // extract features from the observed image using (GpuImage <Gray, Byte> gpuObservedImage = new GpuImage <Gray, byte>(observedImage)) using (GpuMat <float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null)) using (GpuMat <float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints)) using (GpuMat <int> gpuMatchIndices = new GpuMat <int>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <float> gpuMatchDist = new GpuMat <float>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <Byte> gpuMask = new GpuMat <byte>(gpuMatchIndices.Size.Height, 1, 1)) using (Emgu.CV.GPU.Stream stream = new Emgu.CV.GPU.Stream()) { matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream); indices = new Matrix <int>(gpuMatchIndices.Size); mask = new Matrix <byte>(gpuMask.Size); //gpu implementation of voteForUniquess using (GpuMat <float> col0 = gpuMatchDist.Col(0)) using (GpuMat <float> col1 = gpuMatchDist.Col(1)) { GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream); GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream); } observedKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); gpuMask.Download(mask); gpuMatchIndices.Download(indices); if (GpuInvoke.CountNonZero(gpuMask) >= 4) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } } watch.Stop(); } } } else { //extract features from the object image modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null); Matrix <float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); watch = Stopwatch.StartNew(); // extract features from the observed image observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null); Matrix <float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher <float> matcher = new BruteForceMatcher <float>(DistanceType.L2); matcher.Add(modelDescriptors); indices = new Matrix <int>(observedDescriptors.Rows, k); using (Matrix <float> dist = new Matrix <float>(observedDescriptors.Rows, k)) { matcher.KnnMatch(observedDescriptors, indices, dist, k, null); mask = new Matrix <byte>(dist.Rows, 1); mask.SetValue(255); Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); } nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } } watch.Stop(); } //Draw the matched keypoints Image <Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #region draw the projected region on the image if (homography != null) { //draw a rectangle along the projected model Rectangle rect = modelImage.ROI; PointF[] pts = new PointF[] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top) }; homography.ProjectPoints(pts); for (int i = 0; i < pts.Length; i++) { //print("points are " + pts[i] + " width "+modelImage.Width+" modelImage.Height "+modelImage.Height); if (pts[i].X > modelImage.Width) { //print("not within"); pts[i].X = modelImage.Width; } else if (pts[i].X < 0) { //print("not within"); pts[i].X = 0; } if (pts[i].Y > modelImage.Width) { //print("not within"); pts[i].Y = modelImage.Height; } else if (pts[i].Y < 0) { //print("not within"); pts[i].Y = 0; } else { //print("within"); } } if (pts.Length > 0) { int a = (int)(pts[0].X * pts[1].Y + pts[1].X * pts[2].Y + pts[2].X * pts[3].Y + pts[3].X * pts[0].Y); int b = (int)(pts[1].X * pts[0].Y + pts[2].X * pts[1].Y + pts[3].X * pts[2].Y + pts[0].X * pts[3].Y); area = Math.Abs(a - b); } else { area = 0; } /** int width = rect.Right - rect.Left; * print("right is "+rect.Right +" left is "+rect.Left+" width is " + width); * int height = rect.Top - rect.Bottom; * print("top is " + rect.Top + " bottom is " + rect.Bottom + " height is " + height); **/ try { result.DrawPolyline(Array.ConvertAll <PointF, Point>(pts, Point.Round), true, new Bgr(System.Drawing.Color.Red), 5); }catch (OverflowException e) { } } else { area = 0; } #endregion matchTime = watch.ElapsedMilliseconds; return(result); }
public static bool FindModelImageInObservedImage( Image<Gray, byte> modelImage, Image<Gray, byte> observedImage ) { var surfCpu = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; if ( GpuInvoke.HasCuda ) { GpuSURFDetector surfGpu = new GpuSURFDetector(surfCpu.SURFParams, 0.01f); using ( GpuImage<Gray, byte> gpuModelImage = new GpuImage<Gray, byte>( modelImage ) ) //extract features from the object image using ( GpuMat<float> gpuModelKeyPoints = surfGpu.DetectKeyPointsRaw( gpuModelImage, null ) ) using ( GpuMat<float> gpuModelDescriptors = surfGpu.ComputeDescriptorsRaw( gpuModelImage, null, gpuModelKeyPoints ) ) using ( GpuBruteForceMatcher<float> matcher = new GpuBruteForceMatcher<float>( DistanceType.L2 ) ) { modelKeyPoints = new VectorOfKeyPoint(); surfGpu.DownloadKeypoints( gpuModelKeyPoints, modelKeyPoints ); // extract features from the observed image using ( GpuImage<Gray, byte> gpuObservedImage = new GpuImage<Gray, byte>( observedImage ) ) using ( GpuMat<float> gpuObservedKeyPoints = surfGpu.DetectKeyPointsRaw( gpuObservedImage, null ) ) using ( GpuMat<float> gpuObservedDescriptors = surfGpu.ComputeDescriptorsRaw( gpuObservedImage, null, gpuObservedKeyPoints ) ) using ( GpuMat<int> gpuMatchIndices = new GpuMat<int>( gpuObservedDescriptors.Size.Height, k, 1, true ) ) using ( GpuMat<float> gpuMatchDist = new GpuMat<float>( gpuObservedDescriptors.Size.Height, k, 1, true ) ) using ( GpuMat<Byte> gpuMask = new GpuMat<byte>( gpuMatchIndices.Size.Height, 1, 1 ) ) using ( var stream = new Emgu.CV.GPU.Stream() ) { matcher.KnnMatchSingle( gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream ); indices = new Matrix<int>( gpuMatchIndices.Size ); mask = new Matrix<byte>( gpuMask.Size ); //gpu implementation of voteForUniquess using ( GpuMat<float> col0 = gpuMatchDist.Col( 0 ) ) using ( GpuMat<float> col1 = gpuMatchDist.Col( 1 ) ) { GpuInvoke.Multiply( col1, new MCvScalar( uniquenessThreshold ), col1, stream ); GpuInvoke.Compare( col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream ); } observedKeyPoints = new VectorOfKeyPoint(); surfGpu.DownloadKeypoints( gpuObservedKeyPoints, observedKeyPoints ); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); gpuMask.Download( mask ); gpuMatchIndices.Download( indices ); if ( GpuInvoke.CountNonZero( gpuMask ) >= 4 ) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if ( nonZeroCount >= 4 ) { Features2DToolbox.GetHomographyMatrixFromMatchedFeatures( modelKeyPoints, observedKeyPoints, indices, mask, 2 ); } if ( (double)nonZeroCount / mask.Height > 0.02 ) { return true; } } } } } else { //extract features from the object image modelKeyPoints = surfCpu.DetectKeyPointsRaw( modelImage, null ); Matrix<float> modelDescriptors = surfCpu.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = surfCpu.DetectKeyPointsRaw( observedImage, null ); Matrix<float> observedDescriptors = surfCpu.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add( modelDescriptors ); indices = new Matrix<int>( observedDescriptors.Rows, k ); using ( Matrix<float> dist = new Matrix<float>( observedDescriptors.Rows, k ) ) { matcher.KnnMatch( observedDescriptors, indices, dist, k, null ); mask = new Matrix<byte>( dist.Rows, 1 ); mask.SetValue( 255 ); Features2DToolbox.VoteForUniqueness( dist, uniquenessThreshold, mask ); } int nonZeroCount = CvInvoke.cvCountNonZero(mask); if ( nonZeroCount >= 4 ) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation( modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20 ); if ( nonZeroCount >= 4 ) { Features2DToolbox.GetHomographyMatrixFromMatchedFeatures( modelKeyPoints, observedKeyPoints, indices, mask, 2 ); } } if ( (double)nonZeroCount/mask.Height > 0.02 ) { return true; } } //Draw the matched keypoints //var result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(0, 0, 255), new Bgr(255, 0, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT); //result.Save( @"C:\Users\D.Markachev\Desktop\bleh-keypoints.jpg" ); return false; }
public static Image <Bgr, Byte> SURF(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage) { bool isFound = false; long matchTime; Stopwatch watch; HomographyMatrix homography = null; SURFDetector surfCPU = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix <int> indices; Matrix <byte> mask; int k = 2; double uniquenessThreshold = 0.8; watch = Stopwatch.StartNew(); GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f); using (GpuImage <Gray, Byte> gpuModelImage = new GpuImage <Gray, byte>(modelImage)) //extract features from the object image using (GpuMat <float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null)) using (GpuMat <float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) using (GpuBruteForceMatcher <float> matcher = new GpuBruteForceMatcher <float>(DistanceType.L2)) { modelKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); //watch = Stopwatch.StartNew(); // extract features from the observed image using (GpuImage <Gray, Byte> gpuObservedImage = new GpuImage <Gray, byte>(observedImage)) using (GpuMat <float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null)) using (GpuMat <float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints)) using (GpuMat <int> gpuMatchIndices = new GpuMat <int>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <float> gpuMatchDist = new GpuMat <float>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <Byte> gpuMask = new GpuMat <byte>(gpuMatchIndices.Size.Height, 1, 1)) using (Emgu.CV.GPU.Stream stream = new Emgu.CV.GPU.Stream()) { matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream); indices = new Matrix <int>(gpuMatchIndices.Size); mask = new Matrix <byte>(gpuMask.Size); //gpu implementation of voteForUniquess using (GpuMat <float> col0 = gpuMatchDist.Col(0)) using (GpuMat <float> col1 = gpuMatchDist.Col(1)) { GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream); GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream); } observedKeyPoints = new VectorOfKeyPoint(); surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); gpuMask.Download(mask); gpuMatchIndices.Download(indices); if (GpuInvoke.CountNonZero(gpuMask) >= 4) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } } watch.Stop(); } } ////extract features from the object image //modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null); //Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); //// extract features from the observed image //observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null); //Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); //BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); //matcher.Add(modelDescriptors); //indices = new Matrix<int>(observedDescriptors.Rows, k); //using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k)) //{ // matcher.KnnMatch(observedDescriptors, indices, dist, k, null); // mask = new Matrix<byte>(dist.Rows, 1); // mask.SetValue(255); // Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); //} //int nonZeroCount = CvInvoke.cvCountNonZero(mask); //if (nonZeroCount >= 4) //{ // nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); // if (nonZeroCount >= 4) // homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); //} //watch.Stop(); //Draw the matched keypoints Image <Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #region draw the projected region on the image if (homography != null) { //draw a rectangle along the projected model Rectangle rect = modelImage.ROI; PointF[] pts = new PointF[] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top) }; homography.ProjectPoints(pts); if (CvInvoke.cvCountNonZero(mask) >= 10) { isFound = true; } result.DrawPolyline(Array.ConvertAll <PointF, Point>(pts, Point.Round), true, new Bgr(Color.LightGreen), 5); } #endregion matchTime = watch.ElapsedMilliseconds; _richTextBox1.Clear(); _richTextBox1.AppendText("objek ditemukan: " + isFound + "\n"); _richTextBox1.AppendText("waktu pendeteksian SURF: " + matchTime + "ms\n"); _richTextBox1.AppendText("fitur model yang terdeteksi: " + modelKeyPoints.Size + "\n"); _richTextBox1.AppendText("match yang ditemukan: " + CvInvoke.cvCountNonZero(mask).ToString()); return(result); }
public static bool FindModelImageInObservedImage(Image <Gray, byte> modelImage, Image <Gray, byte> observedImage) { var surfCpu = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix <int> indices; Matrix <byte> mask; int k = 2; double uniquenessThreshold = 0.8; if (GpuInvoke.HasCuda) { GpuSURFDetector surfGpu = new GpuSURFDetector(surfCpu.SURFParams, 0.01f); using (GpuImage <Gray, byte> gpuModelImage = new GpuImage <Gray, byte>(modelImage)) //extract features from the object image using (GpuMat <float> gpuModelKeyPoints = surfGpu.DetectKeyPointsRaw(gpuModelImage, null)) using (GpuMat <float> gpuModelDescriptors = surfGpu.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) using (GpuBruteForceMatcher <float> matcher = new GpuBruteForceMatcher <float>(DistanceType.L2)) { modelKeyPoints = new VectorOfKeyPoint(); surfGpu.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); // extract features from the observed image using (GpuImage <Gray, byte> gpuObservedImage = new GpuImage <Gray, byte>(observedImage)) using (GpuMat <float> gpuObservedKeyPoints = surfGpu.DetectKeyPointsRaw(gpuObservedImage, null)) using (GpuMat <float> gpuObservedDescriptors = surfGpu.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints)) using (GpuMat <int> gpuMatchIndices = new GpuMat <int>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <float> gpuMatchDist = new GpuMat <float>(gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <Byte> gpuMask = new GpuMat <byte>(gpuMatchIndices.Size.Height, 1, 1)) using (var stream = new Emgu.CV.GPU.Stream()) { matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream); indices = new Matrix <int>(gpuMatchIndices.Size); mask = new Matrix <byte>(gpuMask.Size); //gpu implementation of voteForUniquess using (GpuMat <float> col0 = gpuMatchDist.Col(0)) using (GpuMat <float> col1 = gpuMatchDist.Col(1)) { GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream); GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream); } observedKeyPoints = new VectorOfKeyPoint(); surfGpu.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); gpuMask.Download(mask); gpuMatchIndices.Download(indices); if (GpuInvoke.CountNonZero(gpuMask) >= 4) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } if ((double)nonZeroCount / mask.Height > 0.02) { return(true); } } } } } else { //extract features from the object image modelKeyPoints = surfCpu.DetectKeyPointsRaw(modelImage, null); Matrix <float> modelDescriptors = surfCpu.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = surfCpu.DetectKeyPointsRaw(observedImage, null); Matrix <float> observedDescriptors = surfCpu.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher <float> matcher = new BruteForceMatcher <float>(DistanceType.L2); matcher.Add(modelDescriptors); indices = new Matrix <int>(observedDescriptors.Rows, k); using (Matrix <float> dist = new Matrix <float>(observedDescriptors.Rows, k)) { matcher.KnnMatch(observedDescriptors, indices, dist, k, null); mask = new Matrix <byte>(dist.Rows, 1); mask.SetValue(255); Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); } int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } } if ((double)nonZeroCount / mask.Height > 0.02) { return(true); } } //Draw the matched keypoints //var result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(0, 0, 255), new Bgr(255, 0, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT); //result.Save( @"C:\Users\D.Markachev\Desktop\bleh-keypoints.jpg" ); return(false); }