/// <summary> /// Match the Image feature from the observed image to the features from the model image /// </summary> /// <param name="observedFeatures">The Image feature from the observed image</param> /// <param name="k">The number of neighbors to find</param> /// <returns>The matched features</returns> public MatchedImageFeature[] MatchFeature(ImageFeature[] observedFeatures, int k) { VectorOfKeyPoint obsKpts; Matrix <float> obsDscpts; ConvertFromImageFeature(observedFeatures, out obsKpts, out obsDscpts); using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) using (Matrix <int> indices = new Matrix <int>(obsKpts.Size, k)) using (Matrix <float> dists = new Matrix <float>(indices.Size)) { matcher.Add(_modelDescriptors); matcher.KnnMatch(obsDscpts, indices, dists, k, null); MatchedImageFeature[] result = new MatchedImageFeature[observedFeatures.Length]; for (int i = 0; i < observedFeatures.Length; i++) { result[i].SimilarFeatures = new SimilarFeature[k]; for (int j = 0; j < k; j++) { result[i].SimilarFeatures[j].Distance = dists.Data[i, j]; result[i].SimilarFeatures[j].Feature = _modelFeatures[indices.Data[i, j]]; } result[i].ObservedFeature = observedFeatures[i]; } obsKpts.Dispose(); obsDscpts.Dispose(); return(result); } }
/// <summary> /// Detect the if the model features exist in the observed features. If true, an homography matrix is returned, otherwise, null is returned. /// </summary> /// <param name="modelDescriptors">The descriptors from the model image</param> /// <param name="modelKeyPoints">The keypoints drom the model image</param> /// <param name="observedDescriptors">The descriptors from the descriptor image</param> /// <param name="observedKeyPoints">The keypoints from the observed image</param> /// <param name="uniquenessThreshold">The distance different ratio which a match is consider unique, a good number will be 0.8</param> /// <returns>If the model features exist in the observed features, an homography matrix is returned, otherwise, null is returned.</returns> public static HomographyMatrix Detect( VectorOfKeyPoint modelKeyPoints, Matrix <float> modelDescriptors, VectorOfKeyPoint observedKeyPoints, Matrix <float> observedDescriptors, double uniquenessThreshold) { using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) using (Matrix <int> indices = new Matrix <int>(observedKeyPoints.Size, 2)) using (Matrix <float> dist = new Matrix <float>(indices.Size)) using (Matrix <byte> mask = new Matrix <byte>(dist.Rows, 1)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, indices, dist, 2, null); mask.SetValue(255); //Stopwatch w1 = Stopwatch.StartNew(); VoteForUniqueness(dist, uniquenessThreshold, mask); //Trace.WriteLine(w1.ElapsedMilliseconds); int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount < 4) { return(null); } //Stopwatch w2 = Stopwatch.StartNew(); nonZeroCount = VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount < 4) { return(null); } return(GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 3)); } }
/// <summary> /// Match the Image feature from the observed image to the features from the model image, using brute force matcher /// </summary> /// <param name="observedFeatures">The Image feature from the observed image</param> /// <param name="k">The number of neighbors to find</param> /// <returns>The matched features</returns> public MatchedImageFeature[] MatchFeature(ImageFeature <TDescriptor>[] observedFeatures, int k) { VectorOfKeyPoint obsKpts; Matrix <TDescriptor> observedDescriptors; ImageFeature <TDescriptor> .ConvertToRaw(observedFeatures, out obsKpts, out observedDescriptors); try { DistanceType dt = typeof(TDescriptor) == typeof(Byte) ? DistanceType.Hamming : DistanceType.L2; using (Matrix <int> indices = new Matrix <int>(observedDescriptors.Rows, k)) using (Matrix <float> dists = new Matrix <float>(observedDescriptors.Rows, k)) using (BruteForceMatcher <TDescriptor> matcher = new BruteForceMatcher <TDescriptor>(dt)) { matcher.Add(_modelDescriptors); matcher.KnnMatch(observedDescriptors, indices, dists, k, null); return(ConvertToMatchedImageFeature(_modelKeyPoints, _modelDescriptors, obsKpts, observedDescriptors, indices, dists, null)); } } finally { obsKpts.Dispose(); observedDescriptors.Dispose(); } }
public void Evaluate(int SpreadMax) { FStatus.SliceCount = SpreadMax; FOutPositions1.SliceCount = SpreadMax; FOutPositions2.SliceCount = SpreadMax; for (int i = 0; i < SpreadMax; i++) { if (!FDo[i]) continue; var input1 = FInput1[i]; var input2 = FInput2[i]; if (input1 == null || input2 == null) continue; if (!input1.Allocated || !input2.Allocated) continue; Matrix<byte> mask; var matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(input2.Descriptors); var indices = new Matrix<int>(input1.Descriptors.Rows, 2); using (Matrix<float> distance = new Matrix<float>(input1.Descriptors.Rows, 2)) { matcher.KnnMatch(input1.Descriptors, indices, distance, 2, null); mask = new Matrix<byte>(distance.Rows, 1); mask.SetValue(255); Features2DToolbox.VoteForUniqueness(distance, FUniqueness[i], mask); } int nonZeroCount = CvInvoke.cvCountNonZero(mask); nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(input2.KeyPoints, input1.KeyPoints, indices, mask, 1.5, 20); var positions1 = FOutPositions1[i]; var positions2 = FOutPositions2[i]; positions1.SliceCount = 0; positions2.SliceCount = 0; for (int j = 0; j < mask.Rows; j++) { if (mask[j, 0] != 0) { var index2 = indices[j, 0]; var point1 = input1.KeyPoints[j]; var point2 = input2.KeyPoints[index2]; positions1.Add(new Vector2D(point1.Point.X, point1.Point.Y)); positions2.Add(new Vector2D(point2.Point.X, point2.Point.Y)); } } } }
public SURFEngine(Emgu.CV.Image<Gray, byte> roi) { surfDetector = new SURFDetector(500, false); itemImage = roi; itemKP = surfDetector.DetectKeyPointsRaw(itemImage, null); itemDescriptors = surfDetector.ComputeDescriptorsRaw(itemImage, null, itemKP); matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(itemDescriptors); }
public static void DescriptorMatchKnn(Matrix <float> modelDescriptors, Matrix <float> observedDescriptors, int k, out Matrix <int> indices, out Matrix <float> dist) { indices = new Matrix <int>(observedDescriptors.Rows, k); dist = new Matrix <float>(observedDescriptors.Rows, k); using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, indices, dist, k, null); } /* * using (Flann.Index index = new Flann.Index(modelDescriptors)) * { * index.KnnSearch(observedDescriptors, indices, dist, k, 0); * CvInvoke.cvSqrt(dist, dist); * }*/ }
public bool Recognize(Image<Gray, Byte> observedImage, out PointF[] Region) { // extract features from the observed image observedKeyPoints = new VectorOfKeyPoint(); Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(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 >= requiredNonZeroCount) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, scaleIncrement, RotationBins); if (nonZeroCount >= requiredNonZeroCount) homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, ransacReprojThreshold); } bool ObjectFound; if (homography != null) { //draw a rectangle along the projected model Rectangle rect = modelImage.ROI; Region = 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(Region); ObjectFound = true; } else { Region = null; ObjectFound = false; } return ObjectFound; }
/// <summary> /// Match the Image feature from the observed image to the features from the model image /// </summary> /// <param name="observedFeatures">The Image feature from the observed image</param> /// <param name="k">The number of neighbors to find</param> /// <returns>The matched features</returns> public MatchedImageFeature[] MatchFeature(ImageFeature[] observedFeatures, int k) { VectorOfKeyPoint obsKpts; Matrix<float> obsDscpts; ConvertFromImageFeature(observedFeatures, out obsKpts, out obsDscpts); using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) using (Matrix<int> indices = new Matrix<int>(obsKpts.Size, k)) using (Matrix<float> dists = new Matrix<float>(indices.Size)) { matcher.Add(_modelDescriptors); matcher.KnnMatch(obsDscpts, indices, dists, k, null); MatchedImageFeature[] result = new MatchedImageFeature[observedFeatures.Length]; for (int i = 0; i < observedFeatures.Length; i++) { result[i].SimilarFeatures = new SimilarFeature[k]; for (int j = 0; j < k; j++) { result[i].SimilarFeatures[j].Distance = dists.Data[i, j]; result[i].SimilarFeatures[j].Feature = _modelFeatures[indices.Data[i, j]]; } result[i].ObservedFeature = observedFeatures[i]; } obsKpts.Dispose(); obsDscpts.Dispose(); return result; } }
/// <summary> /// Detect the if the model features exist in the observed features. If true, an homography matrix is returned, otherwise, null is returned. /// </summary> /// <param name="modelDescriptors">The descriptors from the model image</param> /// <param name="modelKeyPoints">The keypoints drom the model image</param> /// <param name="observedDescriptors">The descriptors from the descriptor image</param> /// <param name="observedKeyPoints">The keypoints from the observed image</param> /// <param name="uniquenessThreshold">The distance different ratio which a match is consider unique, a good number will be 0.8</param> /// <returns>If the model features exist in the observed features, an homography matrix is returned, otherwise, null is returned.</returns> public static HomographyMatrix Detect( VectorOfKeyPoint modelKeyPoints, Matrix<float> modelDescriptors, VectorOfKeyPoint observedKeyPoints, Matrix<float> observedDescriptors, double uniquenessThreshold) { using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) using (Matrix<int> indices = new Matrix<int>(observedKeyPoints.Size, 2)) using (Matrix<float> dist = new Matrix<float>(indices.Size)) using (Matrix<byte> mask = new Matrix<byte>(dist.Rows, 1)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, indices, dist, 2, null); mask.SetValue(255); //Stopwatch w1 = Stopwatch.StartNew(); VoteForUniqueness(dist, uniquenessThreshold, mask); //Trace.WriteLine(w1.ElapsedMilliseconds); int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount < 4) return null; //Stopwatch w2 = Stopwatch.StartNew(); nonZeroCount = VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount < 4) return null; return GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 3); } }
public static void DescriptorMatchKnn(Matrix<float> modelDescriptors, Matrix<float> observedDescriptors, int k, out Matrix<int> indices, out Matrix<float> dist) { indices = new Matrix<int>(observedDescriptors.Rows, k); dist = new Matrix<float>(observedDescriptors.Rows, k); using (BruteForceMatcher matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, indices, dist, k, null); } /* using (Flann.Index index = new Flann.Index(modelDescriptors)) { index.KnnSearch(observedDescriptors, indices, dist, k, 0); CvInvoke.cvSqrt(dist, dist); }*/ }
public static void FindMatch(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix<int> indices, out Matrix<byte> mask, out HomographyMatrix homography) { int k = 2; double uniquenessThreshold = 0.8; SURFDetector surfCPU = new SURFDetector(500, false); Stopwatch watch; homography = null; //extract features from the object image modelKeyPoints = new VectorOfKeyPoint(); Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints); watch = Stopwatch.StartNew(); // extract features from the observed image observedKeyPoints = new VectorOfKeyPoint(); Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(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(); matchTime = watch.ElapsedMilliseconds; }
private static bool IsModelInObserved( Image<Gray, byte> modelImage, Image<Gray, byte> observedImage, double similarityThreshold = 0.075 ) { var surfCpu = new SURFDetector(500, false); Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; //extract features from the object image var modelKeyPoints = surfCpu.DetectKeyPointsRaw( modelImage, null ); Matrix<float> modelDescriptors = surfCpu.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image var observedKeyPoints = surfCpu.DetectKeyPointsRaw( observedImage, null ); Matrix<float> observedDescriptors = surfCpu.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add( modelDescriptors ); var indices = new Matrix<int>( observedDescriptors.Rows, k ); using ( var 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 keypointMatchCount = CvInvoke.cvCountNonZero( mask ); if ( keypointMatchCount >= 4 ) { keypointMatchCount = Features2DToolbox.VoteForSizeAndOrientation( modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20 ); if ( keypointMatchCount >= 4 ) { Features2DToolbox.GetHomographyMatrixFromMatchedFeatures( modelKeyPoints, observedKeyPoints, indices, mask, 2 ); } } var similarity = (double)keypointMatchCount / observedKeyPoints.Size; return similarity > similarityThreshold; }
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; }
/// <summary> /// Draw the model image and observed image, the matched features and homography projection. /// </summary> /// <param name="modelImageFileName">The model image</param> /// <param name="observedImageBitmap">The observed image</param> /// <param name="matchTime">The output total time for computing the homography matrix.</param> /// <returns>The model image and observed image, the matched features and homography projection.</returns> private System.Drawing.Point[] DrawBruteForceMatch(String modelImageFileName, Bitmap observedImageBitmap, out long matchTime) { try { Image<Gray, Byte> modelImage = new Image<Gray, byte>(modelImageFileName); Image<Gray, Byte> observedImage = new Image<Gray, byte>(observedImageBitmap); HomographyMatrix homography = null; Stopwatch watch; SURFDetector surfCPU = new SURFDetector(500, false); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; //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); 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); System.Drawing.Point[] newpts = null; #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); //result.DrawPolyline(Array.ConvertAll<PointF, System.Drawing.Point>(pts, System.Drawing.Point.Round), true, new Bgr(Color.Red), 2); //result.Save(@"E:\1.jpg"); newpts = Array.ConvertAll<PointF, System.Drawing.Point>(pts, System.Drawing.Point.Round); } #endregion matchTime = watch.ElapsedMilliseconds; return newpts; } catch (Exception e) { Console.WriteLine(e.Message); matchTime = 0; return new System.Drawing.Point[] { new System.Drawing.Point(-1, -1), new System.Drawing.Point(-1, -1), new System.Drawing.Point(-1, -1), new System.Drawing.Point(-1, -1) }; } }
public static Image<Bgr, Byte> FAST(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage) { bool isFound = false; long matchTime; Stopwatch watch; HomographyMatrix homography = null; FastDetector fastCPU = new FastDetector(10, true); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; BriefDescriptorExtractor descriptor = new BriefDescriptorExtractor(); Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; watch = Stopwatch.StartNew(); //extract features from the object image modelKeyPoints = fastCPU.DetectKeyPointsRaw(modelImage, null); Matrix<Byte> modelDescriptors = descriptor.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = fastCPU.DetectKeyPointsRaw(observedImage, null); Matrix<Byte> observedDescriptors = descriptor.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher<Byte> matcher = new BruteForceMatcher<Byte>(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 FAST: " + 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 void FindMatch(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix<int> indices, out Matrix<byte> mask, out HomographyMatrix homography) { int k = 2; double uniquenessThreshold = 0.8; SURFDetector surfCPU = new SURFDetector(500, false); Stopwatch watch; homography = null; #if !IOS 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 (Stream stream = new 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 #endif { //extract features from the object image modelKeyPoints = new VectorOfKeyPoint(); Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints); watch = Stopwatch.StartNew(); // extract features from the observed image observedKeyPoints = new VectorOfKeyPoint(); Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(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(); } matchTime = watch.ElapsedMilliseconds; }
private void GetAllKeyPointsAndMatch(Image<Gray, byte> prevFrame, Image<Gray, byte> currFrame) { int k = 2; double uniquenessThreshold = .8; VectorOfKeyPoint targetKeyPoints = new VectorOfKeyPoint(); VectorOfKeyPoint currentFrameKeyPoints = new VectorOfKeyPoint(); Matrix<float> targetDescriptors = surfDetector.DetectAndCompute(prevFrame, null, targetKeyPoints); Matrix<float> currentFrameDescriptors = surfDetector.DetectAndCompute(currFrame, null, currentFrameKeyPoints); if (targetDescriptors != null && currentFrameDescriptors != null) { BruteForceMatcher<float> keyPointMatcher = new BruteForceMatcher<float>(DistanceType.L2); keyPointMatcher.Add(targetDescriptors); Matrix<int> indices = new Matrix<int>(currentFrameDescriptors.Rows, k); using (Matrix<float> dist = new Matrix<float>(currentFrameDescriptors.Rows, k)) { keyPointMatcher.KnnMatch(currentFrameDescriptors, indices, dist, k, null); Matrix<byte> matchMask = new Matrix<byte>(dist.Rows, 1); matchMask.SetValue(255); Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, matchMask); prevMasked = Features2DToolbox.DrawMatches(prevFrame, targetKeyPoints, currFrame, currentFrameKeyPoints, indices, new Bgr(255, 0, 0), new Bgr(0, 255, 0), matchMask, Features2DToolbox.KeypointDrawType.DEFAULT); CalculateAvgDelta(targetDescriptors, currentFrameDescriptors, matchMask); } } }
private void PerformSurfDetection(object sender, EventArgs e) { this.Text = "working..."; Application.DoEvents(); stopwatch.Restart(); HomographyMatrix homographyMatrix = null; SURFDetector surfDetector = new SURFDetector(500, false); Image<Gray, Byte> imgMasterGray; Image<Gray, Byte> imgToFindGray; VectorOfKeyPoint vkpMasterKeyPoints; VectorOfKeyPoint vkpToFindKeyPoints; Matrix<float> mtxMasterDescriptors; Matrix<float> mtxToFindDescriptors; Matrix<int> mtxMatchIndices; Matrix<float> mtxDistance; Matrix<Byte> mtxMask; BruteForceMatcher<float> bruteForceMatcher; int neighbors = 2; double ratioUnique = 0.5; int nonZeroElements; double scaleIncrement = 1.5; int rotationBin = 20; double maxReprojectionError = 2.0; //PointF[] ptfPointsF; //Point ptPoints; imgMasterGray = new Image<Gray, byte>(imgMasterColor.ToBitmap()); imgToFindGray = new Image<Gray, byte>(imgToFindColor.ToBitmap()); vkpMasterKeyPoints = surfDetector.DetectKeyPointsRaw(imgMasterGray, null); mtxMasterDescriptors = surfDetector.ComputeDescriptorsRaw(imgMasterGray, null, vkpMasterKeyPoints); vkpToFindKeyPoints = surfDetector.DetectKeyPointsRaw(imgToFindGray, null); mtxToFindDescriptors = surfDetector.ComputeDescriptorsRaw(imgToFindGray, null, vkpToFindKeyPoints); bruteForceMatcher = new BruteForceMatcher<float>(DistanceType.L2); bruteForceMatcher.Add(mtxToFindDescriptors); mtxMatchIndices = new Matrix<int>(mtxMasterDescriptors.Rows, neighbors); mtxDistance = new Matrix<float>(mtxMasterDescriptors.Rows, neighbors); bruteForceMatcher.KnnMatch(mtxMasterDescriptors, mtxMatchIndices, mtxDistance, neighbors, null); mtxMask = new Matrix<byte>(mtxDistance.Rows, 1); mtxMask.SetValue(255); Features2DToolbox.VoteForUniqueness(mtxDistance, ratioUnique, mtxMask); nonZeroElements = CvInvoke.cvCountNonZero(mtxMask); if (nonZeroElements >= 4) { nonZeroElements = Features2DToolbox.VoteForSizeAndOrientation(vkpToFindKeyPoints, vkpMasterKeyPoints, mtxMatchIndices, mtxMask, scaleIncrement, rotationBin); if (nonZeroElements >= 4) { homographyMatrix = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(vkpToFindKeyPoints, vkpMasterKeyPoints, mtxMatchIndices, mtxMask, maxReprojectionError); } } imgCopyToFind = imgToFindColor.Copy(); imgCopyToFind.Draw(new Rectangle(1, 1, imgCopyToFind.Width - 3, imgCopyToFind.Height - 3), bgrFoundImageColor, 2); imgResult = imgMasterColor; imgResult = imgResult.ConcateHorizontal(imgCopyToFind); if (homographyMatrix != null) { // draw a rectangle along the projected model Rectangle rect = imgCopyToFind.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) }; homographyMatrix.ProjectPoints(pts); Point[] ptPoints = { Point.Round(pts[0]), Point.Round(pts[1]), Point.Round(pts[2]), Point.Round(pts[3]) }; imgResult.DrawPolyline(ptPoints, true, bgrFoundImageColor, 2); int X = Convert.ToInt16((pts[0].X + pts[1].X) / 2) + this.Left; int Y = Convert.ToInt16((pts[1].Y + pts[2].Y) / 2) + this.Top + 30; LeftClick(X, Y); } stopwatch.Stop(); //this.Text = "working time = " + stopwatch.Elapsed.TotalSeconds.ToString() + "sec, done ! "; }
public bool testSIFT(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage) { bool isFound = false; HomographyMatrix homography = null; SIFTDetector siftCPU = new SIFTDetector(); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; //extract features from the object image modelKeyPoints = siftCPU.DetectKeyPointsRaw(modelImage, null); Matrix<float> modelDescriptors = siftCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = siftCPU.DetectKeyPointsRaw(observedImage, null); Matrix<float> observedDescriptors = siftCPU.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); } //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 static Boolean Detect(ObjectDetectee observedScene, ObjectDetectee obj) { HomographyMatrix homography = null; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; int testsPassed = 0; // extract features from the observed image observedKeyPoints = observedScene.objectKeyPoints; Matrix<float> observedDescriptors = observedScene.objectDescriptors; BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(obj.objectDescriptors); if (observedDescriptors == null) { return false; } 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 nonZero = 0; int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(obj.objectKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) { homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(obj.objectKeyPoints, observedKeyPoints, indices, mask, 2); for (int i = 0; i < mask.Height; i++) { for (int j = 0; j < mask.Width; j++) { if (mask[i, j] != 0) { nonZero++; } } } if (nonZero > 4) { testsPassed++; } } } if (homography != null) { //draw a rectangle along the projected model Rectangle rect = obj.objectImage.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)}; using (MemStorage m1 = new MemStorage()) using (MemStorage m2 = new MemStorage()) { Contour<PointF> objPoly = new Contour<PointF>(m1); Contour<PointF> scenePoly = new Contour<PointF>(m2); pts.OrderBy(p => p.X).ThenBy(p => p.Y); foreach (PointF i in pts) { objPoly.Push(i); } homography.ProjectPoints(pts); pts.OrderBy(p => p.X).ThenBy(p => p.Y); foreach (PointF i in pts) { scenePoly.Push(i); } double shapeMatch = CvInvoke.cvMatchShapes(objPoly, scenePoly, Emgu.CV.CvEnum.CONTOURS_MATCH_TYPE.CV_CONTOURS_MATCH_I3, 0); double ratio = scenePoly.Area / objPoly.Area; foreach (PointF i in pts) { if (i.X < 0 || i.Y < 0) { return false; } } if (shapeMatch != 0 && shapeMatch <= 2) { testsPassed++; } if (ratio > 0.001 && ratio < 5.25) { testsPassed++; } if (!(Math.Abs(homography.Data[2, 0]) > .005 && Math.Abs(homography.Data[2, 1]) > .005)) { testsPassed++; } if (testsPassed >= 2) { return true; } else { return false; } } } else { return false; } }
/// <summary> /// Draw the model image and observed image, the matched features and homography projection. /// </summary> /// <param name="modelImage">The model image</param> /// <param name="observedImage">The observed image</param> /// <param name="matchTime">The output total time for computing the homography matrix.</param> /// <returns>The model image and observed image, the matched features and homography projection.</returns> public static Image<Bgr, Byte> 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 (Stream stream = new 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); } 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); result.DrawPolyline (Array.ConvertAll<PointF, Point> (pts, Point.Round), true, new Bgr (Color.Red), 5); } #endregion matchTime = watch.ElapsedMilliseconds; return result; }
public Image<Bgr, float> alignment(Image<Bgr, float> fImage, Image<Bgr, float> lImage, Boolean qrCode) { 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; Image<Gray, Byte> fImageG = fImage.Convert<Gray, Byte>(); Image<Gray, Byte> lImageG = lImage.Convert<Gray, Byte>(); //extract features from the object image modelKeyPoints = new VectorOfKeyPoint(); Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(fImageG, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = new VectorOfKeyPoint(); Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(lImageG, 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); } if (!qrCode && homography.Sum > 0) { throw new Exception(); } //Console.WriteLine("h**o: " + indices.Size + " ," + homography.Size+ " "+homography.Sum); Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(fImageG, modelKeyPoints, lImageG, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); if (homography != null) { Console.Write("homoegraphy is not null"); //draw a rectangle along the projected model Rectangle rect = fImageG.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); result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5); result.Save("resultqr.jpg"); //mage<Bgr, byte> mosaic = new Image<Bgr, byte>(fImageG.Width + fImageG.Width, fImageG.Height); //Image<Bgr, byte> warp_image = mosaic.Clone(); Image<Bgr, float> result2 = new Image<Bgr, float>(fImage.Size); //Image<Gray, Byte> result3 = new Image<Gray, Byte>(fImage.Size); CvInvoke.cvWarpPerspective(fImage.Ptr, result2, homography.Ptr, (int)INTER.CV_INTER_CUBIC + (int)WARP.CV_WARP_FILL_OUTLIERS, new MCvScalar(0)); //CvInvoke.cvWarpPerspective(fImage.Ptr, result2, homography.Ptr, (int)INTER.CV_INTER_CUBIC + (int)WARP.CV_WARP_INVERSE_MAP, new MCvScalar(0)); return result2; } else { Console.WriteLine("homography is null"); } return null; }