public static Bitmap DoIt(Bitmap bmp) { GaussianBlur blur = new GaussianBlur(10, 50); Bitmap blurred = blur.Apply(bmp); Bitmap ret = new Bitmap(blurred.Width, blurred.Height, blurred.PixelFormat); for (int y = 0; y < blurred.Height; y++) { for (int x = 0; x < blurred.Width; x++) { Color blurredColor = blurred.GetPixel(x, y); Color orinalColor = bmp.GetPixel(x, y); Color newColor = Color.FromArgb((blurredColor.R + orinalColor.R * 2) / 3, (blurredColor.G + orinalColor.G * 2) / 3, (blurredColor.B + orinalColor.B * 2) / 3); ret.SetPixel(x, y, newColor); } } GammaCorrection gc = new GammaCorrection(.8); gc.ApplyInPlace(ret); Sharpen sharpen = new Sharpen(); sharpen.ApplyInPlace(ret); Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap gray = filter.Apply(ret); CannyEdgeDetector canny = new CannyEdgeDetector(); gray = canny.Apply(gray); for (int y = 0; y < gray.Height; y++) { for (int x=0;x < gray.Width; x++) { if(gray.GetPixel(x,y).R > 0) { Color retColor = ret.GetPixel(x, y); Color newColor = Color.FromArgb( (int)(retColor.R * .7), (int)(retColor.G * .7), (int)(retColor.B * .7)); ret.SetPixel(x, y, newColor); } } } return ret; }
public double GetTemperature() { var temp = 0.0; var image = Image.FromFile(filename); var grayscale = new Grayscale(0.2125, 0.7154, 0.0721); image = grayscale.Apply(image); var invert = new Invert(); image = invert.Apply(image); var stats = new ImageStatistics(image); var levelsLinear = new LevelsLinear { InGray = stats.Gray.GetRange(2.90) }; image = levelsLinear.Apply(image); var contrast = new ContrastStretch(); image = contrast.Apply(image); var erosion = new Erosion(); image = erosion.Apply(image); var blur = new GaussianBlur(2, 3); image = blur.Apply(image); var threshold = new Threshold(79); image = threshold.Apply(image); image.Save(processedFileName, System.Drawing.Imaging.ImageFormat.Jpeg); image.Dispose(); var text = Recognise(); double.TryParse(text.Replace(',', '.'), out temp); return temp; }
/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="source">Source image data.</param> /// <param name="destination">Destination image data.</param> /// <param name="rect">Image rectangle for processing by the filter.</param> /// protected override unsafe void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect) { // processing start and stop X,Y positions var startX = rect.Left + 1; var startY = rect.Top + 1; var stopX = startX + rect.Width - 2; var stopY = startY + rect.Height - 2; var width = rect.Width - 2; var height = rect.Height - 2; var dstStride = destination.Stride; var srcStride = source.Stride; var dstOffset = dstStride - rect.Width + 2; var srcOffset = srcStride - rect.Width + 2; // pixel's value and gradients int gx, gy; // double orientation, toAngle = 180.0 / System.Math.PI; float leftPixel = 0, rightPixel = 0; // STEP 1 - blur image var blurredImage = gaussianFilter.Apply(source); // orientation array var orients = new byte[width * height]; // gradients array var gradients = new float[source.Width, source.Height]; var maxGradient = float.NegativeInfinity; // do the job var src = (byte *)blurredImage.ImageData.ToPointer(); // allign pointer src += srcStride * startY + startX; // STEP 2 - calculate magnitude and edge orientation var p = 0; // for each line for (var y = startY; y < stopY; y++) { // for each pixel for (var x = startX; x < stopX; x++, src++, p++) { gx = src[-srcStride + 1] + src[srcStride + 1] - src[-srcStride - 1] - src[srcStride - 1] + 2 * (src[1] - src[-1]); gy = src[-srcStride - 1] + src[-srcStride + 1] - src[srcStride - 1] - src[srcStride + 1] + 2 * (src[-srcStride] - src[srcStride]); // get gradient value gradients[x, y] = (float)System.Math.Sqrt(gx * gx + gy * gy); if (gradients[x, y] > maxGradient) { maxGradient = gradients[x, y]; } // --- get orientation if (gx == 0) { // can not divide by zero orientation = (gy == 0) ? 0 : 90; } else { var div = (double)gy / gx; // handle angles of the 2nd and 4th quads if (div < 0) { orientation = 180 - System.Math.Atan(-div) * toAngle; } // handle angles of the 1st and 3rd quads else { orientation = System.Math.Atan(div) * toAngle; } // get closest angle from 0, 45, 90, 135 set if (orientation < 22.5) { orientation = 0; } else if (orientation < 67.5) { orientation = 45; } else if (orientation < 112.5) { orientation = 90; } else if (orientation < 157.5) { orientation = 135; } else { orientation = 0; } } // save orientation orients[p] = (byte)orientation; } src += srcOffset; } // STEP 3 - suppres non maximums var dst = (byte *)destination.ImageData.ToPointer(); // allign pointer dst += dstStride * startY + startX; p = 0; // for each line for (var y = startY; y < stopY; y++) { // for each pixel for (var x = startX; x < stopX; x++, dst++, p++) { // get two adjacent pixels switch (orients[p]) { case 0: leftPixel = gradients[x - 1, y]; rightPixel = gradients[x + 1, y]; break; case 45: leftPixel = gradients[x - 1, y + 1]; rightPixel = gradients[x + 1, y - 1]; break; case 90: leftPixel = gradients[x, y + 1]; rightPixel = gradients[x, y - 1]; break; case 135: leftPixel = gradients[x + 1, y + 1]; rightPixel = gradients[x - 1, y - 1]; break; } // compare current pixels value with adjacent pixels if ((gradients[x, y] < leftPixel) || (gradients[x, y] < rightPixel)) { *dst = 0; } else { *dst = (byte)(gradients[x, y] / maxGradient * 255); } } dst += dstOffset; } // STEP 4 - hysteresis dst = (byte *)destination.ImageData.ToPointer(); // allign pointer dst += dstStride * startY + startX; // for each line for (var y = startY; y < stopY; y++) { // for each pixel for (var x = startX; x < stopX; x++, dst++) { if (*dst < highThreshold) { if (*dst < lowThreshold) { // non edge *dst = 0; } else { // check 8 neighboring pixels if ((dst[-1] < highThreshold) && (dst[1] < highThreshold) && (dst[-dstStride - 1] < highThreshold) && (dst[-dstStride] < highThreshold) && (dst[-dstStride + 1] < highThreshold) && (dst[dstStride - 1] < highThreshold) && (dst[dstStride] < highThreshold) && (dst[dstStride + 1] < highThreshold)) { *dst = 0; } } } } dst += dstOffset; } // STEP 5 - draw black rectangle to remove those pixels, which were not processed // (this needs to be done for those cases, when filter is applied "in place" - // source image is modified instead of creating new copy) Drawing.Rectangle(destination, rect, Color.Black); // release blurred image blurredImage.Dispose(); }
// Apply filter public Bitmap Apply(Bitmap srcImg) { // Step 1 - grayscale initial image Bitmap grayImage = (srcImg.PixelFormat == PixelFormat.Format8bppIndexed) ? srcImg : grayscaleFilter.Apply(srcImg); // Step 2 - blur image Bitmap blurredImage = gaussianFilter.Apply(grayImage); // get source image size int width = srcImg.Width; int height = srcImg.Height; // lock source bitmap data BitmapData srcData = blurredImage.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); // create new image Bitmap dstImg = AForge.Imaging.Image.CreateGrayscaleImage(width, height); // lock destination bitmap data BitmapData dstData = dstImg.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); int stride = srcData.Stride; int offset = stride - width; int widthM1 = width - 1; int heightM1 = height - 1; int i, j, ir; double v, gx, gy; double orientation, toPI = 180.0 / System.Math.PI; byte leftPixel = 0, rightPixel = 0; // orientation array byte[] orients = new byte[width * height]; // do the job unsafe { byte *src = (byte *)srcData.Scan0.ToPointer() + stride; byte *dst = (byte *)dstData.Scan0.ToPointer() + stride; int p = width; // Step 3 - calculate magnitude and edge orientation // for each line for (int y = 1; y < heightM1; y++) { src++; dst++; p++; // for each pixel for (int x = 1; x < widthM1; x++, src++, dst++, p++) { gx = gy = 0; // for each kernel row for (i = 0; i < 3; i++) { ir = i - 1; // for each kernel column for (j = 0; j < 3; j++) { // source value v = src[ir * stride + j - 1]; gx += v * xKernel[i, j]; gy += v * yKernel[i, j]; } } // get gradient value *dst = (byte)Math.Min(Math.Abs(gx) + Math.Abs(gy), 255); // --- get orientation // can not devide by zero if (gx == 0) { orientation = (gy == 0) ? 0 : 90; } else { double div = gy / gx; // handle angles of the 2nd and 4th quads if (div < 0) { orientation = 180 - System.Math.Atan(-div) * toPI; } // handle angles of the 1st and 3rd quads else { orientation = System.Math.Atan(div) * toPI; } // get closest angle from 0, 45, 90, 135 set if (orientation < 22.5) { orientation = 0; } else if (orientation < 67.5) { orientation = 45; } else if (orientation < 112.5) { orientation = 90; } else if (orientation < 157.5) { orientation = 135; } else { orientation = 0; } } // save orientation orients[p] = (byte)orientation; } src += (offset + 1); dst += (offset + 1); p++; } // Step 4 - suppres non maximums dst = (byte *)dstData.Scan0.ToPointer() + stride; p = width; // for each line for (int y = 1; y < heightM1; y++) { dst++; p++; // for each pixel for (int x = 1; x < widthM1; x++, dst++, p++) { // get two adjacent pixels switch (orients[p]) { case 0: leftPixel = dst[-1]; rightPixel = dst[1]; break; case 45: leftPixel = dst[width - 1]; rightPixel = dst[-width + 1]; break; case 90: leftPixel = dst[width]; rightPixel = dst[-width]; break; case 135: leftPixel = dst[width + 1]; rightPixel = dst[-width - 1]; break; } // compare current pixels value with adjacent pixels if ((*dst < leftPixel) || (*dst < rightPixel)) { *dst = 0; } } dst += (offset + 1); p++; } // Step 5 - hysteresis dst = (byte *)dstData.Scan0.ToPointer() + stride; p = width; // for each line for (int y = 1; y < heightM1; y++) { dst++; p++; // for each pixel for (int x = 1; x < widthM1; x++, dst++, p++) { if (*dst < highThreshold) { if (*dst < lowThreshold) { // non edge *dst = 0; } else { // check 8 neighboring pixels if ((dst[-1] < highThreshold) && (dst[1] < highThreshold) && (dst[-width - 1] < highThreshold) && (dst[-width] < highThreshold) && (dst[-width + 1] < highThreshold) && (dst[width - 1] < highThreshold) && (dst[width] < highThreshold) && (dst[width + 1] < highThreshold)) { *dst = 0; } } } } dst += (offset + 1); p++; } } // unlock images dstImg.UnlockBits(dstData); blurredImage.UnlockBits(srcData); // release temporary objects blurredImage.Dispose(); if (grayImage != srcImg) { grayImage.Dispose(); } return(dstImg); }
protected unsafe override void ProcessFilter(UnmanagedImage source, UnmanagedImage destination, Rectangle rect) { int num = rect.Left + 1; int num2 = rect.Top + 1; int num3 = num + rect.Width - 2; int num4 = num2 + rect.Height - 2; int num5 = rect.Width - 2; int num6 = rect.Height - 2; int stride = destination.Stride; int stride2 = source.Stride; int num7 = stride - rect.Width + 2; int num8 = stride2 - rect.Width + 2; double num9 = 180.0 / System.Math.PI; float num10 = 0f; float num11 = 0f; UnmanagedImage unmanagedImage = gaussianFilter.Apply(source); byte[] array = new byte[num5 * num6]; float[,] array2 = new float[source.Width, source.Height]; float num12 = float.NegativeInfinity; byte *ptr = (byte *)unmanagedImage.ImageData.ToPointer(); ptr += stride2 * num2 + num; int num13 = 0; for (int i = num2; i < num4; i++) { int num14 = num; while (num14 < num3) { int num15 = ptr[-stride2 + 1] + ptr[stride2 + 1] - ptr[-stride2 - 1] - ptr[stride2 - 1] + 2 * (ptr[1] - ptr[-1]); int num16 = ptr[-stride2 - 1] + ptr[-stride2 + 1] - ptr[stride2 - 1] - ptr[stride2 + 1] + 2 * (ptr[-stride2] - ptr[stride2]); array2[num14, i] = (float)System.Math.Sqrt(num15 * num15 + num16 * num16); if (array2[num14, i] > num12) { num12 = array2[num14, i]; } double num17; if (num15 == 0) { num17 = ((num16 != 0) ? 90 : 0); } else { double num18 = (double)num16 / (double)num15; num17 = ((!(num18 < 0.0)) ? (System.Math.Atan(num18) * num9) : (180.0 - System.Math.Atan(0.0 - num18) * num9)); num17 = ((!(num17 < 22.5)) ? ((!(num17 < 67.5)) ? ((!(num17 < 112.5)) ? ((!(num17 < 157.5)) ? 0.0 : 135.0) : 90.0) : 45.0) : 0.0); } array[num13] = (byte)num17; num14++; ptr++; num13++; } ptr += num8; } byte *ptr2 = (byte *)destination.ImageData.ToPointer(); ptr2 += stride * num2 + num; num13 = 0; for (int j = num2; j < num4; j++) { int num19 = num; while (num19 < num3) { switch (array[num13]) { case 0: num10 = array2[num19 - 1, j]; num11 = array2[num19 + 1, j]; break; case 45: num10 = array2[num19 - 1, j + 1]; num11 = array2[num19 + 1, j - 1]; break; case 90: num10 = array2[num19, j + 1]; num11 = array2[num19, j - 1]; break; case 135: num10 = array2[num19 + 1, j + 1]; num11 = array2[num19 - 1, j - 1]; break; } if (array2[num19, j] < num10 || array2[num19, j] < num11) { *ptr2 = 0; } else { *ptr2 = (byte)(array2[num19, j] / num12 * 255f); } num19++; ptr2++; num13++; } ptr2 += num7; } ptr2 = (byte *)destination.ImageData.ToPointer(); ptr2 += stride * num2 + num; for (int k = num2; k < num4; k++) { int num20 = num; while (num20 < num3) { if (*ptr2 < highThreshold) { if (*ptr2 < lowThreshold) { *ptr2 = 0; } else if (ptr2[-1] < highThreshold && ptr2[1] < highThreshold && ptr2[-stride - 1] < highThreshold && ptr2[-stride] < highThreshold && ptr2[-stride + 1] < highThreshold && ptr2[stride - 1] < highThreshold && ptr2[stride] < highThreshold && ptr2[stride + 1] < highThreshold) { *ptr2 = 0; } } num20++; ptr2++; } ptr2 += num7; } Drawing.Rectangle(destination, rect, Color.Black); unmanagedImage.Dispose(); }
public static Bitmap gaussianBlur(this Bitmap bitmap, int blur) { AForge.Imaging.Filters.GaussianBlur filter = new AForge.Imaging.Filters.GaussianBlur(Convert.ToDouble(blur), 9); return(filter.Apply(AForge.Imaging.Image.Clone(bitmap, PixelFormat.Format24bppRgb))); }
/// <summary> /// Blur image with Gauss /// </summary> /// <param name="image"></param> /// <param name="sigma">Gaussia sigma</param> /// <param name="kernelSize">Gaussia kermel</param> /// <returns></returns> public static Image Gauss(this Image image, double sigma, int kernelSize) { GaussianBlur blur = new GaussianBlur(sigma, kernelSize); return blur.Apply(new Bitmap(image)); }