public Image <Bgr, Byte> Drawtwo(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage) { HomographyMatrix homography = null; FastDetector fastCPU = new FastDetector(10, true); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix <int> indices; BriefDescriptorExtractor descriptor = new BriefDescriptorExtractor(); Matrix <byte> mask; int k = 2; double uniquenessThreshold = 0.8; //extract features from the object image modelKeyPoints = fastCPU.DetectKeyPointsRaw(modelImage, null); Matrix <Byte> modelDescriptors = descriptor.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = fastCPU.DetectKeyPointsRaw(observedImage, null); Matrix <Byte> observedDescriptors = descriptor.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher <Byte> matcher = new BruteForceMatcher <Byte>(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); } nonZeroCount = CvInvoke.cvCountNonZero(mask); //print("nonZeroCount is "+nonZeroCount); 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); //area = Math.Abs((rect.Top - rect.Bottom) * (rect.Right - rect.Left)); result.DrawPolyline(Array.ConvertAll <PointF, Point>(pts, Point.Round), true, new Bgr(System.Drawing.Color.Red), 5); } #endregion return(result); }
public Image <Bgr, Byte> ObjectDetector(Image <Bgr, Byte> modelImage, string filepath) { Stopwatch watch; HomographyMatrix homography = null; SURFDetector surfCPU = new SURFDetector(500, false); FastDetector fastCPU = new FastDetector(10, true); VectorOfKeyPoint modelKeyPoints; BriefDescriptorExtractor descriptor = new BriefDescriptorExtractor(); Image <Gray, byte> grayImage = new Image <Gray, Byte>(filepath); modelKeyPoints = fastCPU.DetectKeyPointsRaw(grayImage, null); Matrix <byte> modelDescriptors = descriptor.ComputeDescriptorsRaw(grayImage, null, modelKeyPoints); Image <Bgr, Byte> result = Features2DToolbox.DrawKeypoints(grayImage, modelKeyPoints, new Bgr(0, 0, 255), Features2DToolbox.KeypointDrawType.DRAW_RICH_KEYPOINTS); result.Save("C:\\Users\\Sandeep\\Documents\\What_Are_Those\\Assets\\picture645.jpg"); //Image<Bgr, Byte> result = modelImage; MKeyPoint[] modelpoints = modelKeyPoints.ToArray(); List <PointF> points = new List <PointF>(); //List<PointF> boundarypointsList = new List<PointF>(); Dictionary <float, float> boundaryPoints = new Dictionary <float, float>(); Dictionary <float, float> boundaryPointshorizontal = new Dictionary <float, float>(); Dictionary <float, float> boundaryPointsModified = new Dictionary <float, float>(); Dictionary <float, float> boundaryPointsRed = new Dictionary <float, float>(); for (int i = 0; i < modelpoints.Length; i++) { points.Add(modelpoints[i].Point); //print("X is " + points.ToArray()[i].X + "Y is " + points.ToArray()[i].Y); } points.Sort((a, b) => a.X.CompareTo(b.X)); float x = points.ToArray()[0].X; float y = points.ToArray()[0].Y; float nextx, nexty; float miny = grayImage.Height; float maxx = grayImage.Width; for (int i = 0; i < points.ToArray().Length - 1; i++) { x = points.ToArray()[i].X; y = points.ToArray()[i].Y; nextx = points.ToArray()[i + 1].X; nexty = points.ToArray()[i + 1].Y; if (x == nextx) { miny = Mathf.Min(y, nexty); } else { boundaryPoints.Add(x, miny); //boundarypointsList.Add(new PointF(x, miny)); } //print("X is " + points.ToArray()[i].X + " Y is " + points.ToArray()[i].Y); } int lastindex = points.ToArray().Length - 1; if (x != points.ToArray()[lastindex].X) { PointF lastpoint = points.ToArray()[lastindex]; boundaryPoints.Add(lastpoint.X, lastpoint.Y); } points.Sort((a, b) => a.Y.CompareTo(b.Y)); for (int i = 0; i < points.ToArray().Length - 1; i++) { x = points.ToArray()[i].X; y = points.ToArray()[i].Y; nextx = points.ToArray()[i + 1].X; nexty = points.ToArray()[i + 1].Y; if (y == nexty) { maxx = Mathf.Max(x, nextx); } else { boundaryPointshorizontal.Add(y, maxx); //boundarypointsList.Add(new PointF(x, miny)); } //print("X is " + points.ToArray()[i].X + " Y is " + points.ToArray()[i].Y); } lastindex = points.ToArray().Length - 1; if (y != points.ToArray()[lastindex].Y) { PointF lastpoint = points.ToArray()[lastindex]; boundaryPointshorizontal.Add(lastpoint.X, lastpoint.Y); } var min = boundaryPoints.ElementAt(0); var max = boundaryPoints.ElementAt(0); var hmax = boundaryPoints.ElementAt(0); for (int i = 0; i < boundaryPoints.Count; i++) { var item = boundaryPoints.ElementAt(i); float itemKey = item.Key; float itemValue = item.Value; if (itemValue < min.Value) { min = item; } if (itemValue > max.Value || max.Value == result.Rows) { max = item; } //print("X is " + itemKey + " Y is " + itemValue); } for (int i = 0; i < boundaryPointshorizontal.Count; i++) { var item = boundaryPointshorizontal.ElementAt(i); float itemKey = item.Key; float itemValue = item.Value; if (itemValue < min.Value) { min = item; } if (itemValue > hmax.Value || hmax.Value == result.Cols) { hmax = item; } // print("horizontal Y is " + itemKey + " horizontal X is " + itemValue); } //print("MIN is " + min.Key + " " + min.Value); //print("MAX is " + max.Key + " " + max.Value); //print("HMAX is " + hmax.Key + " " + hmax.Value); float prev = boundaryPoints.ElementAt(0).Value; int mid = 0; for (int i = 0; i < boundaryPoints.ElementAt(0).Key; i++) { boundaryPointsModified[(float)i] = boundaryPoints.ElementAt(0).Value; } for (int i = 0; i < boundaryPoints.Count && boundaryPoints.ElementAt(i).Key != boundaryPointshorizontal.ElementAt(1).Value; i++) { var item = boundaryPoints.ElementAt(i); float itemKey = item.Key; float itemValue = item.Value; //print("itemKey "+itemKey+ " itemValue " + itemValue + " prev " + prev); if (itemValue > prev) { boundaryPointsModified[itemKey] = prev; } else if ((prev - itemValue < 80 && prev != result.Rows) || (prev == result.Rows && prev - itemValue > 0)) { boundaryPointsModified[itemKey] = itemValue; prev = itemValue; } else { boundaryPointsModified[itemKey] = prev; } mid = i; } for (int i = mid + 1; i < boundaryPoints.Count; i++) { var item = boundaryPoints.ElementAt(i); float itemKey = item.Key; float itemValue = item.Value; boundaryPointsModified[itemKey] = 0; } for (int i = 0; i < boundaryPointsModified.Count - 1; i++) { var item = boundaryPointsModified.ElementAt(i); var itemKey = item.Key; var itemValue = item.Value; //print("X modified is " + itemKey + " Y modified is " + itemValue); } byte[,,] data = result.Data; byte[,,] data_model = modelImage.Data; int xstop = (int)boundaryPointsModified.ElementAt(0).Key; int ystop = (int)boundaryPointsModified.ElementAt(2).Value; /* print("xstop is " + xstop + " ystop is "+ystop); * for (int i = 0; i <= xstop; i++) * { * for (int j = 0; j <= ystop; j++) * { * data_model[j, i, 0] = 255; * data_model[j, i, 1] = 255; * data_model[j, i, 2] = 255; * } * } * modelImage.Data = data_model; */ for (int run = 19; run >= 0; run--) { for (int i = 0; i <= modelImage.Cols - 1; i++) { for (int j = 0; j <= modelImage.Rows - 1; j++) { if (boundaryPoints.ContainsKey((float)i)) { float stoppingPoint = boundaryPointsModified[(float)i]; //print("Stoppping Point is " + stoppingPoint); if ((float)j <= stoppingPoint) { //print("j is "+j+" i is "+i+" red "+result[j, i].Red); data_model[j, i, 0] = 246; data_model[j, i, 1] = 246; data_model[j, i, 2] = 246; } /* else if (i == 600 || i == 612){ * data[j, i, 0] = 255; * data[j, i, 1] = 0; * data[j, i, 2] = 0; * } */ } else { float stoppingPoint = 0; //print(" i is " + i); if (i < boundaryPointsModified.Count) { stoppingPoint = boundaryPointsModified.ElementAt(i).Value; } //print("Stoppping Point is " + stoppingPoint); if ((float)j <= stoppingPoint) { //print("j is "+j+" i is "+i+" red "+result[j, i].Red); data_model[j, i, 0] = 246; data_model[j, i, 1] = 246; data_model[j, i, 2] = 246; } } } } modelImage.Data = data_model; } // for (int run = 19; run >= 0; run--) // { if (min.Key < mid) { mid = (int)min.Value; } //print("mid is " + mid); for (int i = result.Cols - 1; i >= mid; i--) { for (int j = 0; j <= result.Rows - 1; j++) { // if (boundaryPointshorizontal.ContainsKey((float)i)) // { //float startingPoint = boundaryPointshorizontal[(float)i]; // print("Stoppping Point is " + stoppingPoint); /*startingPoint <= j */ /* if (data[j, i, 2] < 180) * { * data[j, i, 0] = 255; * data[j, i, 1] = 255; * data[j, i, 2] = 255; * * } * else * { * break; * } */ if (data[j, i, 2] >= 240) { boundaryPointsRed.Add(i, j); //print("i is " + i + " j is " + j); break; } // } } } //result.Data = data; // } int maxredx = 0; int maxredy = 0; for (int run = 19; run >= 0; run--) { for (int i = result.Cols - 1; i >= mid; i--) { for (int j = 0; j <= result.Rows - 1; j++) { if (boundaryPointsRed.ContainsKey(i)) { if (i > maxredx) { maxredx = i; } if (j > maxredy) { maxredy = j; } float stoppingPoint = boundaryPointsRed[i]; if ((float)j <= stoppingPoint /* && i != 600 && i != 612 */) { //print("j is "+j+" i is "+i+" red "+result[j, i].Red); data_model[j, i, 0] = 246; data_model[j, i, 1] = 246; data_model[j, i, 2] = 246; } } } } modelImage.Data = data_model; } for (int run = 19; run >= 0; run--) { for (int i = maxredy; i >= 0; i--) { for (int j = result.Cols - 1; j >= maxredx; j--) { data_model[i, j, 0] = 246; data_model[i, j, 1] = 246; data_model[i, j, 2] = 246; } } modelImage.Data = data_model; } for (int run = 19; run >= 0; run--) { for (int i = result.Rows - 1; i >= max.Value; i--) { for (int j = 0; j <= result.Cols - 1; j++) { data_model[i, j, 0] = 246; data_model[i, j, 1] = 246; data_model[i, j, 2] = 246; } } modelImage.Data = data_model; } for (int run = 19; run >= 0; run--) { for (int i = result.Cols - 1; i >= hmax.Value; i--) { for (int j = 0; j <= result.Rows - 1; j++) { data_model[j, i, 0] = 246; data_model[j, i, 1] = 246; data_model[j, i, 2] = 246; } } modelImage.Data = data_model; } return(modelImage); }
public static Image <Bgr, Byte> FAST(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage) { bool isFound = false; long matchTime; Stopwatch watch; HomographyMatrix homography = null; FastDetector fastCPU = new FastDetector(10, true); VectorOfKeyPoint modelKeyPoints; VectorOfKeyPoint observedKeyPoints; Matrix <int> indices; BriefDescriptorExtractor descriptor = new BriefDescriptorExtractor(); Matrix <byte> mask; int k = 2; double uniquenessThreshold = 0.8; watch = Stopwatch.StartNew(); //extract features from the object image modelKeyPoints = fastCPU.DetectKeyPointsRaw(modelImage, null); Matrix <Byte> modelDescriptors = descriptor.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // extract features from the observed image observedKeyPoints = fastCPU.DetectKeyPointsRaw(observedImage, null); Matrix <Byte> observedDescriptors = descriptor.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); BruteForceMatcher <Byte> matcher = new BruteForceMatcher <Byte>(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 FAST: " + matchTime + "ms\n"); _richTextBox1.AppendText("fitur model yang terdeteksi: " + modelKeyPoints.Size + "\n"); _richTextBox1.AppendText("match yang ditemukan: " + CvInvoke.cvCountNonZero(mask).ToString()); return(result); }