2016-09-29 70 views
1

我正在从一个图像集合中识别(相似性百分比)图像的项目。我使用了EmugCV 3.1.0。代码如下。虽然程序运行,但它有以下问题使用emguCV查找图像集合中的匹配图像3.1.0

  1. 当匹配找到总是显示第一个图像的百分比。找到附件

enter image description here

  • 如果我们把数据库图像集合中的同一图像两次,这是查询图像相同的图像,所有匹配百分比为零。找到附件

    string [] dbImages = {imgPath +“1.jpg”,imgPath +“2.jpg”,imgPath +“3.jpg”,imgPath +“4.jpg”}; string queryImage = imgPath +“4.jpg”;

  • 在这些图像的图像 “2” 和 “4” 是相同

    enter image description here

    的代码在下面给出

    public partial class Form1 : Form 
        { 
         private static double surfHessianThresh = 300; 
         private static SURF detector; 
         public Form1() 
         { 
          InitializeComponent(); 
          ImageMatching(); 
         } 
    
         public void ImageMatching() 
         { 
          string MatchString = null; 
          detector = new SURF(surfHessianThresh); 
          IList<IndecesMapping> matches = Match(); 
          IOrderedEnumerable<IndecesMapping> orderedMatches = matches.OrderByDescending(match => match.Similarity); 
    
          foreach (IndecesMapping match in orderedMatches) 
          { 
           MatchString = MatchString + "\n" + match.ToString(); 
          } 
          lblMatch.Text = MatchString; 
          //Console.WriteLine(); 
          //Console.WriteLine("MOST LIKELY MATCH: " + orderedMatches.First()); 
    
          //Console.WriteLine("Press enter to exit..."); 
          //Console.ReadLine(); 
         } 
    
         /// <summary> 
         /// Main method. 
         /// </summary> 
         static public IList<IndecesMapping> Match() 
         { 
    
          string imgPath = "E:\\Riyas\\Projects\\Image Recognition\\Sample Projects\\EmguSample3.1.0\\EmguSample3.1.0\\"; 
          string[] dbImages = { imgPath + "1.jpg", imgPath + "2.jpg", imgPath + "3.jpg", imgPath + "4.jpg" }; 
          string queryImage = imgPath + "1.jpg"; 
    
          IList<IndecesMapping> imap; 
    
          // compute descriptors for each image 
          var dbDescsList = ComputeMultipleDescriptors(dbImages, out imap); 
    
          // concatenate all DB images descriptors into single Matrix 
          Matrix<float> dbDescs = ConcatDescriptors(dbDescsList); 
    
          // compute descriptors for the query image 
          Matrix<float> queryDescriptors = ComputeSingleDescriptors(queryImage); 
    
          FindMatches(dbDescs, queryDescriptors, ref imap); 
    
          return imap; 
         } 
    
         /// <summary> 
         /// Computes image descriptors. 
         /// </summary> 
         /// <param name="fileName">Image filename.</param> 
         /// <returns>The descriptors for the given image.</returns> 
         static public Matrix<float> ComputeSingleDescriptors(string fileName) 
         { 
          Matrix<float> descs = null; 
          using (Image<Gray, Byte> img = new Image<Gray, byte>(fileName)) 
          { 
           MKeyPoint[] mkeyPoints = detector.Detect(img, null); 
           VectorOfKeyPoint keyPoints = new VectorOfKeyPoint(); 
           keyPoints.Push(mkeyPoints); 
    
           UMat observedDescriptors = new UMat(); 
           detector.Compute(img, keyPoints, observedDescriptors); 
           descs = new Matrix<float>(observedDescriptors.Size); 
           detector.Compute(img, keyPoints, descs); 
          } 
    
          return descs; 
         } 
    
    
         /// <summary> 
         /// Convenience method for computing descriptors for multiple images. 
         /// On return imap is filled with structures specifying which descriptor ranges in the concatenated matrix belong to what image. 
         /// </summary> 
         /// <param name="fileNames">Filenames of images to process.</param> 
         /// <param name="imap">List of IndecesMapping to hold descriptor ranges for each image.</param> 
         /// <returns>List of descriptors for the given images.</returns> 
         static public IList<Matrix<float>> ComputeMultipleDescriptors(string[] fileNames, out IList<IndecesMapping> imap) 
         { 
          imap = new List<IndecesMapping>(); 
    
          IList<Matrix<float>> descs = new List<Matrix<float>>(); 
    
          int r = 0; 
    
          for (int i = 0; i < fileNames.Length; i++) 
          { 
           var desc = ComputeSingleDescriptors(fileNames[i]); 
           descs.Add(desc); 
    
           imap.Add(new IndecesMapping() 
           { 
            fileName = fileNames[i], 
            IndexStart = r, 
            IndexEnd = r + desc.Rows - 1 
           }); 
    
           r += desc.Rows; 
          } 
    
          return descs; 
         } 
    
    
         /// <summary> 
         /// Computes 'similarity' value (IndecesMapping.Similarity) for each image in the collection against our query image. 
         /// </summary> 
         /// <param name="dbDescriptors">Query image descriptor.</param> 
         /// <param name="queryDescriptors">Consolidated db images descriptors.</param> 
         /// <param name="images">List of IndecesMapping to hold the 'similarity' value for each image in the collection.</param> 
         static public void FindMatches(Matrix<float> dbDescriptors, Matrix<float> queryDescriptors, ref IList<IndecesMapping> imap) 
         { 
          var indices = new Matrix<int>(queryDescriptors.Rows, 2); // matrix that will contain indices of the 2-nearest neighbors found 
          var dists = new Matrix<float>(queryDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found 
    
          // create FLANN index with 4 kd-trees and perform KNN search over it look for 2 nearest neighbours 
          KdTreeIndexParamses kdparam = new KdTreeIndexParamses(4); 
    
          var flannIndex = new Index(dbDescriptors, kdparam); 
          flannIndex.KnnSearch(queryDescriptors, indices, dists, 2, 24); 
    
          for (int i = 0; i < indices.Rows; i++) 
          { 
           // filter out all inadequate pairs based on distance between pairs 
           if (dists.Data[i, 0] < (0.6 * dists.Data[i, 1])) 
           { 
            // find image from the db to which current descriptor range belongs and increment similarity value. 
            // in the actual implementation this should be done differently as it's not very efficient for large image collections. 
            foreach (var img in imap) 
            { 
             if (img.IndexStart <= i && img.IndexEnd >= i) 
             { 
              img.Similarity++; 
              break; 
             } 
            } 
           } 
          } 
         } 
    
         /// <summary> 
         /// Concatenates descriptors from different sources (images) into single matrix. 
         /// </summary> 
         /// <param name="descriptors">Descriptors to concatenate.</param> 
         /// <returns>Concatenated matrix.</returns> 
         static public Matrix<float> ConcatDescriptors(IList<Matrix<float>> descriptors) 
         { 
          int cols = descriptors[0].Cols; 
          int rows = descriptors.Sum(a => a.Rows); 
    
          float[,] concatedDescs = new float[rows, cols]; 
    
          int offset = 0; 
    
          foreach (var descriptor in descriptors) 
          { 
           // append new descriptors 
           Buffer.BlockCopy(descriptor.ManagedArray, 0, concatedDescs, offset, sizeof(float) * descriptor.ManagedArray.Length); 
           offset += sizeof(float) * descriptor.ManagedArray.Length; 
          } 
    
          return new Matrix<float>(concatedDescs); 
         } 
        } 
    
        public class IndecesMapping 
        { 
         public int IndexStart { get; set; } 
         public int IndexEnd { get; set; } 
         public int Similarity { get; set; } 
         public string fileName { get; set; } 
    
         public override string ToString() 
         { 
          return fileName + ": " + Similarity + "%"; 
         } 
        } 
    

    回答