2

我正在使用 SURF 算法来查找查询图像和存储在数据库中的集合图像之间的相似性。为了获得更好的性能,我使用了快速近似最近邻 (FLANN)。现在,我想将这项工作分为两个步骤:

第一步:计算数据库中所有图像的描述符,然后将所有描述符组合成一个大矩阵,最后构建 FLANN。

第二步:计算查询图像的描述符,并使用 FLANN 索引查找查询描述符和所有集合描述符之间的匹配。

谁能帮我?

FLANN.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Features2D;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.GPU;
using Emgu.CV.Flann;

namespace flannconsole
{

class FLANN
{

    private static double surfHessianThresh = 300;
    private static bool surfExtendedFlag = true;
    private static SURFDetector detector = new      SURFDetector(surfHessianThresh, surfExtendedFlag);


    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 + "%";
        }
    }


    public static IList<IndecesMapping> Match(string[] dbImages, string queryImage)
    {
        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;
    }


    public static Matrix<float> ComputeSingleDescriptors(string fileName)
    {
        Matrix<float> descs;

        using (Image<Gray, Byte> img = new Image<Gray, Byte>(fileName))
        {
            VectorOfKeyPoint keyPoints = detector.DetectKeyPointsRaw(img, null);
            descs = detector.ComputeDescriptorsRaw(img, null, keyPoints);
        }

        return descs;
    }


    public static 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;
    }


    public static void FindMatches(Matrix<float> dbDescriptors, Matrix<float> queryDescriptors, ref IList<IndecesMapping> imap)
    {
        var indices = new Matrix<int>(queryDescriptors.Rows, 2);
        var dists = new Matrix<float>(queryDescriptors.Rows, 2); 

        // create FLANN index with 4 kd-trees and perform KNN search over it look for 2 nearest neighbours
        var flannIndex = new Index(dbDescriptors, 4);
        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]))
            {
                foreach (var img in imap)
                {
                    if (img.IndexStart <= indices[i, 1] && img.IndexEnd >= indices[i, 1])
                    {
                        img.Similarity++;
                        break;
                    }
                }
            }
        }
    }



    public static 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);
    }


}
}

程序.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Features2D;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.GPU;
using Emgu.CV.Flann;


namespace flannconsole
{
class Program
{
    static void Main(string[] args)
    {
        string[] dbImages = Directory.GetFiles(@"E:/nf/");
        string queryImage = "E://nf//01.jpg";

        IList<FLANN.IndecesMapping> matches = FLANN.Match(dbImages, queryImage);

        foreach (FLANN.IndecesMapping match in matches)
        {
            Console.WriteLine(match.ToString());
        }

        Console.ReadLine();
    }


}
}
4

0 回答 0