EMGU CV SURF-Bild entsprechen
Habe ich die Arbeit mit der SURF feature detection Beispiel aus der EMGU CV Bibliothek.
So weit ist es erstaunlich; ich kann erkennen, passende Objekte zwischen 2 gegebenen Bilder, aber ich habe ein problem in Bezug auf, wenn die Bilder nicht übereinstimmen.
War ich auf der Suche nach Unterstützung aus den Foren, aber Sie sind nach unten aus, wo ich bin. Sollte jemand wissen, welche Parameter bestimmen, ob ein Bild, ein Spiel oder nicht. Wenn ich den test mit 2 Bildern, die nicht übereinstimmen, ist der code noch fortgesetzt, als wenn es war ein Spiel und zieht eine unscharf dicken roten Linie auf eine zufällige Position des Bildes, selbst wenn es nicht passt.
Wenn keine übereinstimmung vorhanden ist ich würde wünschen, Sie zu brechen aus dem code und nicht weiter fortfahren.
Anhang:
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));
}
}
}
`
- Zusätzliche Informationen: klarer sein, wenn die 2 Bilder nicht übereinstimmen, ich wünschte, beenden Sie die Ausführung und prüfen Sie mit einem anderen Bild.
- Update: ich denke, dass ich das Problem gelöst. Ich habe gerade reduziert die Einzigartigkeit Schwelle, an: Features2DTracker.VoteForUniqueness(dist, 0.8, Maske); geändert von 0,8 auf 0,5. Funktioniert Prima.
- können Sie schreiben, wie haben Sie das gelöst, da eine Antwort? Dank
- Ich war debugging-Tests mit 2 Bildern, die nahe ähnlichkeit, aber nicht exakt übereinstimmt. Ich fand, dass durch eine Senkung der Einzigartigkeit Schwelle konnte ich erkennen, irgendeine form von ähnlichkeit. es ist immer noch ein work in progress, als ich das Ziel, mich zu verbessern.
- Sie können fügen Sie Ihre Antwort und akzeptiere deine eigene Frage beantwortet,dann kann ich bis Stimme.
- Das ist nicht technisch zu lösen. Schauen Sie in die Methode
Features2DTracker.VoteForUniqueness(...)
. Sie sind nur für die änderung der Einzigartigkeit Schwelle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir nicht sicher, ob es eine Methode gibt, dass für alle Fälle der Bild-Sequenzen oder alle geometrischen Verformung.
Ich schlage vor, Sie berechnen die PSNR zwischen zwei Bildern, zu studieren und eine Toleranz-Schwelle, auf einer Abfolge von Bildern.