/// <summary> /// Processes the specified SRC image. /// </summary> /// <param name="srcImage">The SRC image.</param> /// <remarks></remarks> public void Process(Bitmap srcImage) { resize.NewWidth = srcImage.Width / Scale; resize.NewHeight = srcImage.Height / Scale; FilteredBoard = resize.Apply(srcImage); ImageFilters.HSLFilter(FilteredBoard, targetHue, targetSat, targetBri, hueTol, satTol, briTol); median.ApplyInPlace(FilteredBoard); GaussianBlur blr = new GaussianBlur(1, 2); blr.ApplyInPlace(FilteredBoard); List <IntPoint> cors = new List <IntPoint>(); try { cors = quadFinder.ProcessImage(FilteredBoard); } catch { } if (ValidCorners(cors)) { EnlargeCorners(cors); SortCorners(cors); UpdateCorners(cors); } }
public void FindPeaksTest4() { Bitmap hand = Properties.Resources.rhand2; GaussianBlur median = new GaussianBlur(1.1); median.ApplyInPlace(hand); // Extract contour BorderFollowing bf = new BorderFollowing(20); List <IntPoint> contour = bf.FindContour(hand); hand = hand.Clone(new Rectangle(0, 0, hand.Width, hand.Height), PixelFormat.Format24bppRgb); // Find peaks KCurvature kcurv = new KCurvature(30, new DoubleRange(0, 45)); var peaks = kcurv.FindPeaks(contour); List <IntPoint> supports = new List <IntPoint>(); for (int i = 0; i < peaks.Count; i++) { int j = contour.IndexOf(peaks[i]); supports.Add(contour[(j + kcurv.K) % contour.Count]); supports.Add(contour[Accord.Math.Tools.Mod(j - kcurv.K, contour.Count)]); } // show(hand, contour, peaks, supports); Assert.AreEqual(1, peaks.Count); Assert.AreEqual(18, peaks[0].X); Assert.AreEqual(0, peaks[0].Y); }
void FilerImage() { // Copy Image to Bitmap System.Drawing.Rectangle ImageBounds = new System.Drawing.Rectangle(0, 0, Bitmap.Width, Bitmap.Height); System.Drawing.Imaging.ImageLockMode Mode = System.Drawing.Imaging.ImageLockMode.ReadWrite; System.Drawing.Imaging.PixelFormat Format = Bitmap.PixelFormat; System.Drawing.Imaging.BitmapData BitmapData = Bitmap.LockBits(ImageBounds, Mode, Format); System.IntPtr ptr = BitmapData.Scan0; System.Runtime.InteropServices.Marshal.Copy(FilterdAndCroppedDepthImage, 0, ptr, FilterdAndCroppedDepthImage.Length); Bitmap.UnlockBits(BitmapData); //Apply Filter Blur.ApplyInPlace(Bitmap); //Copy Bitmap back to Image BitmapData = Bitmap.LockBits(ImageBounds, Mode, Format); ptr = BitmapData.Scan0; System.Runtime.InteropServices.Marshal.Copy(ptr, FilterdAndCroppedDepthImage, 0, FilterdAndCroppedDepthImage.Length); Bitmap.UnlockBits(BitmapData); }
public static void NajdiCasRustuVmisce(string slozka, int i) { /* Definice rozostøovacího filtru */ GaussianBlur filterBlur = new GaussianBlur(10, 10); /* Definice modrého filtru */ ColorFiltering filterGreen = new ColorFiltering(); filterGreen.Red = new IntRange(55, 80); filterGreen.Green = new IntRange(55, 100); filterGreen.Blue = new IntRange(40, 65); /* Naètu si obrazky za každou misku */ string[] seznamObrazku = Directory.GetFiles(slozka, "*.png", SearchOption.TopDirectoryOnly); /* Bitmap image1 = (Bitmap)Bitmap.FromFile(seznamObrazku[42]); * Bitmap image2 = (Bitmap)Bitmap.FromFile(seznamObrazku[43]); * string nazevObr = ObecneMetody.DatumCasZNazvu(seznamObrazku[42], "\\", ".png"); * filterBlur.ApplyInPlace(image1); * image1.Save(slozka + "\\" + nazevObr + "_sedy.png");*/ foreach (string obrazek in seznamObrazku) { Bitmap image = (Bitmap)Bitmap.FromFile(obrazek); string nazevObr = ObecneMetody.DatumCasZNazvu(obrazek, "\\", ".png"); filterBlur.ApplyInPlace(image); //filterGreen.ApplyInPlace(image); image.Save(slozka + "\\" + nazevObr + "_sedy.png"); //Console.WriteLine(obrazek); } }
public void FindPeaksTest() { Bitmap hand = Properties.Resources.rhand; GaussianBlur median = new GaussianBlur(1.1); median.ApplyInPlace(hand); // Extract contour BorderFollowing bf = new BorderFollowing(1); List<IntPoint> contour = bf.FindContour(hand); hand = hand.Clone(new Rectangle(0, 0, hand.Width, hand.Height), PixelFormat.Format24bppRgb); // Find peaks KCurvature kcurv = new KCurvature(30, new DoubleRange(0, 45)); // kcurv.Suppression = 30; var peaks = kcurv.FindPeaks(contour); List<IntPoint> supports = new List<IntPoint>(); for (int i = 0; i < peaks.Count; i++) { int j = contour.IndexOf(peaks[i]); supports.Add(contour[(j + kcurv.K) % contour.Count]); supports.Add(contour[Accord.Math.Tools.Mod(j - kcurv.K, contour.Count)]); } // show(hand, contour, peaks, supports); Assert.AreEqual(2, peaks.Count); Assert.AreEqual(46, peaks[0].X); Assert.AreEqual(0, peaks[0].Y); Assert.AreEqual(2, peaks[1].X); Assert.AreEqual(11, peaks[1].Y); }
private void loadImage(string imageFileName) { // Clear everything radUpdateManual.Checked = true; m_snake.deleteAllPoints(); if (m_bmpOrig != null) { m_bmpOrig.Dispose(); m_bmpOrig = null; } if (m_bmpGray != null) { m_bmpGray.Dispose(); m_bmpGray = null; } if (m_bmpSmoo != null) { m_bmpSmoo.Dispose(); m_bmpSmoo = null; } if (m_bmpEdge != null) { m_bmpEdge.Dispose(); m_bmpEdge = null; } // Load image m_bmpOrig = (Bitmap)System.Drawing.Image.FromFile(imageFileName); m_imageFI = new FileInfo(imageFileName); this.Text = "Snake Demo: " + m_imageFI.Name + " (" + m_bmpOrig.Width.ToString() + "x" + m_bmpOrig.Height.ToString() + ", Scale: " + m_imageScale.ToString("0") + ")"; // Build grayscale image if (m_bmpOrig.PixelFormat == PixelFormat.Format8bppIndexed) { m_bmpGray = (Bitmap)m_bmpOrig.Clone(); } else { Grayscale filterGray = new Grayscale(0.257, 0.504, 0.098); m_bmpGray = filterGray.Apply(m_bmpOrig); } // Build smoothed imgage with a gaussian blur filter GaussianBlur filterGauss = new GaussianBlur(1, (int)numGauss.Value); m_bmpSmoo = filterGauss.Apply(m_bmpGray); // Build edges with a Sobel filter SobelEdgeDetector filterSobel = new SobelEdgeDetector(); m_bmpEdge = filterSobel.Apply(m_bmpSmoo); filterGauss.ApplyInPlace(m_bmpEdge); // Enabel controls btnDeleteSnake.Enabled = false; btnDoublePoints.Enabled = false; btnHalfPoints.Enabled = false; grpSnakeForces.Enabled = true; grpImageForce.Enabled = true; grpDisplay.Enabled = true; grpUpdate.Enabled = true; }
public Bitmap BlurImage(System.Drawing.Image imgOrigin) { Bitmap bmp = (Bitmap)imgOrigin; GaussianBlur _filterS = new GaussianBlur(); _filterS.ApplyInPlace(bmp); return(bmp); }
public static Bitmap GaussianBlur(Bitmap bmp, int value) { // create filter with kernel size equal to 11 // and Gaussia sigma value equal to 4.0 GaussianBlur filter = new GaussianBlur(value, 11); // apply the filter filter.ApplyInPlace(bmp); return(bmp); }
private void numGauss_ValueChanged(object sender, EventArgs e) { GaussianBlur filterGauss = new GaussianBlur(1, (int)numGauss.Value); m_bmpSmoo = filterGauss.Apply(m_bmpGray); SobelEdgeDetector filterSobel = new SobelEdgeDetector(); m_bmpEdge = filterSobel.Apply(m_bmpSmoo); filterGauss.ApplyInPlace(m_bmpEdge); Invalidate(); }
public static Bitmap PixelDiff(Bitmap a, Bitmap b) { var difference = new Difference(a); var dif = difference.Apply(b); gaussianBlur.ApplyInPlace(dif); Bitmap clone = Grayscale.CommonAlgorithms.Y.Apply(dif); threshold.ApplyInPlace(clone); fillHoles.ApplyInPlace(clone); return(clone); }
public string ImageWithLazyBlur() { if (_lazyBluredImage == null && !string.IsNullOrEmpty(Image)) { var blur = new GaussianBlur(1, 8); using (var ms = new MemoryStream(Convert.FromBase64String(Image))) using (var outStrm = new MemoryStream()) using (var png = new Bitmap(ms)) { blur.ApplyInPlace(png); png.Save(outStrm, System.Drawing.Imaging.ImageFormat.Png); _lazyBluredImage = Convert.ToBase64String(outStrm.ToArray()); } } return(_lazyBluredImage); }
public static void SaveAsBitmap(Tomogram tomogram, string path) { Color[] colors = new Color[tomogram.BackgroundDensity]; for (int c = 0; c < colors.Length; c++) { byte b = (byte)RandomNormal.Next(tomogram.Random, 85, 15); colors[c] = Color.FromArgb(b, b, b); } using (Bitmap bmp = new Bitmap(tomogram.Width, tomogram.Height)) { for (int y = 0, i = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++, i++) { int colorIndex = tomogram.Data[i]; if (colorIndex > 0 && colorIndex <= tomogram.BackgroundDensity) { bmp.SetPixel(x, y, colors[colorIndex - 1]); } } } GaussianBlur blur = new GaussianBlur(1, 8); blur.ApplyInPlace(bmp); for (int y = 0, i = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++, i++) { int colorIndex = tomogram.Data[i]; if (colorIndex == 0) { byte b = (byte)tomogram.Random.Next(50, 60); bmp.SetPixel(x, y, Color.FromArgb(b, b, b)); } } } blur = new GaussianBlur(1, 8); blur.ApplyInPlace(bmp); bmp.Save(path); } }
/// <summary> /// Processes the specified SRC image. /// </summary> /// <param name="srcImage">The SRC image.</param> /// <remarks></remarks> public void Process(Bitmap srcImage) { if (srcImage == null || srcImage.Width < 10 || srcImage.Height < 10) { return; } resize.NewWidth = srcImage.Width / Scale; resize.NewHeight = srcImage.Height / Scale; FilteredBoard = resize.Apply(srcImage); if (Enhance) { ImageFilters.FlattenLighting(FilteredBoard); } ImageFilters.HSLFilter(FilteredBoard, targetHue, targetSat, targetBri, hueTol, satTol, briTol); median.ApplyInPlace(FilteredBoard); GaussianBlur blr = new GaussianBlur(2, 2); blr.ApplyInPlace(FilteredBoard); TileBlobs.Clear(); try { BlobCounter.ProcessImage(FilteredBoard); Blob[] blobs = BlobCounter.GetObjectsInformation(); TileBlobs.Clear(); foreach (Blob b in blobs) { if (b.Area < 10) { continue; } TileBlobs.Add(b); } } catch { } }
private static Bitmap applyOutlineGlow(this Bitmap bitmap, Color shadowColor, double alpha = 1, double sigma = 1, int size = 15) { if (bitmap == null) { return(null); } var copy = (Bitmap)bitmap.Clone(); for (var x = 0; x < copy.Width; x++) { for (var y = 0; y < copy.Height; y++) { var pixel = copy.GetPixel(x, y); copy.SetPixel(x, y, Color.FromArgb(pixel.A, shadowColor)); } } var shadow = copy; var blur = new GaussianBlur(sigma, size); blur.ApplyInPlace(shadow); for (var x = 0; x < bitmap.Width; x++) { for (var y = 0; y < bitmap.Height; y++) { var originalPixel = bitmap.GetPixel(x, y); if (originalPixel.A != 0) { shadow.SetPixel(x, y, originalPixel); } else { var shadowPixel = shadow.GetPixel(x, y); if (shadowPixel.A != 0) { shadow.SetPixel(x, y, Color.FromArgb((int)(shadowPixel.A * alpha), shadowPixel)); } } } } return(shadow); }
private async Task CalibThread(FrameReadyEventArgs e) { Debug.WriteLine("Calibrating " + _calibrationStep); e.Frame.Bitmap.Save(@"C:\temp\aforge\src\img" + _calibrationStep + ".jpg"); //var stats = new ImageStatistics(e.Frame.Bitmap); // //var histogram = stats.Gray; ////Debug.WriteLine("Grey: Min: " + histogram.Min + " Max: " + histogram.Max + " Mean: " + histogram.Mean + //// " Dev: " + histogram.StdDev + " Median: " + histogram.Median); //var histogram = stats.Green; //Debug.WriteLine("Green: Min: " + histogram.Min + " Max: " + histogram.Max + " Mean: " + histogram.Mean + // " Dev: " + histogram.StdDev + " Median: " + histogram.Median); //histogram = stats.Blue; //Debug.WriteLine("Blue: Min: " + histogram.Min + " Max: " + histogram.Max + " Mean: " + histogram.Mean + // " Dev: " + histogram.StdDev + " Median: " + histogram.Median); //histogram = stats.Red; //Debug.WriteLine("Red: Min: " + histogram.Min + " Max: " + histogram.Max + " Mean: " + histogram.Mean + //e.Frame.Bitmap.Save(@"C:\temp\aforge\src\img" + _calibrationStep + ".jpg"); // " Dev: " + histogram.StdDev + " Median: " + histogram.Median); //e.NewImage.Save(@"C:\temp\aforge\src\img" + _calibrationStep + ".jpg"); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep == 3) { _cc.FrameReady -= BaseCalibration; // TODO //Grid.Calculate(); _vs.Close(); CalibrationCompleted(this, new EventArgs()); } else { //var diffBitmap = new Bitmap(1,1); //if(diffFilter.OverlayImage != null) // diffBitmap = diffFilter.Apply(e.NewImage); //diffBitmap.Save(@"C:\temp\aforge\diff\img" + _calibrationStep + ".jpg"); if (_calibrationStep > 2) { _vs.Clear(); FillRects(); //var gf = new ColorFiltering(new IntRange(0, 255), //(int) stats.Red.Mean), // new IntRange((int) (stats.Green.Mean + ColorDiff), 255), // new IntRange(0, 255));//(int) stats.Blue.Mean)); //var bf = new ColorFiltering(new IntRange(0, 255),//(int)stats.Red.Mean), // new IntRange(0, 255),//(int) stats.Green.Mean), // new IntRange((int) stats.Blue.Mean + ColorDiff, 255)); // create color Channel images var gbm = PartiallyApplyAvgFilter(e.Frame.Bitmap, Channels.Green, 8, 8, 8); gbm.Save(@"C:\temp\aforge\gimg\img" + _calibrationStep + ".jpg"); var bbm = PartiallyApplyAvgFilter(e.Frame.Bitmap, Channels.Blue, 8, 8, 8); bbm.Save(@"C:\temp\aforge\bimg\img" + _calibrationStep + ".jpg"); var gblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 30, MinHeight = 15, MaxWidth = 30, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; gblobCounter.ProcessImage(gbm); var bblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 30, MinHeight = 15, MaxWidth = 30, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; bblobCounter.ProcessImage(bbm); ProcessBlobs(gblobCounter, 0); ProcessBlobs(bblobCounter, 1); _calibrationStep++; } else { switch (_calibrationStep) { case 2: // identify screen bounds //var thresholdFilter = new Threshold(50); //thresholdFilter.ApplyInPlace(diffBitmap); //var cf = new ColorFiltering(new IntRange(0, 255), //red is bad // new IntRange((int) stats.Green.Mean + MeanDiff, 255), // new IntRange((int) stats.Blue.Mean + MeanDiff, 255)); //var bm = cf.Apply(e.NewImage); //var bm = PartiallyApplyAvgFilter(e.Frame.Bitmap, Channels.GreenAndBlue, 2, 2, MeanDiff); var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); bm.ToManagedImage().Save(@"C:\temp\aforge\diff.jpg"); var blobs = blobCounter.GetObjectsInformation(); int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 10 && Grid.BottomLeft.X > 10 && Grid.BottomRight.X < _vs.Width - 10 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 10 && Grid.BottomLeft.Y < _vs.Height - 10 && Grid.BottomRight.Y < _vs.Height - 10 && Grid.TopLeft.X < Grid.BottomRight.X && blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); FillRects(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); } else { _calibrationStep = 0; _errors++; } break; case 1: diffFilter.OverlayImage = e.Frame.Bitmap; //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, (int)_vs.Width, (int)_vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } } Debug.WriteLine("Releasing"); await Task.Delay(100); _sem.Release(); }
private async Task CalibThread(FrameReadyEventArgs e) { try { if (_errors > MaxErrorCount) { _cc.FrameReady -= BaseCalibration; _vs.Close(); Console.WriteLine("Calibration impossible"); } if (_calibrationStep == CalibrationFrames) { _cc.FrameReady -= BaseCalibration; _vs.Close(); Console.WriteLine("Calibration complete"); CalibrationCompleted(this, new EventArgs()); } else { switch (_calibrationStep) { // get the corners from the difference image case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); bm = _diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && //blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: // draw second image, store the first _diffFilter.OverlayImage = e.Frame.Bitmap; _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; //draw the first image case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height) { ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height) }; var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } await Task.Delay(MillisecondsDelay); } finally { _sem.Release(); } }
public static Image ApplyImageProperties(byte[] blobContent, ImageProperties properties) { Bitmap image = null; try { using (var ms = new MemoryStream(blobContent)) { image = (Bitmap)System.Drawing.Image.FromStream(ms, false, false); image = AForge.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb); if (properties.Crop != null) { AForge.Imaging.Filters.Crop filter = new AForge.Imaging.Filters.Crop(new Rectangle(properties.Crop.XOffset, properties.Crop.YOffset, properties.Crop.CropWidth, properties.Crop.CropHeight)); image = filter.Apply(image); } if (properties.ImageWidth != properties.OriginalWidth || properties.ImageHeight != properties.OriginalHeight) { var filter = new ResizeBicubic(properties.ImageWidth, properties.ImageHeight); image = filter.Apply(image); } if (properties.Colors != null) { if (properties.Colors.TransparentColor != null) { image.MakeTransparent(ColorTranslator.FromHtml("#" + properties.Colors.TransparentColor)); } var brightness = properties.Colors.Brightness; var bfilter = new BrightnessCorrection(brightness); bfilter.ApplyInPlace(image); var contrast = properties.Colors.Contrast; var cfilter = new ContrastCorrection(contrast); cfilter.ApplyInPlace(image); if (properties.Colors.Hue != 0) { var hue = properties.Colors.Hue; HueModifier filter = new HueModifier(hue); filter.ApplyInPlace(image); } var saturation = properties.Colors.Saturation; var sfilter = new SaturationCorrection(saturation * 0.01f); sfilter.ApplyInPlace(image); } # region Effects if (!String.IsNullOrEmpty(properties.Effects)) { var effects = properties.Effects.Split(';'); foreach (var item in effects) { switch (item) { case "Grayscale": var g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); break; case "Sepia": var s = new Sepia(); image = AForge.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb); s.ApplyInPlace(image); break; case "Rotate Channels": image = AForge.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb); var r = new RotateChannels(); r.ApplyInPlace(image); break; case "Invert": var i = new Invert(); i.ApplyInPlace(image); break; case "Blur": var b = new Blur(); b.ApplyInPlace(image); break; case "Gaussian Blur": var gb = new GaussianBlur(4, 11); gb.ApplyInPlace(image); break; case "Convolution": int[,] kernel = { { -2, -1, 0 }, { -1, 1, 1 }, { 0, 1, 2 } }; var c = new Convolution(kernel); c.ApplyInPlace(image); break; case "Edges": var e = new Edges(); e.ApplyInPlace(image); break; } } } # endregion } } catch (Exception) {
private async Task CalibThread(FrameReadyEventArgs e) { Debug.WriteLine("Calibrating " + _calibrationStep + " "); e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep < 10?"0":"") + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep > CalibrationFrames) { // A concurrency problem, do nothing } if (_calibrationStep == CalibrationFrames) { _cc.FrameReady -= BaseCalibration; _calibrationStep++; //Grid.Calculate(); _vs.Close(); CalibrationCompleted(this, new EventArgs()); } else { if (_calibrationStep > 2) { // analyse diffimage _vs.Clear(); var img = diffFilter.Apply(e.Frame.Bitmap); var mf = new GaussianBlur(0.6, 5); var gf = Grayscale.CommonAlgorithms.BT709; #if DEBUG actImg = (Bitmap)img.Clone(); #endif img = gf.Apply(img); var stats = new ImageStatistics(img); mf.ApplyInPlace(img); mf = new GaussianBlur(0.7, 7); mf.ApplyInPlace(img); var tf = new Threshold((int)(stats.GrayWithoutBlack.Mean + stats.GrayWithoutBlack.StdDev * 2.0)); tf.ApplyInPlace(img); img.Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.MemoryBmp); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 30, MinHeight = 10, MaxWidth = 30, MinWidth = 10, FilterBlobs = true, CoupledSizeFiltering = false }; blobCounter.ProcessImage(img); if (ProcessBlobs(blobCounter)) { _calibrationStep++; } else { _errors++; } #if DEBUG actImg.Save(@"C:\temp\daforge\squares\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); #endif DrawMarkers(); } else { switch (_calibrationStep) { case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(0.8, 5); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, MinHeight = 200, MinWidth = 300, //BackgroundThreshold = Color.FromArgb(255, 20, 20, 50), //CoupledSizeFiltering = false, FilterBlobs = true }; blobCounter.ProcessImage(bm); bm.ToManagedImage() .Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); DrawMarkers(); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; } break; case 1: diffFilter.OverlayImage = e.Frame.Bitmap; //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg); //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); DrawInverted(0, 0, _vs.Width, _vs.Height); _vs.Draw(); _calibrationStep++; break; case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height); var thread = new Thread(() => { _vs.Show(); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); DrawBackground(); _vs.Draw(); _calibrationStep++; break; } } } Debug.WriteLine("Releasing"); await Task.Delay(500); _sem.Release(); }
private Bitmap detectQuads(Bitmap bitmap) { var cardArtBitmap = bitmap; try { /* * This code works and crops well on 80% of the images but we need 100% * */ var width = bitmap.Width + bitmap.Width / 2; var height = bitmap.Height + bitmap.Height / 2; // Create a compatible bitmap var dest = new Bitmap(width, height, bitmap.PixelFormat); var gd = Graphics.FromImage(dest); dest.Dispose(); gd.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height); // Greyscale filteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap); // Contrast //ContrastStretch filter = new ContrastStretch(); //filter.ApplyInPlace(filteredBitmap); var cutMargin = 80; // split the image to avoid the textbox beeing detected var cropFilterPre = new Crop(new Rectangle(0, cutMargin, filteredBitmap.Width, filteredBitmap.Height / 100 * 60)); filteredBitmap = cropFilterPre.Apply(filteredBitmap); // edge filter var edgeFilter = new SobelEdgeDetector(); // edgeFilter.ApplyInPlace(filteredBitmap); // Threshhold filter var threshholdFilter = new Threshold(190); threshholdFilter.ApplyInPlace(filteredBitmap); var bitmapData = filteredBitmap.LockBits( new Rectangle(0, 0, filteredBitmap.Width, filteredBitmap.Height), ImageLockMode.ReadWrite, filteredBitmap.PixelFormat); var blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 200; blobCounter.MinWidth = 200; blobCounter.ProcessImage(bitmapData); var blobs = blobCounter.GetObjectsInformation(); filteredBitmap.UnlockBits(bitmapData); var shapeChecker = new SimpleShapeChecker(); /*var bm = new Bitmap(filteredBitmap.Width, filteredBitmap.Height, PixelFormat.Format24bppRgb); * * var g = Graphics.FromImage(bm); * g.DrawImage(filteredBitmap, 0, 0); * * var pen = new Pen(Color.Red, 5); * //var cardPositions = new List<IntPoint>();*/ // Loop through detected shapes for (int i = 0, n = blobs.Length; i < n; i++) { var edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> corners; var sameCard = false; // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get sub-type var subType = shapeChecker.CheckPolygonSubType(corners); // Only return 4 corner rectanges if ((subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rectangle) && corners.Count == 4) { // Hack to prevent it from detecting smaller sections of the card instead of the art if (GetArea(corners) < 120000) { continue; } //debug crap /*Bitmap newImage = filteredBitmap; * Random rnd = new Random(); * newImage.Save(@"X:\" + rnd.Next() + ".jpg", ImageFormat.Jpeg);*/ var x = corners[0].X; var y = corners[0].Y + cutMargin; var x2 = corners[2].X - corners[0].X; var y2 = corners[2].Y - (corners[0].Y + 0); if (x2 < 0 || y2 < 0) { x = corners[1].X; y = corners[1].Y + cutMargin; x2 = corners[3].X - corners[1].X; y2 = corners[3].Y - (corners[1].Y + 0); } var cropframe = new Rectangle(x, y, x2, y2); var gbfilter = new GaussianBlur(1, 5); gbfilter.ApplyInPlace(bitmap); var cropFilter = new Crop(cropframe); cardArtBitmap = cropFilter.Apply(bitmap); bitmap.Dispose(); // pen.Dispose(); // g.Dispose(); gd.Dispose(); filteredBitmap.Dispose(); return(cardArtBitmap); } } } Console.WriteLine("Fallback Triggered!"); var gfilter = new GaussianBlur(1, 5); gfilter.ApplyInPlace(bitmap); //Fallback default crop, assumes XLHQ CCGHQ images var cropFilterFallback = new Crop(new Rectangle(88, 121, 564, 440)); cardArtBitmap = cropFilterFallback.Apply(bitmap); bitmap.Dispose(); //pen.Dispose(); //g.Dispose(); gd.Dispose(); filteredBitmap.Dispose(); } catch (Exception e) { throw; } return(cardArtBitmap); }
// New frame received by the player private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image) { lock (this) { if (tracker == null) { return; } if (form != null && !form.IsDisposed) { form.Image = image; } BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat); UnmanagedImage img = new UnmanagedImage(data); tracker.ComputeOrientation = showAngle; tracker.ProcessFrame(img); Rectangle rect = tracker.TrackingObject.Rectangle; UnmanagedImage hand = tracker.TrackingObject.Image; if (hand != null && (showContour || showFingertips)) { UnmanagedImage grayhand = Grayscale.CommonAlgorithms.BT709.Apply(hand); blur.ApplyInPlace(grayhand); List <IntPoint> contour = bf.FindContour(grayhand); for (int i = 0; i < contour.Count; i++) { contour[i] += new IntPoint(rect.X, rect.Y); } List <IntPoint> peaks = kcurv.FindPeaks(contour); if (showContour) { cmarker.Points = contour; cmarker.ApplyInPlace(img); } if (showFingertips) { pmarker.Points = peaks; pmarker.ApplyInPlace(img); } } if (showRectangle) { RectanglesMarker marker = new RectanglesMarker(rect); marker.ApplyInPlace(img); } if (showAngle) { LineSegment axis = tracker.TrackingObject.GetAxis(AxisOrientation.Vertical); if (axis != null) { // Draw X axis Drawing.Line(img, axis.Start.Round(), axis.End.Round(), Color.Red); } } image.UnlockBits(data); } }
private async Task CalibThread(FrameReadyEventArgs e) { //Debug.WriteLine("Calibrating " + _calibrationStep + " " + _drawing); //e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep<10?"0":"") + _calibrationStep + "-" + (_drawing?"1":"0") + "-" + _errors + ".jpg", ImageFormat.Jpeg); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep == CalibrationFrames) { _cc.FrameReady -= BaseCalibration; // TODO //Grid.Calculate(); //Grid.PredictFromCorners(); _vs.Close(); Console.WriteLine("Calibration complete"); CalibrationCompleted(this, new EventArgs()); } else { switch (_calibrationStep) { // get the corners from the difference image case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); //bm.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && //blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: // draw second image, store the first diffFilter.OverlayImage = e.Frame.Bitmap; //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg); //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; //draw the first image case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height); var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } Debug.WriteLine("Releasing"); await Task.Delay(500); _sem.Release(); }
public List <IntPoint> ProcessImage(UnmanagedImage image) { // check image format if ( (image.PixelFormat != PixelFormat.Format8bppIndexed) && (image.PixelFormat != PixelFormat.Format24bppRgb) && (image.PixelFormat != PixelFormat.Format32bppRgb) && (image.PixelFormat != PixelFormat.Format32bppArgb) ) { throw new UnsupportedImageFormatException("Unsupported pixel format of the source image."); } // make sure we have grayscale image UnmanagedImage grayImage = null; grayImage = image.PixelFormat == PixelFormat.Format8bppIndexed ? image : Grayscale.CommonAlgorithms.BT709.Apply(image); // get source image size int width = grayImage.Width; int height = grayImage.Height; int stride = grayImage.Stride; int offset = stride - width; // 1. Calculate partial differences UnmanagedImage diffx = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed); UnmanagedImage diffy = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed); UnmanagedImage diffxy = UnmanagedImage.Create(width, height, PixelFormat.Format8bppIndexed); unsafe { // Compute dx and dy byte *src = (byte *)grayImage.ImageData.ToPointer(); byte *dx = (byte *)diffx.ImageData.ToPointer(); byte *dy = (byte *)diffy.ImageData.ToPointer(); // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, src++, dx++, dy++) { // TODO: Place those verifications // outside the innermost loop if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { *dx = *dy = 0; continue; } int h = -(src[-stride - 1] + src[-1] + src[stride - 1]) + (src[-stride + 1] + src[+1] + src[stride + 1]); *dx = (byte)(h > 255 ? 255 : h < 0 ? 0 : h); int v = -(src[-stride - 1] + src[-stride] + src[-stride + 1]) + (src[+stride - 1] + src[+stride] + src[+stride + 1]); *dy = (byte)(v > 255 ? 255 : v < 0 ? 0 : v); } src += offset; dx += offset; dy += offset; } // Compute dxy dx = (byte *)diffx.ImageData.ToPointer(); var dxy = (byte *)diffxy.ImageData.ToPointer(); // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, dx++, dxy++) { if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { *dxy = 0; continue; } int v = -(dx[-stride - 1] + dx[-stride] + dx[-stride + 1]) + (dx[+stride - 1] + dx[+stride] + dx[+stride + 1]); *dxy = (byte)(v > 255 ? 255 : v < 0 ? 0 : v); } dx += offset; dxy += offset; } } // 2. Smooth the diff images if (_sigma > 0.0) { GaussianBlur blur = new GaussianBlur(_sigma); blur.ApplyInPlace(diffx); blur.ApplyInPlace(diffy); blur.ApplyInPlace(diffxy); } // 3. Compute Harris Corner Response float[,] H = new float[height, width]; unsafe { byte *ptrA = (byte *)diffx.ImageData.ToPointer(); byte *ptrB = (byte *)diffy.ImageData.ToPointer(); byte *ptrC = (byte *)diffxy.ImageData.ToPointer(); float M, A, B, C; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { A = *(ptrA++); B = *(ptrB++); C = *(ptrC++); // Harris corner measure M = (A * B - C * C) - (_k * ((A + B) * (A + B))); if (M > _threshold) { H[y, x] = M; } else { H[y, x] = 0; } } ptrA += offset; ptrB += offset; ptrC += offset; } } // Free resources diffx.Dispose(); diffy.Dispose(); diffxy.Dispose(); if (image.PixelFormat != PixelFormat.Format8bppIndexed) { grayImage.Dispose(); } // 4. Suppress non-maximum points List <IntPoint> cornersList = new List <IntPoint>(); // for each row for (int y = _r, maxY = height - _r; y < maxY; y++) { // for each pixel for (int x = _r, maxX = width - _r; x < maxX; x++) { float currentValue = H[y, x]; // for each windows' row for (int i = -_r; (currentValue != 0) && (i <= _r); i++) { // for each windows' pixel for (int j = -_r; j <= _r; j++) { if (H[y + i, x + j] > currentValue) { currentValue = 0; break; } } } // check if this point is really interesting if (currentValue != 0) { cornersList.Add(new IntPoint(x, y)); } } } return(cornersList); }
private async Task CalibThread(FrameReadyEventArgs e) { Debug.WriteLine("Calibrating " + _calibrationStep + " " + _drawing); e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep < 10?"0":"") + _calibrationStep + "-" + (_drawing?"1":"0") + "-" + _errors + ".jpg", ImageFormat.Jpeg); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep == CalibrationFrames && !_drawing) { _cc.FrameReady -= BaseCalibration; // TODO //Grid.Calculate(); _vs.Close(); CalibrationCompleted(this, new EventArgs()); } else { if (_calibrationStep > 2) { if (_drawing) { // draw diffimage _drawing = false; _vs.Clear(); FillRects(); diffFilter.OverlayImage = e.Frame.Bitmap; } else { // analyse diffimage _calibrationStep++; _drawing = true; _vs.Clear(); FillRects(); _calibrationStep--; var gbm = diffFilter.Apply(e.Frame.Bitmap); gbm.Save(@"C:\temp\daforge\diff\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); #if DEBUG actImg = (Bitmap)gbm.Clone(); #endif var d = UnmanagedImage.FromManagedImage(gbm); var stats = new ImageStatistics(d); var gcf = new ColorFiltering(new IntRange(0, 255), new IntRange((int)(stats.GreenWithoutBlack.Mean + stats.GreenWithoutBlack.StdDev + 5), 255), new IntRange(0, 255)); var bcf = new ColorFiltering(new IntRange(0, 255), new IntRange(0, 255), new IntRange((int)(stats.BlueWithoutBlack.Mean + stats.BlueWithoutBlack.StdDev), 255)); //Debug.WriteLine("Green: " + stats.GreenWithoutBlack.Median + " Blue: " + stats.BlueWithoutBlack.Median); //Debug.WriteLine("Green: " + stats.GreenWithoutBlack.Mean + " Blue: " + stats.BlueWithoutBlack.Mean); var bf = new Difference(gcf.Apply(d)); bcf.ApplyInPlace(d); bf.ApplyInPlace(d); d.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); stats = new ImageStatistics(d); gcf = new ColorFiltering(new IntRange(0, 255), new IntRange((int)stats.GreenWithoutBlack.Mean, 255), new IntRange(0, 255)); bcf = new ColorFiltering(new IntRange(0, 255), new IntRange(0, 255), new IntRange((int)stats.BlueWithoutBlack.Mean, 255)); // split channels var bbm = bcf.Apply(d); bbm.ToManagedImage().Save(@"C:\temp\daforge\bimg\img" + _calibrationStep + ".jpg", ImageFormat.Bmp); gcf.ApplyInPlace(d); d.ToManagedImage().Save(@"C:\temp\daforge\gimg\img" + _calibrationStep + ".jpg", ImageFormat.Bmp); var gblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 60, MinHeight = 15, MaxWidth = 60, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; gblobCounter.ProcessImage(d); var bblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 60, MinHeight = 15, MaxWidth = 60, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; bblobCounter.ProcessImage(bbm); ProcessBlobs(gblobCounter, 0); ProcessBlobs(bblobCounter, 1); #if DEBUG actImg.Save(@"C:\temp\daforge\squares\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); #endif _calibrationStep++; } } else { switch (_calibrationStep) { case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); bm.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _drawing = true; _vs.Clear(); FillRects(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); //_mapper.PredictFromCorners(); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: diffFilter.OverlayImage = e.Frame.Bitmap; //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg); //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height); _mapper = new CornerBarycentricMapper(Grid); var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } } Debug.WriteLine("Releasing"); await Task.Delay(500); _sem.Release(); }
/* Metoda, která dostane na vstup název obrazku na kterém má najít modrou misku a vrátí souøadnici levého horního rohu, šíøku a výšku. */ public static int[] DetekujModryOkrajObrazku(string obrazek) { /* Obrázek naètu dvakrát - na prvním provádím úpravy a druhý pak oøežu a uložím. */ Bitmap image = (Bitmap)Bitmap.FromFile(obrazek); Bitmap puvodniImage = (Bitmap)Bitmap.FromFile(obrazek); /* Definice pomocných promìnných: */ int[] souradniceRozmeryOrezu = new int[4]; int levyHorniX = 0; int levyHorniY = 0; /* Definice rozostøovacího filtru */ GaussianBlur filterBlur = new GaussianBlur(4, 11); /* Definice modrého filtru */ ColorFiltering filterBlue = new ColorFiltering(); filterBlue.Red = new IntRange(18, 35); filterBlue.Green = new IntRange(23, 40); filterBlue.Blue = new IntRange(40, 85); /* Definice hnìdého filtru */ ColorFiltering filterBrown = new ColorFiltering(); filterBrown.Red = new IntRange(35, 45); filterBrown.Green = new IntRange(32, 42); filterBrown.Blue = new IntRange(30, 40); /* Aplikace modrého filtru - vytáhne mi z pùvodního obrázku modrou barvu. */ filterBlue.ApplyInPlace(image); /* Na vytáhnutou modrou vrstvu aplikuji rozostøení abych v nìm mohl vyhledat obdélník. */ filterBlur.ApplyInPlace(image); /* Definice vyhledáváèe obdelníkù. */ BlobCounter bc = new BlobCounter(); bc.FilterBlobs = true; bc.MinHeight = 500; bc.MinWidth = 500; /* Aplikce vyhledávaèe obdelníkù. */ bc.ProcessImage(image); Blob[] blobs = bc.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); foreach (var blob in blobs) { List <IntPoint> edgePoints = bc.GetBlobsEdgePoints(blob); List <IntPoint> cornerPoints; /* kontrola jestli nalezený obdelník je ctyruhelnik a do pomocné promìnné doplnìní jeho rohových bodù. */ if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints)) { /* Kontrola jestli nalezený obdelník je fakt obdelník. */ if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { /* procházím nalezené souøadnice a vytvoøím si z nich kolekci bodù, podle kterých pak oøežu modrý obdelník. */ List <System.Drawing.Point> Points = new List <System.Drawing.Point>(); foreach (var point in cornerPoints) { Points.Add(new System.Drawing.Point(point.X, point.Y)); } /* Tady zpracuju rohove body a vypocitam si vzdalenosti */ int sirkaModrehoObdelnika = (Points[2].X - Points[0].X); int vyskaModrehoObdelnika = (Points[3].Y - Points[1].Y); levyHorniX = Points[0].X; levyHorniY = Points[1].Y; /* Oøežu pùvodní obrázek podle získaných rozmìrù modrého okraje. */ puvodniImage = puvodniImage.Clone(new Rectangle(levyHorniX, levyHorniY, sirkaModrehoObdelnika, vyskaModrehoObdelnika), puvodniImage.PixelFormat); /* Upravovaný obrázek nahradím oøezem pùvodního - chystám se na nìm hledat ještì šedou misku, kterou to oøežu ještì lépe. */ image = puvodniImage.Clone(new Rectangle(0, 0, puvodniImage.Width, puvodniImage.Height), puvodniImage.PixelFormat); } } } /* Teï jsem ve fázi kdy v promìnné image mame oøezaný obrázek v pùvodním tvaru. * Aplikuji hnedý filtr a jedu to co s modrou, */ filterBrown.ApplyInPlace(image); filterBlur.ApplyInPlace(image); bc.FilterBlobs = true; bc.MinHeight = 500; bc.MinWidth = 500; bc.ProcessImage(image); blobs = bc.GetObjectsInformation(); shapeChecker = new SimpleShapeChecker(); foreach (var blob in blobs) { List <IntPoint> edgePoints = bc.GetBlobsEdgePoints(blob); List <IntPoint> cornerPoints; if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints)) { if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { List <System.Drawing.Point> Points = new List <System.Drawing.Point>(); foreach (var point in cornerPoints) { Points.Add(new System.Drawing.Point(point.X, point.Y)); } /* Tady zpracuju rohový bod a vypoèítám rozmìry. */ souradniceRozmeryOrezu[0] = Points[0].X + levyHorniX; souradniceRozmeryOrezu[1] = Points[1].Y + levyHorniY; souradniceRozmeryOrezu[2] = Points[2].X - Points[0].X; souradniceRozmeryOrezu[3] = Points[3].Y - Points[1].Y; } } } /* Vrátím získané hodnoty * 1. pozice - levé horní souøadnice X. * 2. pozice - levá horní souøadnice Y. * 3. pozice - šíøka oøezu. * 4. pozice - výška oøezu. */ return(souradniceRozmeryOrezu); }