// Set monochromeImage to display by the control public int ScanImage(Bitmap monochromeImage) { this.hulls.Clear(); this.image = monochromeImage; this.blobCounter.ProcessImage(this.image); this.blobs = this.blobCounter.GetObjectsInformation(); var grahamScan = new GrahamConvexHull(); foreach (var blob in this.GetBlobs()) { List<IntPoint> leftEdge; List<IntPoint> rightEdge; List<IntPoint> topEdge; List<IntPoint> bottomEdge; // collect edge points this.blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); this.blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge); // find convex hull var edgePoints = new List<IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); List<IntPoint> hull = grahamScan.FindHull(edgePoints); this.hulls.Add(blob.ID, hull); } return this.blobs.Length; }
public ImageProcessor() { shapeChecker = new SimpleShapeChecker(); hullFinder = new GrahamConvexHull(); blobCounter = new BlobCounter(); HotGoal = 0; greenPen = new Pen(Color.FromArgb(0, 255, 0), 1); yellowPen = new Pen(Color.FromArgb(255, 255, 0), 1); redPen = new Pen(Color.FromArgb(255, 0, 0), 2); orangePen = new Pen(Color.FromArgb(255, 127, 0), 1); purplePen = new Pen(Color.FromArgb(102, 51, 153), 1); redBrush = new SolidBrush(Color.FromArgb(255, 0, 0)); blueBrush = new SolidBrush(Color.FromArgb(0, 0, 255)); }
public Bitmap ProcessFrame(Bitmap inputBitmap, int x, int y) { // Create an image for AForge to process Bitmap workingImage = new Bitmap(inputBitmap.Width, inputBitmap.Height); workingImage = AForge.Imaging.Image.Clone(inputBitmap, PixelFormat.Format24bppRgb); // Create a mask for ROI selection Rectangle roi = new Rectangle(x - 30, y-30, 80, 80); Crop roicrop = new Crop(roi); Bitmap outimage = roicrop.Apply(workingImage); BlobCounter blobCounter = new BlobCounter(); blobCounter.ObjectsOrder = ObjectsOrder.Area; Blob[] blobs; // Find the blobs blobCounter.ProcessImage(outimage); blobs = blobCounter.GetObjectsInformation(); List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[0]); GrahamConvexHull grahamScan = new GrahamConvexHull(); List<IntPoint> hullPoints = grahamScan.FindHull(edgePoints); Graphics g = Graphics.FromImage(outimage); Pen redPen = new Pen(Color.Red, 2); g.DrawPolygon(redPen, ToPointsArray(hullPoints)); //g.Clear(Color.Black); //g.DrawImage(handImage, x, y); //g.DrawRectangle(redPen, roi); //g.DrawEllipse(redPen, x, y, 20, 20); ResizeNearestNeighbor resizeFilter = new ResizeNearestNeighbor(160, 160); Bitmap resizedImage = resizeFilter.Apply(outimage); return resizedImage; }
// Set monochromeImage to display by the control public IList<Polygon> ScanImage(Bitmap monochromeImage) { this.hulls.Clear(); this.image = monochromeImage; this.blobCounter.ProcessImage(this.image); this.blobs = this.blobCounter.GetObjectsInformation(); var grahamScan = new GrahamConvexHull(); var polygons = new List<Polygon>(); foreach (var blob in this.GetBlobs()) { List<IntPoint> leftEdge; List<IntPoint> rightEdge; // collect edge points this.blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); // find convex hull var edgePoints = new List<IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); var hull = grahamScan.FindHull(edgePoints); this.hulls.Add(blob.ID, hull); var minX = edgePoints.Min(x => x.X); var minY = edgePoints.Min(x => x.Y); var maxY = edgePoints.Max(x => x.Y); var maxX = edgePoints.Max(x => x.X); polygons.Add(new Polygon(new Point(minX, minY), new Point(maxX, maxY))); } return polygons; }
// ========================================================================================================== // Components: // ========================================================================================================== private List<Shapes.Component> FindComponentsFunct(Bitmap bitmap) { // Locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 8; blobCounter.MinWidth = 8; blobCounter.ProcessImage(bitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); // create convex hull searching algorithm GrahamConvexHull hullFinder = new GrahamConvexHull(); ClosePointsMergingOptimizer optimizer1 = new ClosePointsMergingOptimizer(); FlatAnglesOptimizer optimizer2 = new FlatAnglesOptimizer(); List<Shapes.Component> Components = new List<Shapes.Component>(); // process each blob foreach (Blob blob in blobs) { List<IntPoint> leftPoints, rightPoints, edgePoints = new List<IntPoint>(); if ((blob.Rectangle.Height > 400) && (blob.Rectangle.Width > 600)) { break; // The whole image could be a blob, discard that } // get blob's edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); edgePoints.AddRange(leftPoints); edgePoints.AddRange(rightPoints); // blob's convex hull List<IntPoint> Outline = hullFinder.FindHull(edgePoints); optimizer1.MaxDistanceToMerge = 4; optimizer2.MaxAngleToKeep = 170F; Outline = optimizer2.OptimizeShape(Outline); Outline = optimizer1.OptimizeShape(Outline); // find Longest line segment float dist = 0; LineSegment Longest = new LineSegment(Outline[0], Outline[1]); LineSegment line; dist = Longest.Length; int LongestInd = 0; for (int i = 1; i < Outline.Count; i++) { if (i != Outline.Count - 1) { line = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } line = new LineSegment(Outline[i], Outline[0]); } if (line.Length > dist) { Longest = line; dist = line.Length; LongestInd = i; } } // Get the center point of it AForge.Point LongestCenter = new AForge.Point(); LongestCenter.X = (float)Math.Round((Longest.End.X - Longest.Start.X) / 2.0 + Longest.Start.X); LongestCenter.Y = (float)Math.Round((Longest.End.Y - Longest.Start.Y) / 2.0 + Longest.Start.Y); AForge.Point NormalStart = new AForge.Point(); AForge.Point NormalEnd = new AForge.Point(); // Find normal: // start= longest.start rotated +90deg relative to center // end= longest.end rotated -90deg and relative to center // If you rotate point (px, py) around point (ox, oy) by angle theta you'll get: // p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox // p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy // cos90 = 0, sin90= 1 => // p'x= -(py-oy) + ox= oy-py+ox, p'y= (px-ox)+ oy NormalStart.X = LongestCenter.Y - Longest.Start.Y + LongestCenter.X; NormalStart.Y = (Longest.Start.X - LongestCenter.X) + LongestCenter.Y; // cos-90=0, sin-90= -1 => // p'x= (py-oy) + ox // p'y= -(px-ox)+oy= ox-px+oy NormalEnd.X = (Longest.Start.Y - LongestCenter.Y) + LongestCenter.X; NormalEnd.Y = LongestCenter.X - Longest.Start.X + LongestCenter.Y; // Make line out of the points Line Normal = Line.FromPoints(NormalStart, NormalEnd); // Find the furthest intersection to the normal (skip the Longest) AForge.Point InterSection = new AForge.Point(); AForge.Point Furthest = new AForge.Point(); bool FurhtestAssinged = false; LineSegment seg; dist = 0; for (int i = 0; i < Outline.Count; i++) { if (i == LongestInd) { continue; } if (i != Outline.Count - 1) { seg = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } seg = new LineSegment(Outline[i], Outline[0]); } if (seg.GetIntersectionWith(Normal) == null) { continue; } InterSection = (AForge.Point)seg.GetIntersectionWith(Normal); if (InterSection.DistanceTo(LongestCenter) > dist) { Furthest = InterSection; FurhtestAssinged = true; dist = InterSection.DistanceTo(LongestCenter); } } // Check, if there is a edge point that is close to the normal even further AForge.Point fPoint = new AForge.Point(); for (int i = 0; i < Outline.Count; i++) { fPoint.X = Outline[i].X; fPoint.Y = Outline[i].Y; if (Normal.DistanceToPoint(fPoint) < 1.5) { if (fPoint.DistanceTo(LongestCenter) > dist) { Furthest = fPoint; FurhtestAssinged = true; dist = fPoint.DistanceTo(LongestCenter); } } } AForge.Point ComponentCenter = new AForge.Point(); if (FurhtestAssinged) { // Find the midpoint of LongestCenter and Furthest: This is the centerpoint of component ComponentCenter.X = (float)Math.Round((LongestCenter.X - Furthest.X) / 2.0 + Furthest.X); ComponentCenter.Y = (float)Math.Round((LongestCenter.Y - Furthest.Y) / 2.0 + Furthest.Y); // Alignment is the angle of longest double Alignment; if (Math.Abs(Longest.End.X - Longest.Start.X) < 0.001) { Alignment = 0; } else { Alignment = Math.Atan((Longest.End.Y - Longest.Start.Y) / (Longest.End.X - Longest.Start.X)); Alignment = Alignment * 180.0 / Math.PI; // in deg. } Components.Add(new Shapes.Component(ComponentCenter, Alignment, Outline, Longest, NormalStart, NormalEnd)); } } return Components; }
public void FindHullTest( ) { GrahamConvexHull grahamHull = new GrahamConvexHull( ); for ( int i = 0, n = pointsLists.Count; i < n; i++ ) { ComparePointsLists( grahamHull.FindHull( pointsLists[i] ), expectedHulls[i] ); } }
/** * Loops through our depth range filtered data and saves our tracked points */ private void ProcessTrackedPoints() { System.Drawing.Rectangle[] rects = pointTracker.GetObjectsRectangles(); Points.Clear(); float xPos, yPos; for (int i = 0; i < rects.Length; i++) { xPos = (((float)rects[i].X + ((float)rects[i].Width / 2)) / (float)trackingRegion.Width) * depthWidth; yPos = (((float)rects[i].Y + ((float)rects[i].Height / 2)) / (float)trackingRegion.Height) * depthHeight; Points.Add(new System.Drawing.Point((int)xPos, (int)yPos)); } // create convex hull searching algorithm GrahamConvexHull hullFinder = new GrahamConvexHull(); // lock image to draw on it BitmapData data = regionedBmp.LockBits( new Rectangle(0, 0, regionedBmp.Width, regionedBmp.Height), ImageLockMode.ReadWrite, regionedBmp.PixelFormat); // process each blob foreach (Blob blob in pointTracker.GetObjectsInformation()) { List<IntPoint> edgePoints = new List<IntPoint>(); List<IntPoint> leftPoints, rightPoints; // get blob's edge points pointTracker.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); edgePoints.AddRange(leftPoints); edgePoints.AddRange(rightPoints); // blob's convex hull List<IntPoint> hull = hullFinder.FindHull(edgePoints); Drawing.Polygon(data, hull, Color.Red); } regionedBmp.UnlockBits(data); }
// Set image to display by the control public int SetImage( Bitmap image ) { leftEdges.Clear( ); rightEdges.Clear( ); topEdges.Clear( ); bottomEdges.Clear( ); hulls.Clear( ); quadrilaterals.Clear( ); selectedBlobID = 0; this.image = AForge.Imaging.Image.Clone( image, PixelFormat.Format24bppRgb ); imageWidth = this.image.Width; imageHeight = this.image.Height; blobCounter.ProcessImage( this.image ); blobs = blobCounter.GetObjectsInformation( ); GrahamConvexHull grahamScan = new GrahamConvexHull( ); foreach ( Blob blob in blobs ) { List<IntPoint> leftEdge = new List<IntPoint>( ); List<IntPoint> rightEdge = new List<IntPoint>( ); List<IntPoint> topEdge = new List<IntPoint>( ); List<IntPoint> bottomEdge = new List<IntPoint>( ); // collect edge points blobCounter.GetBlobsLeftAndRightEdges( blob, out leftEdge, out rightEdge ); blobCounter.GetBlobsTopAndBottomEdges( blob, out topEdge, out bottomEdge ); leftEdges.Add( blob.ID, leftEdge ); rightEdges.Add( blob.ID, rightEdge ); topEdges.Add( blob.ID, topEdge ); bottomEdges.Add( blob.ID, bottomEdge ); // find convex hull List<IntPoint> edgePoints = new List<IntPoint>( ); edgePoints.AddRange( leftEdge ); edgePoints.AddRange( rightEdge ); List<IntPoint> hull = grahamScan.FindHull( edgePoints ); hulls.Add( blob.ID, hull ); // find quadrilateral List<IntPoint> quadrilateral = PointsCloud.FindQuadrilateralCorners( hull ); quadrilaterals.Add( blob.ID, quadrilateral ); // shift all points for vizualization IntPoint shift = new IntPoint( 1, 1 ); PointsCloud.Shift( leftEdge, shift ); PointsCloud.Shift( rightEdge, shift ); PointsCloud.Shift( topEdge, shift ); PointsCloud.Shift( bottomEdge, shift ); PointsCloud.Shift( hull, shift ); PointsCloud.Shift( quadrilateral, shift ); } UpdatePosition( ); Invalidate( ); return blobs.Length; }
private System.Drawing.Image ProcessBlobs(Bitmap image, Bitmap ProcessedImage, Input input) { Bitmap ResultImage; // our return image variable // Choose which view to overlay our data on if (NoFilters) { ResultImage = (Bitmap)image.Clone(); } else { ResultImage = new Bitmap(xMax / 2,yMax); } // Create the blob counter and get the blob info array for further processing BlobCounter blobCounter = new BlobCounter(); // We *COULD* filter blobs here, but as pointed out that blocks the ability to eventually twist the hand/fingers horizontally. //blobCounter.FilterBlobs = true; //blobCounter.MinHeight = minHeight; //blobCounter.MaxWidth = maxWidth; blobCounter.ProcessImage(ProcessedImage); Blob[] blobs = blobCounter.GetObjectsInformation(); // create convex hull searching algorithm GrahamConvexHull hullFinder = new GrahamConvexHull(); // Create graphics control to draw in the picture Graphics g = Graphics.FromImage(ResultImage); // Label the camfeeds just to prove this works right... g.DrawString(input.ToString(), new Font("Arial", 16), new SolidBrush(Color.Blue), new PointF(0, 0)); // process each blob foreach (Blob blob in blobs) { if (CheckBlob(blob)) { List<IntPoint> leftPoints, rightPoints; List<IntPoint> edgePoints = new List<IntPoint>(); // get blob's edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); edgePoints.AddRange(leftPoints); edgePoints.AddRange(rightPoints); // calculate the blob's convex hull List<IntPoint> hull = hullFinder.FindHull(edgePoints); // Calculate depth int pix = (int)CvInvoke.cvGet2D(disparity, blob.Rectangle.Top, ((blob.Rectangle.Left + blob.Rectangle.Right) / 2)).v0; // Draw the blob hull and id it with the width/height g.DrawPolygon(new Pen(Color.Blue), IntPointsToPointFs(hull.ToArray())); string coord = ""; coord += blob.Rectangle.Width.ToString() + ","; // X coord += blob.Rectangle.Height.ToString() + ","; // Y coord += pix.ToString(); // Z g.DrawString(coord, new Font("Arial", 16), new SolidBrush(Color.Blue), new PointF(hull[0].X, hull[0].Y)); // This next line is all we should need once done debugging/designing. Toss the image manipulation. hand.AddFinger(new System.Drawing.Point(((blob.Rectangle.Left + blob.Rectangle.Right) / 2), blob.Rectangle.Top), pix, (Hand.Input)input); } } return ResultImage; }
/// <summary> /// Event to trigger upon clicking the "Calibrate" button /// </summary> /// <param name="sender">Sender of the event</param> /// <param name="e">Event arguments</param> private void button1_Click(object sender, EventArgs e) { // what to do when progress changed (update the progress bar for example) ProgressChangedEventHandler prog = new ProgressChangedEventHandler( delegate(object o, ProgressChangedEventArgs args) { progress = args.ProgressPercentage; instructions.Text = string.Format("{0}% Completed", args.ProgressPercentage); }); // what to do when worker completes its task (notify the user) RunWorkerCompletedEventHandler compl = new RunWorkerCompletedEventHandler( delegate(object o, RunWorkerCompletedEventArgs args) { if (!args.Cancelled && (null == args.Error)) { instructions.Text = "Ready to go!"; detectionRate.Start(); Bitmap[,] samples = (Bitmap[,])args.Result; BackgroundWorker showRes = new BackgroundWorker(); showRes.DoWork += new DoWorkEventHandler(delegate(object obj, DoWorkEventArgs arguments) { try { Blob[] blobs; List<IntPoint> leftEdge, rightEdge, topEdge, bottomEdge; for (int i = 0; i < 10; i++) { //Build a convex hull around blobs //maxBlobFilter = new ExtractBiggestBlob(); Bitmap image = samples[0, i]; lock (image) { blobCounter.ProcessImage(image); blobs = blobCounter.GetObjectsInformation(); // lock image to draw on it BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat); GrahamConvexHull grahamScan = new GrahamConvexHull(); foreach (Blob blob in blobs) { // collect edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge); // find convex hull List<IntPoint> edgePoints = new List<IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); List<IntPoint> hull = grahamScan.FindHull(edgePoints); // Paint the control Drawing.Polygon(data, hull, Color.Red); Line l1, l2, l3; int vertexNum = hull.Count; for (int firstEdge = 0; firstEdge < vertexNum - 3; firstEdge++) { l1.start = hull.ElementAt(firstEdge); l1.end = hull.ElementAt(firstEdge + 1); for (int secondEdge = 1; secondEdge < vertexNum - 2; secondEdge++) { l2.start = hull.ElementAt(secondEdge); l2.end = hull.ElementAt(secondEdge); for (int thirdEdge = 2; thirdEdge < vertexNum - 1; thirdEdge++) { l3.start = hull.ElementAt(thirdEdge); l3.end = hull.ElementAt(thirdEdge); } } } } image.UnlockBits(data); } //trainingPic.Image = image; //System.Threading.Thread.Sleep(1000); } } catch (TargetInvocationException ex) { Console.Out.WriteLine(ex.Message); } }); showRes.WorkerReportsProgress = false; showRes.RunWorkerAsync(); bool working = showRes.IsBusy; } }); //trainingPic.Image = mirror.Apply(bgm.MotionFrame).ToManagedImage(); learner.Learn((frameWidth / 2) - ((int)calibrationBoxWidth.Value / 2), (frameHeight / 2) - 120, (int)calibrationBoxWidth.Value, 200, 1, getMovementImage, prog, compl); }