2012-03-16 21 views
9

He estado trabajando con el ejemplo de detección de características de SURF de la biblioteca EMGU CV.EMGU CV SURF coincidencia de imagen

Hasta ahora está funcionando increíblemente; Puedo detectar objetos coincidentes entre 2 imágenes dadas, pero me he encontrado con un problema con respecto a cuándo las imágenes no coinciden.

Estaba buscando apoyo de los foros pero están abajo de donde estoy. ¿Alguien sabría qué parámetros determinan si una imagen es una coincidencia o no? Cuando pruebo con 2 imágenes que no coinciden, el código continúa como si hubiera una coincidencia y dibuja una línea roja gruesa borrosa en una ubicación aleatoria de la imagen, incluso cuando no coinciden.

Si no hay coincidencia, me gustaría separarme del código y no seguir adelante.

Apéndice:

 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

Adicional: Para ser más claro, cuando las 2 imágenes no coinciden, deseo detener la ejecución y verificar con otra imagen. – user1246856

+3

Actualización: Creo que he resuelto el problema. Acabo de reducir el umbral de exclusividad en: Features2DTracker.VoteForUniqueness (dist, 0.8, máscara); cambiado de 0.8 a 0.5. Funcionando bien. – user1246856

+0

¿Puedes escribir cómo resolviste como respuesta? gracias –

Respuesta

1

no estoy seguro de si hay un método que se adapte a todos los casos de secuencias de imágenes o toda deformación geométrica.

Le sugiero que calcule el PSNR entre dos imágenes, y que estudie un umbral de tolerancia en su secuencia de imágenes.

Cuestiones relacionadas