private EnclosingRectangle FindEnclosingRectangle(ref Image <Gray, byte> grayscaleImage, Point center, ref Image <Rgb, byte> debugImage, Rectangle roi) { var binaryThreshold = BinaryThreshold; var binaryThresholdImage = grayscaleImage.ThresholdBinary(new Gray(binaryThreshold), Grays.White); #region Debug Binary Image // Binary Threshold Image var binaryThresholdImageCopy = binaryThresholdImage.Copy(); Task.Factory.StartNew(() => { var bitmapSource = binaryThresholdImageCopy.ToBitmapSource(true); binaryThresholdImageCopy.Dispose(); return(bitmapSource); }).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion var floodFillImage = binaryThresholdImage.Copy(); binaryThresholdImage.Dispose(); var imageWidth = floodFillImage.Width; var imageHeight = floodFillImage.Height; MCvConnectedComp comp; // mask needs to be 2 pixels wider and 2 pixels taller var mask = new Image <Gray, byte>(imageWidth + 2, imageHeight + 2); CvInvoke.cvFloodFill(floodFillImage, center, new MCvScalar(255), new MCvScalar(FloodFillDifference), new MCvScalar(FloodFillDifference), out comp, CONNECTIVITY.FOUR_CONNECTED, FLOODFILL_FLAG.DEFAULT, mask); #region Debug Flood Fill Image //// Flood fill image //var maskCopy = floodFillImage.Copy(); //Task.Factory.StartNew(() => //{ // var bitmapSource = maskCopy.ToBitmapSource(true); // maskCopy.Dispose(); // return bitmapSource; //}).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion // shrink mask back to original grayscale image size mask.ROI = new Rectangle(1, 1, imageWidth, imageHeight); var contourBinaryImage = mask.Mul(255); #region Debug Output Binary Image //var maskCopy = contourBinaryImage.Copy(); //Task.Factory.StartNew(() => //{ // var bitmapSource = maskCopy.ToBitmapSource(true); // maskCopy.Dispose(); // return bitmapSource; //}).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion mask.Dispose(); floodFillImage.Dispose(); EnclosingRectangle enclosingRectangle = null; using (var storage = new MemStorage()) { for ( var contours = contourBinaryImage.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_EXTERNAL, storage); contours != null; contours = contours.HNext) { var contour = contours.ApproxPoly(contours.Perimeter * 0.05, storage); var contourBounds = contour.BoundingRectangle; if (contourBounds.Width + 5 >= roi.Width || contourBounds.Height + 5 >= roi.Height) { continue; } if (!EmguExtensions.IsRectangle(contour, 10.0)) { continue; } var edges = GetRightAngleEdges(contour); if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; debugImage.Draw(contour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), Rgbs.Cyan, 2); debugImage.Draw(contour.GetMinAreaRect(storage), Rgbs.Cyan, 2); DrawEdge(ref debugImage, edges[0], Rgbs.Red); DrawEdge(ref debugImage, edges[1], Rgbs.Green); debugImage.ROI = debugImageRoi; } enclosingRectangle = new EnclosingRectangle { Contour = contour, LongEdge = edges[0], ShortEdge = edges[1] }; } } contourBinaryImage.Dispose(); return(enclosingRectangle); }
internal void Sample(EnclosingRectangle rectangle) { DisplaySamples[SampleCounter] = rectangle; SampleCounter++; }
private EnclosingRectangle FindEnclosingRectangle(ref Image<Gray, byte> grayscaleImage, Point center, ref Image<Rgb, byte> debugImage, Rectangle roi) { var binaryThreshold = BinaryThreshold; var binaryThresholdImage = grayscaleImage.ThresholdBinary(new Gray(binaryThreshold), Grays.White); #region Debug Binary Image // Binary Threshold Image var binaryThresholdImageCopy = binaryThresholdImage.Copy(); Task.Factory.StartNew(() => { var bitmapSource = binaryThresholdImageCopy.ToBitmapSource(true); binaryThresholdImageCopy.Dispose(); return bitmapSource; }).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion var floodFillImage = binaryThresholdImage.Copy(); binaryThresholdImage.Dispose(); var imageWidth = floodFillImage.Width; var imageHeight = floodFillImage.Height; MCvConnectedComp comp; // mask needs to be 2 pixels wider and 2 pixels taller var mask = new Image<Gray, byte>(imageWidth + 2, imageHeight + 2); CvInvoke.cvFloodFill(floodFillImage, center, new MCvScalar(255), new MCvScalar(FloodFillDifference), new MCvScalar(FloodFillDifference), out comp, CONNECTIVITY.FOUR_CONNECTED, FLOODFILL_FLAG.DEFAULT, mask); #region Debug Flood Fill Image //// Flood fill image //var maskCopy = floodFillImage.Copy(); //Task.Factory.StartNew(() => //{ // var bitmapSource = maskCopy.ToBitmapSource(true); // maskCopy.Dispose(); // return bitmapSource; //}).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion // shrink mask back to original grayscale image size mask.ROI = new Rectangle(1, 1, imageWidth, imageHeight); var contourBinaryImage = mask.Mul(255); #region Debug Output Binary Image //var maskCopy = contourBinaryImage.Copy(); //Task.Factory.StartNew(() => //{ // var bitmapSource = maskCopy.ToBitmapSource(true); // maskCopy.Dispose(); // return bitmapSource; //}).ContinueWith(t => BinaryThresholdImageBitmapSource = t.Result); #endregion mask.Dispose(); floodFillImage.Dispose(); EnclosingRectangle enclosingRectangle = null; using (var storage = new MemStorage()) { for ( var contours = contourBinaryImage.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_EXTERNAL, storage); contours != null; contours = contours.HNext) { var contour = contours.ApproxPoly(contours.Perimeter * 0.05, storage); var contourBounds = contour.BoundingRectangle; if (contourBounds.Width + 5 >= roi.Width || contourBounds.Height + 5 >= roi.Height) continue; if (!EmguExtensions.IsRectangle(contour, 10.0)) continue; var edges = GetRightAngleEdges(contour); if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; debugImage.Draw(contour.GetConvexHull(ORIENTATION.CV_CLOCKWISE), Rgbs.Cyan, 2); debugImage.Draw(contour.GetMinAreaRect(storage), Rgbs.Cyan, 2); DrawEdge(ref debugImage, edges[0], Rgbs.Red); DrawEdge(ref debugImage, edges[1], Rgbs.Green); debugImage.ROI = debugImageRoi; } enclosingRectangle = new EnclosingRectangle { Contour = contour, LongEdge = edges[0], ShortEdge = edges[1] }; } } contourBinaryImage.Dispose(); return enclosingRectangle; }