2012-03-16 14 views
9

Ho lavorato con l'esempio di rilevamento delle funzioni SURF dalla libreria CV EMGU.Corrispondenza immagine SURF EMGU CV

Finora funziona in modo sorprendente; Riesco a rilevare oggetti corrispondenti tra 2 immagini date ma ho incontrato un problema relativo a quando le immagini non corrispondono.

Stavo cercando supporto dai forum ma sono giù da dove sono. Qualcuno saprebbe quali parametri determinano se un'immagine corrisponde o no. Quando provo con 2 immagini che non corrispondono, il codice procede ancora come se ci fosse una corrispondenza e disegna una linea rossa spessa e sfocata su una posizione casuale dell'immagine anche quando non c'è una corrispondenza.

Se non c'è corrispondenza, vorrei rompere il codice e non procedere oltre.

Appendice:

 static void Run() 
     { 
      Image<Gray, Byte> modelImage = new Image<Gray, byte>("HatersGonnaHate.png"); 
     Image<Gray, Byte> observedImage = new Image<Gray, byte>("box_in_scene.png"); 
     Stopwatch watch; 
     HomographyMatrix homography = null; 

     SURFDetector surfCPU = new SURFDetector(500, false); 

     VectorOfKeyPoint modelKeyPoints; 
     VectorOfKeyPoint observedKeyPoints; 
     Matrix<int> indices; 
     Matrix<float> dist; 
     Matrix<byte> mask; 

     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 matcher = new GpuBruteForceMatcher(GpuBruteForceMatcher.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, 2, 1)) 
       using (GpuMat<float> gpuMatchDist = new GpuMat<float>(gpuMatchIndices.Size, 1)) 
       { 
        observedKeyPoints = new VectorOfKeyPoint(); 
        surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); 

        matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, 2, null); 

        indices = new Matrix<int>(gpuMatchIndices.Size); 
        dist = new Matrix<float>(indices.Size); 
        gpuMatchIndices.Download(indices); 
        gpuMatchDist.Download(dist); 

        mask = new Matrix<byte>(dist.Rows, 1); 

        mask.SetValue(255); 

        Features2DTracker.VoteForUniqueness(dist, 0.8, mask); 

        int nonZeroCount = CvInvoke.cvCountNonZero(mask); 
        if (nonZeroCount >= 4) 
        { 
        nonZeroCount = Features2DTracker.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); 
        if (nonZeroCount >= 4) 
         homography = Features2DTracker.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 3); 
        } 

        watch.Stop(); 
       } 
      } 
     } 
     else 
     { 
      //extract features from the object image 
      modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null); 
      //MKeyPoint[] kpts = modelKeyPoints.ToArray(); 
      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 matcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32); 
      matcher.Add(modelDescriptors); 
      int k = 2; 
      indices = new Matrix<int>(observedDescriptors.Rows, k); 
      dist = new Matrix<float>(observedDescriptors.Rows, k); 
      matcher.KnnMatch(observedDescriptors, indices, dist, k, null); 

      mask = new Matrix<byte>(dist.Rows, 1); 

      mask.SetValue(255); 

      Features2DTracker.VoteForUniqueness(dist, 0.8, mask); 

      int nonZeroCount = CvInvoke.cvCountNonZero(mask); 
      if (nonZeroCount >= 4) 
      { 
       nonZeroCount = Features2DTracker.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); 
       if (nonZeroCount >= 4) 
        homography = Features2DTracker.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 3); 
      } 

      watch.Stop(); 
     } 

     //Draw the matched keypoints 
     Image<Bgr, Byte> result = Features2DTracker.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, 
      indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DTracker.KeypointDrawType.NOT_DRAW_SINGLE_POINTS); 

     #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 

     ImageViewer.Show(result, String.Format("Matched using {0} in {1} milliseconds", GpuInvoke.HasCuda ? "GPU" : "CPU", watch.ElapsedMilliseconds)); 
     } 


    } 

} 

`

+0

In aggiunta: per essere più chiari, quando le 2 immagini non corrispondono, desidero interrompere l'esecuzione e verificare con un'altra immagine. Aggiornamento – user1246856

+3

: Penso di aver risolto il problema. Ho appena ridotto la soglia di unicità su: Features2DTracker.VoteForUniqueness (dist, 0.8, mask); cambiato da 0,8 a 0,5. Funzionando bene. – user1246856

+0

puoi scrivere come hai risolto come risposta? grazie –

risposta

1

non sono sicuro se c'è un metodo che si adatta a tutti i casi di sequenze di immagini o tutti deformazione geometrica.

Ti suggerisco di calcolare lo PSNR tra due immagini e di studiare una soglia di tolleranza sulla sequenza di immagini.