Соответствие изображения EMUU CV SURF

Я работаю с примером обнаружения функции SURF из библиотеки CVG EMGU.

До сих пор он работал удивительно; Я могу обнаружить совпадающие объекты между двумя заданными изображениями, но я столкнулся с проблемой в отношении того, когда изображения не совпадают.

Я искал поддержку на форумах, но они с того места, где я есть. Кто-нибудь знает, какие параметры определяют, соответствует ли изображение или нет. Когда я тестирую с 2 изображениями, которые не соответствуют, код по-прежнему продолжается, как если бы было совпадение, и рисует размытую густую красную линию в случайном месте изображения, даже если нет совпадения.

Если нет совпадения, я хотел бы выйти из кода и не продолжить дальше.

Приложение:

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 (*********.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", *********.HasCuda ? "GPU" : "CPU", watch.ElapsedMilliseconds));
 }
 }
}
</pointf,></bgr,></byte></float></int></float></float></byte></float></int></float></float></int></int></float></float></gray,></gray,></float></float></gray,></gray,></byte></float></int></gray,></gray,></gray,></gray,>

`

1 ответ

Я не уверен, есть ли метод, который подходит для всех случаев последовательности изображений или всей геометрической деформации.

Я предлагаю вам рассчитать PSNR между двумя изображениями и изучить порог допуска на вашей последовательности изображений.

licensed under cc by-sa 3.0 with attribution.