public static Bitmap AdaptiveSmoothing(Bitmap bmp) { // create filter AdaptiveSmoothing filter = new AdaptiveSmoothing(); // apply the filter filter.ApplyInPlace(bmp); return bmp; }
public Bitmap Detect(Bitmap bitmap) { Bitmap grayscaleBitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap); IFilter smoothingFilter = null; switch (_smoothMode) { case "None": smoothingFilter = null; break; case "Mean": smoothingFilter = new Mean(); break; case "Median": smoothingFilter = new Median(); break; case "Conservative": smoothingFilter = new ConservativeSmoothing(); break; case "Adaptive": smoothingFilter = new AdaptiveSmoothing(); break; case "Bilateral": smoothingFilter = new BilateralSmoothing(); break; } Bitmap smoothBitmap = smoothingFilter != null ? smoothingFilter.Apply(grayscaleBitmap) : grayscaleBitmap; IFilter edgeFilter = null; switch (_edgeMode) { case "Homogenity": edgeFilter = new HomogenityEdgeDetector(); break; case "Difference": edgeFilter = new DifferenceEdgeDetector(); break; case "Sobel": edgeFilter = new SobelEdgeDetector(); break; case "Canny": edgeFilter = new CannyEdgeDetector(); break; } Bitmap edgeBitmap = edgeFilter != null ? edgeFilter.Apply(smoothBitmap) : smoothBitmap; IFilter threshholdFilter = new Threshold(_threshold); Bitmap thresholdBitmap = _threshold == 0 ? edgeBitmap : threshholdFilter.Apply(edgeBitmap); BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = _minHeight; blobCounter.MinWidth = _minWidth; blobCounter.ProcessImage(thresholdBitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); Bitmap outputBitmap = new Bitmap(thresholdBitmap.Width, thresholdBitmap.Height, PixelFormat.Format24bppRgb); Graphics bitmapGraphics = Graphics.FromImage(outputBitmap); Bitmap inputBitmap = null; switch (_drawMode) { case "Original": inputBitmap = bitmap; break; case "Grayscale": inputBitmap = grayscaleBitmap; break; case "Smooth": inputBitmap = smoothBitmap; break; case "Edge": inputBitmap = edgeBitmap; break; case "Threshold": inputBitmap = thresholdBitmap; break; } if (inputBitmap != null) bitmapGraphics.DrawImage(inputBitmap, 0, 0); Pen nonConvexPen = new Pen(Color.Red, 2); Pen nonRectPen = new Pen(Color.Orange, 2); Pen cardPen = new Pen(Color.Blue, 2); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); List<IntPoint> cardPositions = new List<IntPoint>(); for (int i = 0; i < blobs.Length; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if ((subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rectangle) && corners.Count == 4) { // Check if its sideways, if so rearrange the corners so it's vertical. RearrangeCorners(corners); // Prevent detecting the same card twice by comparing distance against other detected cards. bool sameCard = false; foreach (IntPoint point in cardPositions) { if (corners[0].DistanceTo(point) < _minDistance) { sameCard = true; break; } } if (sameCard) continue; // Hack to prevent it from detecting smaller sections of the card instead of the whole card. if (GetArea(corners) < _minArea) continue; cardPositions.Add(corners[0]); bitmapGraphics.DrawPolygon(cardPen, ToPointsArray(corners)); } else { foreach (IntPoint point in edgePoints.Take(300)) { bitmapGraphics.DrawEllipse(nonRectPen, point.X, point.Y, 1, 1); } } } else { foreach (IntPoint point in edgePoints.Take(300)) { bitmapGraphics.DrawEllipse(nonConvexPen, point.X, point.Y, 1, 1); } } } bitmapGraphics.Dispose(); nonConvexPen.Dispose(); nonRectPen.Dispose(); cardPen.Dispose(); return outputBitmap; }