//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; }
//Finds the degree tilt of the part using Hough Line Detection //Reference Documentation for Method:http://www.aforgenet.com/framework/docs/html/6141703e-d685-efb5-2f7f-b430aa42210f.htm public double findDegreeTilt(Bitmap inImage) { //Creating HoughLineTranformation object AForge.Imaging.HoughLineTransformation lineTransform = new AForge.Imaging.HoughLineTransformation(); //Adjusts the number of decimal places of the returned angle (Reference Documentation:http://www.aforgenet.com/framework/docs/html/24be38e1-20d8-214e-7adb-31a61854e839.htm) lineTransform.StepsPerDegree = 10; //Applys filter on image lineTransform.ProcessImage(inImage); //Creating a temporary bitmap to apply graphics to(Grpahics doesn't accept canny images) Bitmap tempBitmap = new Bitmap(inImage.Width, inImage.Height); Graphics g = Graphics.FromImage(tempBitmap); //Redrawing original image on temporary image g.DrawImage(inImage, 0, 0); Pen bluePen = new Pen(Color.Blue, 2.0f); //Stores all Hough lines found with the filter //.8 repersents the intensity constant(higher the constant the less lines the filter picks up) AForge.Imaging.HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(.8); double averageAngle = 0; //Converts each Hough line found to cartesian coordinates and draw each one foreach (AForge.Imaging.HoughLine line in lines) { //Stores the radius and theta and polar line int lineRadius = line.Radius; double lineTheta = line.Theta; //Negative radii are made positive if (lineRadius < 0) { lineTheta += 180; lineRadius = -lineRadius; } //Converting line theta from degrees to radians lineTheta = (lineTheta / 180) * Math.PI; //Image center coordinates double centerX = inImage.Width / 2.0; double centerY = inImage.Height / 2.0; //Initialization of hough line coordinates double firstX = 0, lastX = 0, firstY = 0, lastY = 0; //Creating line coordinates if (line.Theta != 0) { firstX = -centerX; lastX = centerX; firstY = (-Math.Cos(lineTheta) * firstX + lineRadius) / Math.Sin(lineTheta); lastY = (-Math.Cos(lineTheta) * lastX + lineRadius) / Math.Sin(lineTheta); } else { firstX = line.Radius; lastX = line.Radius; firstY = centerY; lastY = -centerY; } //Adjusting lineTheta angle to be in a range from 0 to 90 degrees double partRotationAngle = 90.0 - (double)(lines[0].Theta); if (partRotationAngle < 0) { partRotationAngle += 90; } //Treat the angle of 90 the same as 0 if (partRotationAngle == 90) { partRotationAngle = 0; } //Adding the returned angles to average result later on averageAngle += partRotationAngle; //Draws cartesian line repersenting polar hough line g.DrawLine(bluePen, new System.Drawing.Point((int)(firstX + centerX), (int)(centerY - firstY)), new System.Drawing.Point((int)(lastX + centerX), (int)(centerY - lastY))); } //Calculate the average degree of tilt to improve consistancy averageAngle /= (double)lines.Length; //Set the label to display rotation angle offsetAngle.Text = averageAngle.ToString(); //If wanted by the user, the hough lines will be displayed in they canny image panel if (houghLineCheckBox.Checked) { cannyImagePanel.Image = tempBitmap; } //Returns the avearge offset angle return(averageAngle); }
private bool GetIntersect(Bitmap grayImage, Bitmap bitmap, int[, ,] intersectPoint) { HoughLineTransformation lineTransform = new HoughLineTransformation(); lineTransform.ProcessImage(grayImage); Bitmap houghLineImage = lineTransform.ToBitmap(); // get lines using relative intensity HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(0.5); BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); BitmapData grayImageData = grayImage.LockBits( new Rectangle(0, 0, grayImage.Width, grayImage.Height), ImageLockMode.ReadWrite, grayImage.PixelFormat); UnmanagedImage unmanagedImage = new UnmanagedImage(bitmapData); int w2 = 0, h2 = 0; Color color = Color.Black; int[] mVer = new int[19]; double[] mHor = new double[19]; double[] cVer = new double[19]; double[] cHor = new double[19]; int verCount = 0; int horCount = 0; foreach (HoughLine line in lines) { String temp = line.Theta.ToString(); // get line's radius and theta values int r = line.Radius; double t = line.Theta; // check if line is in lower part of the image if (r < 0) { t += 180; r = -r; } // convert degrees to radians t = (t / 180) * Math.PI; // get image centers (all coordinate are measured relative // to center) w2 = grayImage.Width / 2; h2 = grayImage.Height / 2; double x0 = 0, x1 = 0, y0 = 0, y1 = 0; if (line.Theta != 0) { // vertical line if (line.Theta > 0 && line.Theta < 10 || line.Theta > 170) { if (verCount == 19) { bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); return false; } y0 = -h2; y1 = h2; x0 = (r - (Math.Sin(t) * y0)) / Math.Cos(t); x1 = (r - (Math.Sin(t) * y1)) / Math.Cos(t); color = Color.Red; x0 = w2 + (int)x0; x1 = w2 + (int)x1; y0 = (h2 - y0); y1 = (h2 - y1); //mVer[verCount] = (int) -(Math.Cos(t)/Math.Sin(t)); //cVer[verCount] = (double)r*(1/Math.Sin(t)); if ((int)x0 == (int)x1) { mVer[verCount] = (int)((y1 - y0) / (x1 - x0 + 1)); cVer[verCount] = y0 - (mVer[verCount] * x0); } else { mVer[verCount] = (int)((y1 - y0) / (x1 - x0)); cVer[verCount] = (y0 - (mVer[verCount] * x0)); } Drawing.Line(bitmapData, new IntPoint((int)x0, (int)y0), new IntPoint((int)x1 ,(int)y1), color); Drawing.Line(grayImageData, new IntPoint((int)x0 , (int)y0), new IntPoint((int)x1 , (int)y1), color); verCount++; } // horizontal if (line.Theta > 80 && line.Theta < 100) { if (horCount == 19) { bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); return false; } x0 = -w2; // most left point x1 = w2; // most right point6 y0 = (-Math.Cos(t) * x0 + r) / Math.Sin(t); y1 = (-Math.Cos(t) * x1 + r) / Math.Sin(t); x0 = x0 + w2; x1 = x1 + w2; y0 = (int)(h2 - (int)y0); y1 = (int)(h2 - (int)y1); //mHor[horCount] = (int)-(Math.Cos(t) / Math.Sin(t)); //cHor[horCount] = (double)r * (1 / Math.Sin(t)); if (y0 - (mHor[horCount] * x0) < 10 || y0 - (mHor[horCount] * x0) > bitmap.Height - 10) continue; mHor[horCount] = ((y1 - y0) / (x1 - x0)); cHor[horCount] = y0 - (mHor[horCount] * x0); horCount++; Drawing.Line(bitmapData, new IntPoint((int)x0,(int)y0), new IntPoint((int)x1, (int)y1), Color.Blue); Drawing.Line(grayImageData, new IntPoint((int)x0, (int)y0), new IntPoint((int)x1, (int)y1), Color.Blue); } } else { if (verCount == 19) { bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); return false; } // vertical line x0 = line.Radius; x1 = line.Radius; y0 = h2; y1 = -h2; color = Color.Yellow; x0 = x0 + w2; x1 = x1 + w2; y0 = (h2 - (int)y0); y1 = (h2 - (int)y1); //mVer[verCount] = (int)-(Math.Cos(t) / Math.Sin(t)); //cVer[verCount] = (double)r * (1 / Math.Sin(t)); if (x0 < 10 || x0 > bitmap.Width - 10) continue; mVer[verCount] = (int)((y1 - y0) / (x1 - x0 + 1)); cVer[verCount] = y0 - (mVer[verCount] * x0); Drawing.Line(bitmapData, new IntPoint((int)x0, (int)y0), new IntPoint((int)x1, (int)y1), color); Drawing.Line(grayImageData, new IntPoint((int)x0, (int)y0), new IntPoint((int)x1, (int)y1), color); //MessageBox.Show("y0 = " + y0 + " y1 = " + y1 + " x0 = " + x0 + " x1 = " + x1 + // " m = " + mVer[verCount] + " c = " + cVer[verCount], "ok", MessageBoxButtons.OK); verCount++; } } int m = 0; int n = 0; if (horCount == 19 && verCount == 19) { for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { intersectPoint[0, i, j] = (int)((cHor[j] - cVer[i]) / (mVer[i] - mHor[j])); intersectPoint[1, i, j] = (int)((mHor[j] * intersectPoint[0, i, j]) + cHor[j]); Debug.WriteLine(intersectPoint[0, i, j] + " " + intersectPoint[1, i, j] + " " + cHor[j] + " " + mHor[j]); } } bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); return true; } else { bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); return false; } //int num = 0; //MessageBox.Show("num = " + num + " mv =" + mVer[num] + "," + " cv = " + cVer[num] + " mh =" + mHor[num] + "," + " ch = " + cHor[num] + "," + "x = " // + intersectPoint[0, num, num] + "y = " + intersectPoint[1, num, num], "ok", MessageBoxButtons.OK); //MessageBox.Show(mVer[18] + "," + cVer[18] + "," + intersectPoint[0, 18, 18], "ok", MessageBoxButtons.OK); //MessageBox.Show(intersectPoint. + "", "ok", MessageBoxButtons.OK); }
// Process image private void ProcessImage( Bitmap bitmap ) { Grayscale grayscaleFilter = new Grayscale(0.33, 0.33, 0.34); // apply the filter Bitmap grayImage = grayscaleFilter.Apply(bitmap); //Get Histogram /*int[] histogram = new int[256]; for (int i = 0; i < 256; i++) { histogram[i] = 0; } for (int i = 0; i < grayImage.Width; i++ ) { for (int j = 0; j < grayImage.Height; j++) { histogram[(Convert.ToInt32(grayImage.GetPixel(i, j).R.ToString()) + Convert.ToInt32(grayImage.GetPixel(i, j).G.ToString()) + Convert.ToInt32(grayImage.GetPixel(i, j).B.ToString()))/3] +=1; } }*/ //create filter SobelEdgeDetector sobelFilter = new SobelEdgeDetector(); // apply the filter sobelFilter.ApplyInPlace(grayImage); Threshold filter = new Threshold(243); // apply the filter filter.ApplyInPlace(grayImage); HoughLineTransformation lineTransform = new HoughLineTransformation(); lineTransform.ProcessImage(grayImage); Bitmap houghLineImage = lineTransform.ToBitmap(); // get lines using relative intensity HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(0.5); BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); BitmapData grayImageData = grayImage.LockBits( new Rectangle(0, 0, grayImage.Width, grayImage.Height), ImageLockMode.ReadWrite, grayImage.PixelFormat); UnmanagedImage unmanagedImage = new UnmanagedImage(bitmapData); int w2 = 0, h2 = 0; int vertical = 0; int horizons = 0; int testColor = 0; Color color = Color.Black; foreach (HoughLine line in lines) { String temp = line.Theta.ToString(); //MessageBox.Show(temp, "ok", MessageBoxButtons.OK); // get line's radius and theta values int r = line.Radius; double t = line.Theta; // check if line is in lower part of the image if (r < 0) { t += 180; r = -r; } // convert degrees to radians t = (t / 180) * Math.PI; // get image centers (all coordinate are measured relative // to center) w2 = grayImage.Width / 2; h2 = grayImage.Height / 2; double x0 = 0, x1 = 0, y0 = 0, y1 = 0; if (line.Theta != 0) { // horizontal // none-vertical line if (line.Theta > 0 && line.Theta < 10 || line.Theta > 170) { x0 = -w2; // most left point x1 = w2; // most right point y0 = (-Math.Cos(t) * x0 + r) / Math.Sin(t); y1 = (-Math.Cos(t) * x1 + r) / Math.Sin(t); color = Color.Red; Drawing.Line(bitmapData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), color); Drawing.Line(grayImageData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), color); } if (line.Theta > 80 && line.Theta < 100) { x0 = -w2; // most left point x1 = w2; // most right point y0 = (-Math.Cos(t) * x0 + r) / Math.Sin(t); y1 = (-Math.Cos(t) * x1 + r) / Math.Sin(t); Drawing.Line(bitmapData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), Color.Blue); Drawing.Line(grayImageData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), Color.Blue); } } else { // vertical line x0 = line.Radius; x1 = line.Radius; y0 = h2; y1 = -h2; color = Color.Red; Drawing.Line(bitmapData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), color); Drawing.Line(grayImageData, new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1), color); } } bitmap.UnlockBits(bitmapData); grayImage.UnlockBits(grayImageData); MessageBox.Show(lines.Length+"", "ok", MessageBoxButtons.OK); // put new image to clipboard Clipboard.SetDataObject(bitmap); // and to picture box pictureBox.Image = bitmap; UpdatePictureBoxPosition(); }
/// <summary> /// Apply - search for broken bones - by finding lines and detecting angles between them /// </summary> /// <param name="bmp">Bitmap - original</param> /// <returns>Bitmap - processed</returns> public Bitmap Apply(Bitmap bmp) { System.Drawing.Imaging.PixelFormat pf = bmp.PixelFormat; ROI = bmp.Rectangle(); var lineTransform = new AForge.Imaging.HoughLineTransformation(); lineTransform.MinLineIntensity = 60; lineTransform.LocalPeakRadius = 15; //lineTransform.StepsPerDegree = 10; //lineTransform.LocalPeakRadius = 10; // apply Hough line transofrm lineTransform.ProcessImage(bmp); Bitmap houghLineImage = lineTransform.ToBitmap(); // get lines using relative intensity var lines = lineTransform.GetLinesByRelativeIntensity(0.5); lines = filterLinesByTheta(lines); Dilatation dl = new Dilatation(); dl.ApplyInPlace(bmp); Invert filter = new Invert(); filter.ApplyInPlace(bmp); bmp = bmp.Bit8ToBit24(); foreach (var line in lines) { // get line's radius and theta values int radius = line.Radius; double lineSlopeInDegrees = line.Theta; // check if line is in lower part of the image if (radius < 0) { lineSlopeInDegrees += 180; radius = -radius; } var radians = lineSlopeInDegrees.DegreesToRadians(); var imageCenter = bmp.GetCenter(); double x0 = 0, //most left point y0 = 0, x1 = 0, //most right point y1 = 0; if (line.Theta != 0) { // none-vertical line x0 = -imageCenter.X; // most left point x1 = imageCenter.X; // most right point // calculate corresponding y values y0 = (-radians.Cosinus() * x0 + radius) / radians.Sinus(); y1 = (-radians.Cosinus() * x1 + radius) / radians.Sinus(); } else { // vertical line x0 = line.Radius; x1 = line.Radius; y0 = imageCenter.Y; y1 = -imageCenter.Y; } var line2 = new Line( (int)x0 + imageCenter.X, imageCenter.Y - (int)y0, (int)x1 + imageCenter.X, imageCenter.Y - (int)y1); line2.X1 = (int)x0 + imageCenter.X; line2.Y1 = imageCenter.Y - (int)y0; line2.X2 = (int)x1 + imageCenter.X; line2.Y2 = imageCenter.Y - (int)y1; Lines.Add(line2); } return(drawLines(bmp)); }