public void FindContourTest2() { Bitmap bmp = Accord.Imaging.Image.Clone(Properties.Resources.hand2); BlobCounter bc = new BlobCounter(bmp); bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); bc.ExtractBlobsImage(bmp, blobs[0], true); List<IntPoint> expected = bc.GetBlobsEdgePoints(blobs[0]); Bitmap blob = blobs[0].Image.ToManagedImage(); BorderFollowing bf = new BorderFollowing(); List<IntPoint> actual = bf.FindContour(blob); foreach (IntPoint point in expected) Assert.IsTrue(actual.Contains(point)); IntPoint prev = actual[0]; for (int i = 1; i < actual.Count; i++) { IntPoint curr = actual[i]; Assert.IsTrue(System.Math.Abs(prev.X - curr.X) <= 1 && System.Math.Abs(prev.Y - curr.Y) <= 1); prev = curr; } IntPoint first = actual[0]; IntPoint last = actual[actual.Count - 1]; Assert.IsTrue(System.Math.Abs(first.X - last.X) <= 1 && System.Math.Abs(first.Y - last.Y) <= 1); }
// Process image private void ProcessImage(Bitmap bitmap) { // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); // step 1 - turn background to black ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new IntRange(0, 64); colorFilter.Green = new IntRange(0, 64); colorFilter.Blue = new IntRange(0, 64); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace(bitmapData); // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); // step 3 - check objects' type and highlight SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(bitmap); Pen yellowPen = new Pen(Color.Yellow, 2); // circles Pen redPen = new Pen(Color.Red, 2); // quadrilateral Pen brownPen = new Pen(Color.Brown, 2); // quadrilateral with known sub-type Pen greenPen = new Pen(Color.Green, 2); // known triangle Pen bluePen = new Pen(Color.Blue, 2); // triangle for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); Accord.Point center; float radius; // is circle ? if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { g.DrawEllipse(yellowPen, (float)(center.X - radius), (float)(center.Y - radius), (float)(radius * 2), (float)(radius * 2)); } else { List<IntPoint> corners; // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get sub-type PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); Pen pen; if (subType == PolygonSubType.Unknown) { pen = (corners.Count == 4) ? redPen : bluePen; } else { pen = (corners.Count == 4) ? brownPen : greenPen; } g.DrawPolygon(pen, ToPointsArray(corners)); } } } yellowPen.Dispose(); redPen.Dispose(); greenPen.Dispose(); bluePen.Dispose(); brownPen.Dispose(); g.Dispose(); // put new image to clipboard Clipboard.SetDataObject(bitmap); // and to picture box pictureBox.Image = bitmap; UpdatePictureBoxPosition(); }