2016-03-28 35 views
4

Resimlerdeki benzer nesneleri tanımak için Emgu CV'nin SURF özelliğini kullanıyorum. bütün kilit noktalarını gösteren görüntü hakkına çizilirEmgu CV SURF eşleşen puan koordinatlarını alın

, o kapsar ve bir dikdörtgen (genellikle bazen sadece bir çizgi, dikdörtgen) (ne istiyorum ki ), her iki görüntülerde, benzer puan bulundu benzer noktalar.

sorun benzer noktaları görüntüde görüldüğünü, ancak onlar, aslında, onlar sadece bir işaretçi saklayan bir VectorOfKeyPoint nesne, saklanan konum istediğiniz formatta kaydedilmez, ve noktaların bellekte saklandığı diğer hafıza verileri (bence bu). Anlam, ben gibi çiftler halinde benzer noktaları alamayan:

((img1X, img1Y), (img2X, img2Y))

Bu yüzden, ben aradığım şey olurdu Bir sonraki noktaları kullanabilirim. Şu anda, sonuçta elde edilen görüntüdeki noktaları görebiliyorum, ancak onları çift olarak alamıyorum.

Kullandığım kod, Emgu CV örneğidir. Ben kibrit dışında bazı puan almak başardınız

//---------------------------------------------------------------------------- 
// Copyright (C) 2004-2016 by EMGU Corporation. All rights reserved.  
//---------------------------------------------------------------------------- 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using Emgu.CV; 
using Emgu.CV.CvEnum; 
using Emgu.CV.Features2D; 
using Emgu.CV.Structure; 
using Emgu.CV.Util; 
#if !__IOS__ 
using Emgu.CV.Cuda; 
#endif 
using Emgu.CV.XFeatures2D; 

namespace FirstEmgu 
{ 

    public static class DrawMatches 
    { 
    // -------------------------------- 
    // ORIGINAL FUNCTION FROM EXAMPLE 
    // -------------------------------- 
     private static void FindMatch(Mat modelImage, Mat observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Mat mask, out Mat homography) 
     { 
      int k = 2; 
      double uniquenessThreshold = 0.8; 
      double hessianThresh = 300; 

      Stopwatch watch; 
      homography = null; 

      modelKeyPoints = new VectorOfKeyPoint(); 
      observedKeyPoints = new VectorOfKeyPoint(); 

#if !__IOS__ 
      if (CudaInvoke.HasCuda) 
      { 
       CudaSURF surfCuda = new CudaSURF((float)hessianThresh); 
       using (GpuMat gpuModelImage = new GpuMat(modelImage)) 
       //extract features from the object image 
       using (GpuMat gpuModelKeyPoints = surfCuda.DetectKeyPointsRaw(gpuModelImage, null)) 
       using (GpuMat gpuModelDescriptors = surfCuda.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) 
       using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2)) 
       { 
        surfCuda.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); 
        watch = Stopwatch.StartNew(); 

        // extract features from the observed image 
        using (GpuMat gpuObservedImage = new GpuMat(observedImage)) 
        using (GpuMat gpuObservedKeyPoints = surfCuda.DetectKeyPointsRaw(gpuObservedImage, null)) 
        using (GpuMat gpuObservedDescriptors = surfCuda.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints)) 
        //using (GpuMat tmp = new GpuMat()) 
        //using (Stream stream = new Stream()) 
        { 
         matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k); 

         surfCuda.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); 

         mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); 
         mask.SetTo(new MCvScalar(255)); 
         Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask); 

         int nonZeroCount = CvInvoke.CountNonZero(mask); 
         if (nonZeroCount >= 4) 
         { 
          nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, 
           matches, mask, 1.5, 20); 
          if (nonZeroCount >= 4) 
           homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, 
            observedKeyPoints, matches, mask, 2); 
         } 
        } 
        watch.Stop(); 
       } 
      } 
      else 
#endif 
      { 
       using (UMat uModelImage = modelImage.ToUMat(AccessType.Read)) 
       using (UMat uObservedImage = observedImage.ToUMat(AccessType.Read)) 
       { 
        SURF surfCPU = new SURF(hessianThresh); 
        //extract features from the object image 
        UMat modelDescriptors = new UMat(); 
        surfCPU.DetectAndCompute(uModelImage, null, modelKeyPoints, modelDescriptors, false); 

        watch = Stopwatch.StartNew(); 

        // extract features from the observed image 
        UMat observedDescriptors = new UMat(); 
        surfCPU.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false); 
        BFMatcher matcher = new BFMatcher(DistanceType.L2); 
        matcher.Add(modelDescriptors); 

        matcher.KnnMatch(observedDescriptors, matches, k, null); 
        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); 
        mask.SetTo(new MCvScalar(255)); 
        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask); 

        int nonZeroCount = CvInvoke.CountNonZero(mask); 
        if (nonZeroCount >= 4) 
        { 
         nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, 
          matches, mask, 1.5, 20); 
         if (nonZeroCount >= 4) 
          homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, 
           observedKeyPoints, matches, mask, 2); 
        } 

        watch.Stop(); 
       } 
      } 
      matchTime = watch.ElapsedMilliseconds; 
     } 
     // -------------------------------- 
     // ORIGINAL FUNCTION FROM EXAMPLE 
     // -------------------------------- 
     /// <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 Mat Draw(Mat modelImage, Mat observedImage, out long matchTime) 
     { 
      Mat homography; 
      VectorOfKeyPoint modelKeyPoints; 
      VectorOfKeyPoint observedKeyPoints; 
      using (VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch()) 
      { 
       Mat mask; 
       FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, matches, 
        out mask, out homography); 

       //Draw the matched keypoints 
       Mat result = new Mat(); 
       Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, 
        matches, result, new MCvScalar(255, 255, 255), new MCvScalar(255, 255, 255), mask); 

       #region draw the projected region on the image 

       if (homography != null) 
       { 
        //draw a rectangle along the projected model 
        Rectangle rect = new Rectangle(Point.Empty, modelImage.Size); 
        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) 
       }; 
        pts = CvInvoke.PerspectiveTransform(pts, homography); 

        Point[] points = Array.ConvertAll<PointF, Point>(pts, Point.Round); 
        using (VectorOfPoint vp = new VectorOfPoint(points)) 
        { 
         CvInvoke.Polylines(result, vp, true, new MCvScalar(255, 0, 0, 255), 5); 
        } 

       } 

       #endregion 

       return result; 

      } 
     } 

     // ---------------------------------- 
     // WRITTEN BY MYSELF 
     // ---------------------------------- 
     // Returns 4 points (usually rectangle) of similar points 
     // but can't be used, since sometimes this is a line (negative 
     // points) 
     public static Point[] FindPoints(Mat modelImage, Mat observedImage, out long matchTime) 
     { 
      Mat homography; 
      VectorOfKeyPoint modelKeyPoints; 
      VectorOfKeyPoint observedKeyPoints; 
      using (VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch()) 
      { 
       Mat mask; 
       FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, matches, 
        out mask, out homography); 

       //Draw the matched keypoints 
       Mat result = new Mat(); 
       Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, 
        matches, result, new MCvScalar(255, 255, 255), new MCvScalar(255, 255, 255), mask); 

       Point[] points = null; 
       if (homography != null) 
       { 
        //draw a rectangle along the projected model 
        Rectangle rect = new Rectangle(Point.Empty, modelImage.Size); 
        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) 
       }; 
        pts = CvInvoke.PerspectiveTransform(pts, homography); 

        points = Array.ConvertAll<PointF, Point>(pts, Point.Round); 

       } 

       return points; 
      } 
     } 
    } 
} 

DÜZENLEME böyle nesneleri:

Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, matches, result, new MCvScalar(255, 255, 255), new MCvScalar(255, 255, 255), mask); for (int i = 0; i < matches.Size; i++) { var a = matches[i].ToArray(); foreach (var e in a) { Point p = new Point(e.TrainIdx, e.QueryIdx); Console.WriteLine(string.Format("Point: {0}", p)); } Console.WriteLine("-----------------------"); } 

bu bana puan almak gerektiğini düşünüyorum. Python'da çalışmayı başardım ve kod çok farklı değil. Sorun, iade edilen çok fazla puan var. Aslında, bu, bana, Y üzerinde tüm noktaları verir

Örnek

(45, 1), (67, 1)

(656, 2), (77, 2)

...

Yakında olabilsem de bana istediğim noktaları alamıyor. Herhangi bir öneri takdir edilir.

DÜZENLEME 2 Bu soru: Find interest point in surf Detector Algorithm ihtiyacım olanı çok benzer bir şeydir. Sadece bir cevap var, ama eşleştirilen puan koordinatlarını nasıl alacağını anlatmıyor. İhtiyacım olan şey, her iki görüntüde de bir nesne varsa, her iki görüntüden de nesnelerin noktalarının koordinatlarını alır.

cevap

2

Her bir nokta çifti, VoteForUniqueness işlevi tarafından doğrulanır. Bu doğrulama sonucu mask'da saklanır.maç valide olup olmadığını

Yani tüm yapmanız gereken kontrol edilir:

for (int i = 0; i < matches.Size; i++) 
{ 
    var a = matches[i].ToArray(); 
    if (mask.GetData(i)[0] == 0) 
     continue; 
    foreach (var e in a) 
    { 
     Point p = new Point(e.TrainIdx, e.QueryIdx); 
     Console.WriteLine(string.Format("Point: {0}", p)); 
    } 
    Console.WriteLine("-----------------------"); 
} 
3

koordinatları TrainIdx ve QueryIdx yapılmış değildir, bu keypoints endeksleri vardır. Bu model ile gözlenen görüntü arasında eşleşen piksel koordinatlarını verecektir.

for (int i = 0; i < matches.Size; i++) 
{ 
    var arrayOfMatches = matches[i].ToArray(); 
    if (mask.GetData(i)[0] == 0) continue; 
    foreach (var match in arrayOfMatches) 
    { 
     var matchingModelKeyPoint = modelKeyPoints[match.TrainIdx]; 
     var matchingObservedKeyPoint = observedKeyPoints[match.QueryIdx]; 
     Console.WriteLine("Model coordinate '" + matchingModelKeyPoint.Point + "' matches observed coordinate '" + matchingObservedKeyPoint.Point + "'."); 
    } 
} 

arrayOfMatches öğelerin sayısı Bu en düşük mesafe ile maç en iyisi benim anlaşılmasıdır K. değerine eşittir.

İlgili konular