public static Bitmap FindColorCorrectedForBlob(FoundColorSpaces foundColorSpaces, Blob blob) { Bitmap bmp = foundColorSpaces.OriginalColorSpace.Clone(blob.Rectangle, foundColorSpaces.OriginalColorSpace.PixelFormat); return FindColorCorrectedForBlob(bmp); }
public static FoundBlobs FindLargest(FoundColorSpaces colorSpaces) { FoundBlobs foundBlobs = FindAny(colorSpaces); if(foundBlobs.Blobs.Length > 0) { foundBlobs.Blobs = new Blob[] { foundBlobs.Blobs.OrderByDescending(m => m.Area).First() }; } return foundBlobs; }
public static FoundBlobs Find(FoundColorSpaces colorSpaces, int maxWidth, int minWidth, int maxHeight, int minHeight, double minRatio, double maxRatio) { FoundBlobs foundBlobs = FindAny(colorSpaces); foundBlobs.Blobs = foundBlobs.Blobs.Where( m => m.Rectangle.Width < maxWidth && m.Rectangle.Width > minWidth && m.Rectangle.Height < maxHeight && m.Rectangle.Height > minHeight && m.Rectangle.Height / (m.Rectangle.Width * 1.0f) > minRatio && m.Rectangle.Height / (m.Rectangle.Width * 1.0f) < maxRatio).ToArray(); return foundBlobs; }
public static FoundBlobs FindAny(FoundColorSpaces colorSpaces) { FoundBlobs foundBlobs = new FoundBlobs(); SobelEdgeDetector edge = new SobelEdgeDetector(); Bitmap edges = edge.Apply(colorSpaces.GrayColorSpace); Threshold threshold = new Threshold(50); threshold.ApplyInPlace(edges); BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(edges); foundBlobs.Blobs = blobCounter.GetObjects(colorSpaces.GrayColorSpace, false).ToArray(); foundBlobs.BlobCounter = blobCounter; return foundBlobs; }
public static FoundBlobType Find(Bitmap bmp, FoundColorSpaces foundColorSpaces) { FoundBlobType foundBlobType = new FoundBlobType(); ResizeBicubic resize = new ResizeBicubic(30, 50); Bitmap resizedBitmap = resize.Apply(bmp); double blackPixelCount = 0; for (int y = 0; y < resizedBitmap.Height; y++) { for (int x = 0; x < resizedBitmap.Width; x++) { Color color = resizedBitmap.GetPixel(x, y); if (color.R == 0 && color.G == 0 && color.B == 0) { blackPixelCount++; } } } double total = (resizedBitmap.Width * resizedBitmap.Height * 1.0); double percentageBlack = blackPixelCount / total; int p0 = EdgeFoundAtX(resizedBitmap, 6); int p1 = EdgeFoundAtX(resizedBitmap, 16); int p2 = EdgeFoundAtX(resizedBitmap, 36); int p3 = EdgeFoundAtX(resizedBitmap, 43); if (percentageBlack < .6) { if (Math.Abs(p0 - p1) < 4 && Math.Abs(p2 - p0) < 4 && p0 > 0) { foundBlobType.ShapeType = ShapeTypeEnum.Pill; } else if (p0 < p1 && p2 <= p0) { foundBlobType.ShapeType = ShapeTypeEnum.Squiggle; } else if (p0 > p1 && p3 > p1) { foundBlobType.ShapeType = ShapeTypeEnum.Diamond; } } else { foundBlobType.ShapeType = ShapeTypeEnum.NotAType; } float darkestPixelBrightnessValue = float.MaxValue; float lightestPixelBrightnessValue = 0; float lightestHue = float.MaxValue; Bitmap corrected = foundColorSpaces.CorrectedRGBColorSpace; for (int y = 0; y < corrected.Height; y++) { for (int x = 0; x < corrected.Width; x++) { Color color = corrected.GetPixel(x, y); float brightness = color.GetBrightness(); float hue = color.GetHue(); if (brightness < darkestPixelBrightnessValue) { darkestPixelBrightnessValue = brightness; } if (brightness > lightestPixelBrightnessValue) { lightestPixelBrightnessValue = brightness; } if (hue < lightestHue) { lightestHue = hue; } } } float delta = (lightestPixelBrightnessValue - darkestPixelBrightnessValue); float darknessRange = lightestPixelBrightnessValue - (delta * .4f); foundBlobType.StrippedBitmap = new Bitmap(corrected.Width, corrected.Height, PixelFormat.Format24bppRgb); int redPixel = 0, greenPixel = 0, purplePixel = 0; foundBlobType.Histogram = new int[360]; for (int y = 0; y < corrected.Height; y++) { for (int x = 0; x < corrected.Width; x++) { Color color = corrected.GetPixel(x, y); if (color.GetBrightness() < darknessRange) { foundBlobType.StrippedBitmap.SetPixel(x, y, color); float hue = color.GetHue(); float sat = color.GetSaturation(); foundBlobType.Histogram[(int)hue]++; if (hue < 17 || hue > 329) { redPixel++; } else if (hue > 90 && hue < 187) { greenPixel++; } else if (hue < 31 || hue > 200) { purplePixel++; } } } } if (redPixel > greenPixel && redPixel > purplePixel) { foundBlobType.ColorType = ColorTypeEnum.Red; } else if (greenPixel > redPixel && greenPixel > purplePixel) { foundBlobType.ColorType = ColorTypeEnum.Green; } else if (purplePixel > redPixel && purplePixel > greenPixel) { foundBlobType.ColorType = ColorTypeEnum.Purple; } //bmp2.Save(@"c:\users\brush\desktop\brokenout\" + (Count++).ToString() + ".bmp"); return foundBlobType; }
public static FoundColorSpaces Find(Bitmap bmp) { FoundColorSpaces ret = new FoundColorSpaces(); ret.OriginalColorSpace = bmp; ret.GrayColorSpace = Grayscale.CommonAlgorithms.BT709.Apply(ret.OriginalColorSpace); CannyEdgeDetector edges = new CannyEdgeDetector(); Threshold threshold = new Threshold(); ret.Edges = threshold.Apply(edges.Apply(ret.GrayColorSpace)); ret.BinaryColorSpace = threshold.Apply(ret.GrayColorSpace); //ret.CorrectedRGBColorSpace = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb); return ret; }
public static Bitmap Find(Blob blob, BlobCounter blobCounter, FoundColorSpaces colorSpaces) { List<IntPoint> blobPoints = new List<IntPoint>(); List<IntPoint> leftPoints, rightPoints; blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); Bitmap bmp = new Bitmap(blob.Rectangle.Width, blob.Rectangle.Height, PixelFormat.Format24bppRgb); for (int c = 0; c < leftPoints.Count; c++) { IntPoint startLeft = leftPoints[c]; IntPoint endRight = rightPoints[c]; for (int x = startLeft.X; x <= endRight.X; x++) { blobPoints.Add(new IntPoint(x - blob.Rectangle.Left, startLeft.Y - blob.Rectangle.Top)); bmp.SetPixel(x - blob.Rectangle.Left, startLeft.Y - blob.Rectangle.Top, colorSpaces.OriginalColorSpace.GetPixel(x, startLeft.Y)); } } double[,] aData = new double[blobPoints.Count, 2]; double[,] eData = new double[blobPoints.Count, 2]; double[] bData = new double[blobPoints.Count]; double centroidX = 0; double centroidY = 0; double total = 0; for (int c = 0; c < blobPoints.Count; c++) { centroidX += blobPoints[c].X; centroidY += blobPoints[c].Y; total++; } centroidX /= total; centroidY /= total; for (int c = 0; c < blobPoints.Count; c++) { eData[c, 0] = blobPoints[c].X - centroidX; eData[c, 1] = blobPoints[c].Y - centroidY; aData[c, 0] = 1; aData[c, 1] = blobPoints[c].X; bData[c] = blobPoints[c].Y; } DenseMatrix E = DenseMatrix.OfArray(eData); DenseMatrix Eprime = (DenseMatrix)E.TransposeThisAndMultiply(E); DenseEvd eigen = new DenseEvd(Eprime); Vector<Complex> eigenValues = eigen.EigenValues(); int maxIndex = 0; double max = 0.0; for (int c = 0; c < eigenValues.Count; c++) { double eigenvalue = eigenValues[c].Real; if (eigenvalue > max) { max = eigenvalue; maxIndex = c; } } Matrix<double> eigenVectors = eigen.EigenVectors(); Vector<double> maxEigenVector = eigenVectors.Column(maxIndex); Matrix<double> xHat = DenseMatrix.OfColumns(2, 1, new List<Vector<double>>(new Vector<double>[] { maxEigenVector })); double radians = System.Math.Asin(xHat[0, 0]); double degrees = radians * (180 / System.Math.PI); // Why doesn't this work? //DenseMatrix A = DenseMatrix.OfArray(aData); //DenseVector b = new DenseVector(bData); //Matrix<double> xHat = (A.TransposeThisAndMultiply(A).Inverse() * A.Transpose() * b).ToColumnMatrix(); RotateBicubic rotate = new RotateBicubic(-degrees); bmp = rotate.Apply(bmp); return bmp; }