Browse Source

Added HammingDist for GpuBruteForceMatcher

git-svn-id: https://emgucv.svn.sourceforge.net/svnroot/emgucv/trunk@1340 d7f09016-e345-0410-b530-edf29a71df78
UWP10
canming 14 years ago
parent
commit
ed291510db
  1. 10
      Emgu.CV.GPU.Test/Emgu.CV.GPU.Test.csproj
  2. 90
      Emgu.CV.GPU.Test/TestGpuMat.cs
  3. 22
      Emgu.CV.GPU/GpuBruteForceMatcher.cs

10
Emgu.CV.GPU.Test/Emgu.CV.GPU.Test.csproj

@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{04AE7FDF-DCAB-4A32-936C-5AC38C34FB37}</ProjectGuid>
<OutputType>Library</OutputType>
@ -68,6 +68,14 @@
<Name>Emgu.Util</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\opencv\samples\c\box.png">
<Link>box.png</Link>
</Content>
<Content Include="..\opencv\samples\c\box_in_scene.png">
<Link>box_in_scene.png</Link>
</Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

90
Emgu.CV.GPU.Test/TestGpuMat.cs

@ -12,6 +12,7 @@ using Emgu.CV.GPU;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Util;
using Emgu.CV.Features2D;
using NUnit.Framework;
namespace Emgu.CV.GPU.Test
@ -215,7 +216,7 @@ namespace Emgu.CV.GPU.Test
Image<Gray, Byte> img = new Image<Gray, byte>(300, 400);
img.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0));
using (GpuImage<Gray, Byte> gImg1 = new GpuImage<Gray,byte>(img))
using (GpuImage<Gray, Byte> gImg1 = new GpuImage<Gray, byte>(img))
using (GpuImage<Gray, Byte> gImg2 = gImg1.Clone())
using (Image<Gray, Byte> img2 = gImg2.ToImage())
{
@ -320,5 +321,92 @@ namespace Emgu.CV.GPU.Test
}
}
}
[Test]
public void TestBruteForceHammingDistance()
{
if (GpuInvoke.HasCuda)
{
Image<Gray, byte> box = new Image<Gray, byte>("box.png");
FastDetector fast = new FastDetector(100, true);
BriefDescriptorExtractor brief = new BriefDescriptorExtractor(32);
#region extract features from the object image
Stopwatch stopwatch = Stopwatch.StartNew();
VectorOfKeyPoint modelKeypoints = fast.DetectKeyPointsRaw(box, null);
Matrix<Byte> modelDescriptors = brief.ComputeDescriptorsRaw(box, modelKeypoints);
stopwatch.Stop();
Trace.WriteLine(String.Format("Time to extract feature from model: {0} milli-sec", stopwatch.ElapsedMilliseconds));
#endregion
Image<Gray, Byte> observedImage = new Image<Gray, byte>("box_in_scene.png");
#region extract features from the observed image
stopwatch.Reset(); stopwatch.Start();
VectorOfKeyPoint observedKeypoints = fast.DetectKeyPointsRaw(observedImage, null);
Matrix<Byte> observedDescriptors = brief.ComputeDescriptorsRaw(observedImage, observedKeypoints);
stopwatch.Stop();
Trace.WriteLine(String.Format("Time to extract feature from image: {0} milli-sec", stopwatch.ElapsedMilliseconds));
#endregion
stopwatch.Reset(); stopwatch.Start();
GpuBruteForceMatcher hammingMatcher = new GpuBruteForceMatcher(GpuBruteForceMatcher.DistanceType.HammingDist);
//BruteForceMatcher hammingMatcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.Hamming, modelDescriptors);
int k = 2;
Matrix<int> trainIdx = new Matrix<int>(observedKeypoints.Size, k);
Matrix<float> distance = new Matrix<float>(trainIdx.Size);
using (GpuMat<Byte> gpuModelDescriptors = new GpuMat<byte>(modelDescriptors))
using (GpuMat<Byte> gpuObservedDescriptors = new GpuMat<byte>(observedDescriptors))
using (GpuMat<int> gpuTrainIdx = new GpuMat<int>(trainIdx))
using (GpuMat<float> gpuDistance = new GpuMat<float>(distance))
{
Stopwatch w2 = Stopwatch.StartNew();
hammingMatcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, gpuTrainIdx, gpuDistance, k, null);
w2.Stop();
Trace.WriteLine(String.Format("Time for feature matching (excluding data transfer): {0} milli-sec", w2.ElapsedMilliseconds));
gpuTrainIdx.Download(trainIdx);
gpuDistance.Download(distance);
}
Matrix<Byte> mask = new Matrix<byte>(distance.Rows, 1);
mask.SetValue(255);
Features2DTracker.VoteForUniqueness(distance, 0.8, mask);
HomographyMatrix homography = null;
int nonZeroCount = CvInvoke.cvCountNonZero(mask);
if (nonZeroCount >= 4)
{
nonZeroCount = Features2DTracker.VoteForSizeAndOrientation(modelKeypoints, observedKeypoints, trainIdx, mask, 1.5, 20);
if (nonZeroCount >= 4)
homography = Features2DTracker.GetHomographyMatrixFromMatchedFeatures(modelKeypoints, observedKeypoints, trainIdx, mask);
}
stopwatch.Stop();
Trace.WriteLine(String.Format("Time for feature matching (including data transfer): {0} milli-sec", stopwatch.ElapsedMilliseconds));
if (homography != null)
{
Rectangle rect = box.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)};
PointF[] points = pts.Clone() as PointF[];
homography.ProjectPoints(points);
//Merge the object image and the observed image into one big image for display
Image<Gray, Byte> res = box.ConcateVertical(observedImage);
for (int i = 0; i < points.Length; i++)
points[i].Y += box.Height;
res.DrawPolyline(Array.ConvertAll<PointF, Point>(points, Point.Round), true, new Gray(255.0), 5);
//ImageViewer.Show(res);
}
}
}
}
}

22
Emgu.CV.GPU/GpuBruteForceMatcher.cs

@ -42,7 +42,11 @@ namespace Emgu.CV.GPU
/// <summary>
/// Euclidean distance
/// </summary>
L2
L2,
/// <summary>
/// Hamming distance
/// </summary>
HammingDist
}
/// <summary>
@ -55,7 +59,7 @@ namespace Emgu.CV.GPU
}
/// <summary>
/// Find the k nearest neighbour using the brute force matcher
/// For L1 and L2 distance type, find the k nearest neighbour using the brute force matcher.
/// </summary>
/// <param name="queryDescriptors">The query descriptors</param>
/// <param name="modelDescriptors">The model descriptors</param>
@ -68,6 +72,20 @@ namespace Emgu.CV.GPU
gpuBruteForceMatcherKnnMatch(_ptr, queryDescriptors, modelDescriptors, modelIdx, distance, k, mask);
}
/// <summary>
/// For Hamming distance type, find the k nearest neighbour using the brute force matcher.
/// </summary>
/// <param name="queryDescriptors">The query descriptors</param>
/// <param name="modelDescriptors">The model descriptors</param>
/// <param name="modelIdx">The model index. A n x <paramref name="k"/> matrix where n = <paramref name="queryDescriptors"/>.Cols</param>
/// <param name="distance">The matrix where the distance valus is stored. A n x <paramref name="k"/> matrix where n = <paramref name="queryDescriptors"/>.Size.Height</param>
/// <param name="k">The number of nearest neighbours to be searched</param>
/// <param name="mask">The mask</param>
public void KnnMatch(GpuMat<Byte> queryDescriptors, GpuMat<Byte> modelDescriptors, GpuMat<int> modelIdx, GpuMat<float> distance, int k, GpuMat<Byte> mask)
{
gpuBruteForceMatcherKnnMatch(_ptr, queryDescriptors, modelDescriptors, modelIdx, distance, k, mask);
}
/// <summary>
/// Release all the unmanaged memory associated with this matcher
/// </summary>

Loading…
Cancel
Save