public List<Keypoint> usingSift(Bitmap image) { SIFTDetector sift = new SIFTDetector(); Image<Gray, Byte> modelImage = new Image<Gray, byte>(new Bitmap(image)); VectorOfKeyPoint modelKeyPoints = sift.DetectKeyPointsRaw(modelImage, null); MKeyPoint[] keypoints = modelKeyPoints.ToArray(); Keypoint key; List<Keypoint> keypointsList = new List<Keypoint>(); foreach (MKeyPoint keypoint in keypoints) { key = new Keypoint(keypoint.Point.X, keypoint.Point.Y, keypoint.Size); keypointsList.Add(key); } return keypointsList; }
public bool testSIFT(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage) { bool isFound = false; HomographyMatrix homography = null; SIFTDetector siftCPU = new SIFTDetector(); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; //extract features from the object image modelKeyPoints = siftCPU.DetectKeyPointsRaw(modelImage, null); Matrix<float> modelDescriptors = siftCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = siftCPU.DetectKeyPointsRaw(observedImage, null); Matrix<float> observedDescriptors = siftCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(modelDescriptors); indices = new Matrix<int>(observedDescriptors.Rows, k); using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k)) { matcher.KnnMatch(observedDescriptors, indices, dist, k, null); mask = new Matrix<byte>(dist.Rows, 1); mask.SetValue(255); Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); } int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } //Draw the matched keypoints Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #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); if (CvInvoke.cvCountNonZero(mask) >= 10) isFound = true; result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.LightGreen), 5); } #endregion return isFound; }
public static Image<Bgr, Byte> SIFT(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage) { bool isFound = false; long matchTime; Stopwatch watch; HomographyMatrix homography = null; SIFTDetector siftCPU = new SIFTDetector(); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix<int> indices; Matrix<byte> mask; int k = 2; double uniquenessThreshold = 0.8; watch = Stopwatch.StartNew(); //extract features from the object image modelKeyPoints = siftCPU.DetectKeyPointsRaw(modelImage, null); Matrix<float> modelDescriptors = siftCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = siftCPU.DetectKeyPointsRaw(observedImage, null); Matrix<float> observedDescriptors = siftCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(modelDescriptors); indices = new Matrix<int>(observedDescriptors.Rows, k); using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k)) { matcher.KnnMatch(observedDescriptors, indices, dist, k, null); mask = new Matrix<byte>(dist.Rows, 1); mask.SetValue(255); Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); } int nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 4) homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } watch.Stop(); //Draw the matched keypoints Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #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); if (CvInvoke.cvCountNonZero(mask) >= 10) isFound = true; result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.LightGreen), 5); } #endregion matchTime = watch.ElapsedMilliseconds; _richTextBox1.Clear(); _richTextBox1.AppendText("objek ditemukan: " + isFound + "\n"); _richTextBox1.AppendText("waktu pendeteksian SIFT: " + matchTime + "ms\n"); _richTextBox1.AppendText("fitur mentah pada model yang terdeteksi: " + modelKeyPoints.Size + "\n"); _richTextBox1.AppendText("match yang ditemukan: " + CvInvoke.cvCountNonZero(mask).ToString()); return result; }