//1. bright pixel / dark pixel //2.lowest gray level //3.highest gray level //4.number of peaks in the x direction. //5.number of peaks in the y direction. public static double[] ExtractFeatures(Bitmap bmp,int i) { //Apply GrayScale GrayscaleBT709 greyScaleFilter = new GrayscaleBT709(); Bitmap newBmp = greyScaleFilter.Apply((Bitmap)bmp.Clone()); //Count Blobs BlobCounter blobCounter = new BlobCounter(); blobCounter.BackgroundThreshold = Color.FromArgb(255, 150, 150, 150); blobCounter.ProcessImage(newBmp); int blobs = (blobCounter.ObjectsCount - 1) * 30; //Count Corner SusanCornersDetector scd = new SusanCornersDetector(); scd.DifferenceThreshold = 70; scd.GeometricalThreshold = 8; int corners = scd.ProcessImage((Bitmap)newBmp.Clone()).Count(); //Apply Edge Filter CannyEdgeDetector filter = new CannyEdgeDetector(); //newBmp = filter.Apply(newBmp); Histogram his = new HorizontalIntensityStatistics(newBmp).Gray; Histogram vis = new VerticalIntensityStatistics(newBmp).Gray; HoughLineTransformation lineTransform = new HoughLineTransformation(); // apply Hough line transofrm lineTransform.ProcessImage(filter.Apply(newBmp)); Bitmap houghLineImage = lineTransform.ToBitmap(); // get lines using relative intensity HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(1); int linesCount = lines.Count() * 30; double[] features = new double[13] { blobs, corners, his.Max, his.Min, his.Mean, his.Median, his.StdDev, vis.Max, vis.Min, vis.Mean, vis.Median, vis.StdDev,linesCount}; //double[] features = new double[3] { blobs, corners,lines}; newBmp.Save(String.Format("test{0}.bmp",i)); return features; }
/// <summary> /// Determines if the cells are white over a black background, for a black and white image /// </summary> /// <param name="page">The bitmap that is the manga page</param> /// <returns>Returns true if the background of the manga page is black</returns> public static bool IsInvertedColor(Bitmap page) { // The colors are inverted if the color of the borders are inverted. HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(page); VerticalIntensityStatistics vis = new VerticalIntensityStatistics(page); int vband = (int)(page.Height * 0.05); int hband = (int)(page.Width * 0.05); decimal totalValue = 0; for (int i = 0; i < vband; i++) { totalValue += vis.Gray.Values[i] + vis.Gray.Values[page.Height - i - 1]; } for (int i = 0; i < hband; i++) { totalValue += his.Gray.Values[i] + his.Gray.Values[page.Width - i - 1]; } return totalValue < (decimal)(((page.Height * hband * 2) + (page.Width * vband * 2)) * 255 * 0.50); }
// New frame received by the player private void videoSourcePlayer_NewFrame( object sender, ref Bitmap image ) { BitmapData imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat); try { UnmanagedImage unmanagedImg = new UnmanagedImage( imageData ); int x = (int)(unmanagedImg.Width / 3.19); // 443 int y = (int)(unmanagedImg.Height / 2.2); // 490 int w = (int)(unmanagedImg.Width / 2.7); // 553 int h = (int)(unmanagedImg.Height / 4); // 270 int s = (int)(unmanagedImg.Width / 10.2); // 141 // Crop the player scroll window. Speeds up the next couple operations Crop onePlayer = new Crop(new Rectangle(x, y, w, h)); UnmanagedImage img = onePlayer.Apply(unmanagedImg); // Use a quadrilateral transformation to make the scroller a big square. List<IntPoint> corners = new List<IntPoint>(); corners.Add(new IntPoint(s, 0)); corners.Add(new IntPoint(img.Width - s, 0)); ; corners.Add(new IntPoint(img.Width, img.Height)); corners.Add(new IntPoint(0, img.Height)); QuadrilateralTransformation filter = new QuadrilateralTransformation(corners, img.Width, img.Height); img = filter.Apply(img); // Crop the bottom half since it appears to have the best imagery Crop bottom = new Crop(new Rectangle(0, img.Height / 2, img.Width, img.Height / 2)); img = bottom.Apply(img); UnmanagedImage grayImg = UnmanagedImage.Create(img.Width, img.Height, PixelFormat.Format8bppIndexed); Grayscale.CommonAlgorithms.BT709.Apply(img, grayImg); OtsuThreshold threshold = new OtsuThreshold(); threshold.ApplyInPlace(grayImg); // Divide the square into 5 peices. One for each color. UnmanagedImage[] colorImg = new UnmanagedImage[5]; for(int i=0; i < 5; i++) { int colorWidth = grayImg.Width / 5; int colorHeight = grayImg.Height; Crop colorCrop = new Crop(new Rectangle(colorWidth * i, 0, colorWidth, colorHeight)); colorImg[i] = colorCrop.Apply(grayImg); } greenCol.Image = colorImg[GREEN].ToManagedImage(); redCol.Image = colorImg[RED].ToManagedImage(); yellowCol.Image = colorImg[YELLOW].ToManagedImage(); blueCol.Image = colorImg[BLUE].ToManagedImage(); orangeCol.Image = colorImg[ORANGE].ToManagedImage(); VerticalIntensityStatistics[] hist = new VerticalIntensityStatistics[5]; for (int i = 0; i < 5; i++) { hist[i] = new VerticalIntensityStatistics(colorImg[i]); } findPucks(hist); greenHist.Values = hist[GREEN].Gray.Values; redHist.Values = hist[RED].Gray.Values; yellowHist.Values = hist[YELLOW].Gray.Values; blueHist.Values = hist[BLUE].Gray.Values; orangeHist.Values = hist[ORANGE].Gray.Values; pictureBox1.Image = img.ToManagedImage(); } finally { image.UnlockBits( imageData ); } }
private void findPucks(VerticalIntensityStatistics[] hist) { // Find all the pucks /* Thinking for this: * - Choose your color and figure out how many pucks we've found * - Scan through all the lines and find all objects larger than the min puck height * - Compare each item */ for (int i = 0; i < 5; i++) { List<puck> found_pucks = new List<puck>(); int cur_line = hist[i].Gray.Values.Length - 1; int puck_start = -1; while (cur_line > 0) { if (hist[i].Gray.Values[cur_line] > THRESHOLD) { if (puck_start < 0) { puck_start = cur_line; } } else { if (puck_start > 0) { if (cur_line == 0 || hist[i].Gray.Values[cur_line - 1] < THRESHOLD) { int height = puck_start - cur_line; if (height > MIN_PUCK_SIZE) { puck p = new puck(); p.location = puck_start; p.height = height; found_pucks.Add(p); } puck_start = -1; } } } cur_line--; } if (i == 0) { s += "Found " + found_pucks.Count + " Pucks: "; foreach (puck p in found_pucks) { s += "(" + p.location + "/" + p.height + ") "; } s += "\r\n"; } } }
/// <summary> /// Estimate hand position on the specified image. /// </summary> /// /// <param name="handImage">Hand image to processþ</param> /// /// <returns>Returns detected hand's position.</returns> /// private HandPosition GetHandPosition( Bitmap handImage ) { HandPosition handPosition = HandPosition.NotRaised; // get vertical intensity statistics of the hand VerticalIntensityStatistics stat = new VerticalIntensityStatistics( handImage ); Histogram histogram = stat.Gray; // do histogram's preprocessing FilterLowValues( histogram ); FilterNoisyPeaks( histogram ); if ( ( (double) handImage.Width / ( histogram.Max - histogram.Min + 1 ) ) > minStraightHandProportion ) { handPosition = HandPosition.RaisedStraigh; } else { if ( ( (double) histogram.Min / ( histogram.Max - histogram.Min + 1 ) ) < maxRaisedUpHandProportion ) { handPosition = HandPosition.RaisedDiagonallyUp; } else { handPosition = HandPosition.RaisedDiagonallyDown; } } return handPosition; }
/// <summary> /// Gets the content. /// </summary> /// <param name="mincross">Минимальная разница яркости ячейки с кретсиком</param> /// <param name="maxcross">Максимальная разница яркости ячейки с кретсиком</param> public void GetContent(double mincross, double maxcross) { _content = false; _neurocontent = CellContent.Free; List<double> _lrange = new List<double>(); BitmapData data = _parentimage.LockBits(_rect, ImageLockMode.ReadWrite, _parentimage.PixelFormat); VerticalIntensityStatistics vis = new VerticalIntensityStatistics(data); histogram = vis.Gray; HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(data); Histogram hhistogram = his.Gray; List<double> _hrange = new List<double>(); _parentimage.UnlockBits(data); for (int i = 8; i <= 15; i++) { _lrange.Add((histogram.Values[i]+hhistogram.Values[i])/2); // _hrange.Add(hhistogram.Values[i]); } // _britnessdispertion = (1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max()) + (1 - RecogCore.Statistics.Mean(_hrange) / hhistogram.Values.Max()); _britnessdispertion = 1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max(); if (_britnessdispertion <= mincross) { _neurocontent = CellContent.Free; _content = false; } if (_britnessdispertion > mincross & _britnessdispertion <= maxcross) { _neurocontent = CellContent.Cross; _content = true; } if (_britnessdispertion > maxcross) { _neurocontent = CellContent.Miss; _content = false; } }
/// <summary> /// Process new frame. /// </summary> /// /// <remarks>Process new frame of video source and try to recognize gesture.</remarks> /// public void ProcessFrame( ref Bitmap image ) { // check background frame if ( backgroundFrame == null ) { // save image dimension width = image.Width; height = image.Height; frameSize = width * height; // create initial backgroung image backgroundFrame = grayscaleFilter.Apply( image ); return; } // check image dimension if ( ( image.Width != width ) || ( image.Height != height ) ) return; // apply the grayscale filter Bitmap currentFrame = grayscaleFilter.Apply( image ); // set backgroud frame as an overlay for difference filter differenceFilter.OverlayImage = backgroundFrame; // apply difference filter Bitmap motionObjectsImage = differenceFilter.Apply( currentFrame ); // lock motion objects image for further faster processing BitmapData motionObjectsData = motionObjectsImage.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed ); // apply threshold filter thresholdFilter.ApplyInPlace( motionObjectsData ); // apply opening filter to remove noise openingFilter.ApplyInPlace( motionObjectsData ); // process blobs blobCounter.ProcessImage( motionObjectsData ); Blob[] blobs = blobCounter.GetObjectInformation( ); int maxSize = 0; Blob maxObject = new Blob( 0, new Rectangle( 0, 0, 0, 0 ) ); // find biggest blob if ( blobs != null ) { foreach ( Blob blob in blobs ) { int blobSize = blob.Rectangle.Width * blob.Rectangle.Height; if ( blobSize > maxSize ) { maxSize = blobSize; maxObject = blob; } } } // if we have only small objects then let's adopt to changes in the scene if ( ( maxObject.Rectangle.Width < 20 ) || ( maxObject.Rectangle.Height < 20 ) ) { // move background towards current frame moveTowardsFilter.OverlayImage = currentFrame; moveTowardsFilter.ApplyInPlace( backgroundFrame ); } if ( ( maxObject.Rectangle.Width >= minBodyWidth ) && ( maxObject.Rectangle.Height >= minBodyHeight ) && ( previousFrame != null ) ) { // check motion level between frames differenceFilter.OverlayImage = previousFrame; // apply difference filter Bitmap betweenFramesMotion = differenceFilter.Apply( currentFrame ); // lock image with between frames motion for faster further processing BitmapData betweenFramesMotionData = betweenFramesMotion.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed ); // apply threshold filter thresholdFilter.ApplyInPlace( betweenFramesMotionData ); // apply opening filter to remove noise openingFilter.ApplyInPlace( betweenFramesMotionData ); // calculate amount of changed pixels VerticalIntensityStatistics vis = new VerticalIntensityStatistics( betweenFramesMotionData ); int[] histogram = vis.Gray.Values; int changedPixels = 0; for ( int i = 0, n = histogram.Length; i < n; i++ ) { changedPixels += histogram[i] / 255; } // free temporary image betweenFramesMotion.UnlockBits( betweenFramesMotionData ); betweenFramesMotion.Dispose( ); // check motion level if ( (double) changedPixels / frameSize <= motionLimit ) { framesWithoutMotion++; } else { // reset counters framesWithoutMotion = 0; framesWithoutGestureChange = 0; notDetected = true; } // check if we don't have motion for a while if ( framesWithoutMotion >= minFramesWithoutMotion ) { if ( notDetected ) { // extract the biggest blob blobCounter.ExtractBlobsImage( motionObjectsData, maxObject ); // recognize gesture from the image Gesture gesture = gestureRecognizer.Recognize( maxObject.Image, true ); maxObject.Image.Dispose( ); // check if gestures has changed since the previous frame if ( ( gesture.LeftHand == previousGesture.LeftHand ) && ( gesture.RightHand == previousGesture.RightHand ) ) { framesWithoutGestureChange++; } else { framesWithoutGestureChange = 0; } // check if gesture was not changing for a while if ( framesWithoutGestureChange >= minFramesWithoutGestureChange ) { if ( GestureDetected != null ) { GestureDetected( this, gesture ); } notDetected = false; } previousGesture = gesture; } } } else { // reset counters framesWithoutMotion = 0; framesWithoutGestureChange = 0; notDetected = true; } // free motion objects' image motionObjectsImage.UnlockBits( motionObjectsData ); motionObjectsImage.Dispose( ); // dispose previous frame if ( previousFrame != null ) { previousFrame.Dispose( ); } // set current frame to previous previousFrame = currentFrame; }
public override void Execute(Bitmap Image) { BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 75; blobCounter.MinWidth = 75; blobCounter.CoupledSizeFiltering = true; blobCounter.ProcessImage(Image); Blob[] blobs = blobCounter.GetObjects(Image); int maxSize = 0; int TmpX = -100, TmpY = -100; Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0)); // find biggest blob if (blobs != null) { foreach (Blob blob in blobs) { int blobSize = blob.Rectangle.Width * blob.Rectangle.Height; if (blobSize > maxSize) { maxSize = blobSize; maxObject = blob; } } if (maxSize > 70) { TmpX = (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2; TmpY = maxObject.Rectangle.Top; } } AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(Image); int[] HistVer = VIS.Gray.Values; AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(Image); int[] HistHor = HIS.Gray.Values; bool Found = false; for (int i = System.Math.Max(CurrY - GateLengthY / 2, 0); i <= System.Math.Min(CurrY + GateLengthY / 2, HistVer.Length - 2); i++) { if (((double)HistVer[i]) / 255 > 0) { Found = true; CurrY = i; break; } } if (!Found) { Validity = ValidLocation.FALSE; return; } Found = false; for (int i = System.Math.Max(0, CurrX - GateLengthX / 2); i <= System.Math.Min(HistHor.Length - 1, CurrX + GateLengthX / 2); i++) { if (Image.GetPixel(i, CurrY).Name != "ff000000") { Found = true; CurrX = i; break; } } if (!Found) { Validity = ValidLocation.FALSE; return; } /*if (System.Math.Sqrt((CurrX - TmpX) * (CurrX - TmpX) + (CurrY - TmpY) * (CurrY - TmpY)) > 80) { Validity = ValidLocation.FALSE; return; } else Validity = ValidLocation.TRUE; CurrX = TmpX; CurrY = TmpY;*/ Validity = ValidLocation.TRUE; }
void webcam_ImageCaptured_Back2(object source, WebcamEventArgs e) { _FrameImage.Image = e.WebCamImage; Bitmap MaskImage = new Bitmap(640, 480); if (backgroundFrame == null) { Frames2Ignore--; if (Frames2Ignore == 0) { backgroundFrame = (Bitmap)e.WebCamImage; backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame); } return; } //Save curent image CurrentFrame = (Bitmap)e.WebCamImage; CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame); /* // create filter IFilter pixellateFilter = new Pixellate(); // apply the filter backgroundFrame = pixellateFilter.Apply(backgroundFrame); backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame); CurrentFrame = pixellateFilter.Apply(CurrentFrame); CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame);*/ MoveTowards moveTowardsFilter = new MoveTowards(); moveTowardsFilter.OverlayImage = CurrentFrameGray; // move background towards current frame Bitmap tmp = moveTowardsFilter.Apply(backgroundFrameGray); // dispose old background backgroundFrame.Dispose(); backgroundFrame = tmp; // create processing filters sequence FiltersSequence processingFilter = new FiltersSequence(); processingFilter.Add(new Difference(backgroundFrameGray)); processingFilter.Add(new Threshold(15)); processingFilter.Add(new Opening()); processingFilter.Add(new Edges()); processingFilter.Add(new DifferenceEdgeDetector()); // apply the filter Bitmap tmp1 = processingFilter.Apply(CurrentFrameGray); // extract red channel from the original image /*IFilter extrachChannel = new ExtractChannel(RGB.R); Bitmap redChannel = extrachChannel.Apply(backgroundFrame); // merge red channel with moving object borders Merge mergeFilter = new Merge(); mergeFilter.OverlayImage = tmp1; Bitmap tmp2 = mergeFilter.Apply(redChannel); // replace red channel in the original image ReplaceChannel replaceChannel = new ReplaceChannel(RGB.R, tmp2); replaceChannel.ChannelImage = tmp2; Bitmap tmp3 = replaceChannel.Apply(backgroundFrame); ConnectedComponentsLabeling CCL = new ConnectedComponentsLabeling(); CCL.MinWidth = 75; CCL.MinHeight = 75; CCL.CoupledSizeFiltering = true; Bitmap tmp4 = CCL.Apply(tmp1); blobCounter.MinHeight = 75; blobCounter.MinWidth = 75; blobCounter.CoupledSizeFiltering = true; blobCounter.ProcessImage(tmp1); Blob[] blobs = blobCounter.GetObjects(tmp1); int maxSize = 0; Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0)); // find biggest blob if (blobs != null) { foreach (Blob blob in blobs) { int blobSize = blob.Rectangle.Width * blob.Rectangle.Height; if (blobSize > maxSize) { maxSize = blobSize; maxObject = blob; } } }*/ Bitmap Hor = new Bitmap(320, 240); Bitmap Ver = new Bitmap(320, 240); /*if (maxSize > 150) { AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(tmp1); int[] HistVer = VIS.Gray.Values; AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(tmp1); int[] HistHor = HIS.Gray.Values; } */ AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(tmp1); int[] HistVer = VIS.Gray.Values; AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(tmp1); int[] HistHor = HIS.Gray.Values; //StateMgr.Execute(HistHor,HistVer); if (eChangedCursorEvent != null && StateMgr.Val == Webcam.ValidLocation.TRUE) { //Console.WriteLine("X={0} , Y={1}", StateMgr.CurrState.CurrX, StateMgr.CurrState.CurrY); eChangedCursorEvent(StateMgr.CurrState.CurrX, StateMgr.CurrState.CurrY); //eChangedCursorEvent(StateMgr.CurrState.CurrX, 100); //eChangedCursorEvent(100, StateMgr.CurrState.CurrY); } #region Paint Hist /*for (int x = 0; x < 320; x++) for (int y = 0; y < 240; y++) { Hor.SetPixel(x, y, Color.White); Ver.SetPixel(x, y, Color.White); } int Imax = -1, Max = -1; for (int i = 0; i < HistHor.Length; i++) { for (int y = 0; y < ((double)(HistHor[i]) / 255); y++) Hor.SetPixel(i, y, Color.Black); if (HistHor[i] > 0) { Imax = i; Max = HistHor[i]; } } int ImaxY = -1, MaxY = -1; for (int i = 0; i < HistVer.Length; i++) { for (int x = 0; x < ((double)(HistVer[i]) / 255); x++) Ver.SetPixel(x, i, Color.Black); if (HistVer[i] > MaxY) { ImaxY = i; MaxY = HistVer[i]; } }*/ #endregion _CaptureImage.Image = Hor; _CaptureImage2.Image = Ver; backgroundFrame = (Bitmap)e.WebCamImage; backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame); }