private void Ok_OnClick(object sender, RoutedEventArgs e) { switch (cmbFilters.SelectionBoxItem.ToString()) { case "Edge Detect Mono": filterType = EdgeFilterType.EdgeDetectMono; break; case "Edge Detect Gradient": filterType = EdgeFilterType.EdgeDetectGradient; break; case "Sharpen": filterType = EdgeFilterType.Sharpen; break; case "Sharpen Gradient": filterType = EdgeFilterType.SharpenGradient; break; } if (rdbFirstDerivative.IsChecked == true) { derivativeLevel = DerivativeLevel.FirstDerivative; } else if (rdbSecondDerivative.IsChecked == true) { derivativeLevel = DerivativeLevel.SecondDerivative; } threshold = (byte)sldThreshold.Value; bFactor = (float)sldBlueFactor.Value; gFactor = (float)sldGreenFactor.Value; rFactor = (float)sldRedFactor.Value; m_backgroundWorker.RunWorkerAsync(); Close(); }
public override void Read(PackFileDeserializer des, BinaryReaderEx br) { base.Read(des, br); m_type = (EdgeFilterType)br.ReadByte(); br.ReadUInt32(); br.ReadUInt16(); br.ReadByte(); }
private void Ok_OnClick(object sender, RoutedEventArgs e) { switch (cmbFilters.SelectionBoxItem.ToString()) { case "Edge Detect Mono": filterType = EdgeFilterType.EdgeDetectMono; break; case "Edge Detect Gradient": filterType = EdgeFilterType.EdgeDetectGradient; break; case "Sharpen": filterType = EdgeFilterType.Sharpen; break; case "Sharpen Gradient": filterType = EdgeFilterType.SharpenGradient; break; } if (rdbFirstDerivative.IsChecked == true) { derivativeLevel = DerivativeLevel.FirstDerivative; } else if (rdbSecondDerivative.IsChecked == true) { derivativeLevel = DerivativeLevel.SecondDerivative; } threshold = (byte)sldThreshold.Value; bFactor = (float)sldBlueFactor.Value; gFactor = (float)sldGreenFactor.Value; rFactor = (float)sldRedFactor.Value; m_backgroundWorker.RunWorkerAsync(); Close(); }
/// <summary> /// Gradient Based Edge Detection Filter /// </summary> /// <param name="sourceBitmap">Set source Bitmap</param> /// <param name="filterType">Set Filter Type</param> /// <param name="derivativeLevel">Set Derivative level</param> /// <param name="redFactor">Set red factor</param> /// <param name="greenFactor">Set green factor</param> /// <param name="blueFactor">Set blue factor</param> /// <param name="threshold">Set threshold</param> /// <returns></returns> public static System.Drawing.Bitmap GradientBasedEdgeDetectionFilter( this System.Drawing.Bitmap sourceBitmap, EdgeFilterType filterType, DerivativeLevel derivativeLevel, float redFactor = 1.0f, float greenFactor = 1.0f, float blueFactor = 1.0f, byte threshold = 0) { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); sourceBitmap.UnlockBits(sourceData); int derivative = (int)derivativeLevel; int byteOffset = 0; int blueGradient, greenGradient, redGradient = 0; double blue = 0, green = 0, red = 0; bool exceedsThreshold = false; for (int offsetY = 1; offsetY < sourceBitmap.Height - 1; offsetY++) { for (int offsetX = 1; offsetX < sourceBitmap.Width - 1; offsetX++) { byteOffset = offsetY * sourceData.Stride + offsetX * 4; blueGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]) / derivative; blueGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]) / derivative; byteOffset++; greenGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]) / derivative; greenGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]) / derivative; byteOffset++; redGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]) / derivative; redGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]) / derivative; if (blueGradient + greenGradient + redGradient > threshold) { exceedsThreshold = true; } else { byteOffset -= 2; blueGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); byteOffset++; greenGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); byteOffset++; redGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); if (blueGradient + greenGradient + redGradient > threshold) { exceedsThreshold = true; } else { byteOffset -= 2; blueGradient = Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]); byteOffset++; greenGradient = Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]); byteOffset++; redGradient = Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] - pixelBuffer[byteOffset + sourceData.Stride]); if (blueGradient + greenGradient + redGradient > threshold) { exceedsThreshold = true; } else { byteOffset -= 2; blueGradient = Math.Abs(pixelBuffer[byteOffset - 4 - sourceData.Stride] - pixelBuffer[byteOffset + 4 + sourceData.Stride]) / derivative; blueGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] - pixelBuffer[byteOffset + sourceData.Stride - 4]) / derivative; byteOffset++; greenGradient = Math.Abs(pixelBuffer[byteOffset - 4 - sourceData.Stride] - pixelBuffer[byteOffset + 4 + sourceData.Stride]) / derivative; greenGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] - pixelBuffer[byteOffset + sourceData.Stride - 4]) / derivative; byteOffset++; redGradient = Math.Abs(pixelBuffer[byteOffset - 4 - sourceData.Stride] - pixelBuffer[byteOffset + 4 + sourceData.Stride]) / derivative; redGradient += Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] - pixelBuffer[byteOffset + sourceData.Stride - 4]) / derivative; if (blueGradient + greenGradient + redGradient > threshold) { exceedsThreshold = true; } else { exceedsThreshold = false; } } } } byteOffset -= 2; if (exceedsThreshold) { if (filterType == EdgeFilterType.EdgeDetectMono) { blue = green = red = 255; } else if (filterType == EdgeFilterType.EdgeDetectGradient) { blue = blueGradient * blueFactor; green = greenGradient * greenFactor; red = redGradient * redFactor; } else if (filterType == EdgeFilterType.Sharpen) { blue = pixelBuffer[byteOffset] * blueFactor; green = pixelBuffer[byteOffset + 1] * greenFactor; red = pixelBuffer[byteOffset + 2] * redFactor; } else if (filterType == EdgeFilterType.SharpenGradient) { blue = pixelBuffer[byteOffset] + blueGradient * blueFactor; green = pixelBuffer[byteOffset + 1] + greenGradient * greenFactor; red = pixelBuffer[byteOffset + 2] + redGradient * redFactor; } } else { if (filterType == EdgeFilterType.EdgeDetectMono || filterType == EdgeFilterType.EdgeDetectGradient) { blue = green = red = 0; } else if (filterType == EdgeFilterType.Sharpen || filterType == EdgeFilterType.SharpenGradient) { blue = pixelBuffer[byteOffset]; green = pixelBuffer[byteOffset + 1]; red = pixelBuffer[byteOffset + 2]; } } blue = (blue > 255 ? 255 : (blue < 0 ? 0 : blue)); green = (green > 255 ? 255 : (green < 0 ? 0 : green)); red = (red > 255 ? 255 : (red < 0 ? 0 : red)); resultBuffer[byteOffset] = (byte)blue; resultBuffer[byteOffset + 1] = (byte)green; resultBuffer[byteOffset + 2] = (byte)red; resultBuffer[byteOffset + 3] = 255; } } System.Drawing.Bitmap resultBitmap = new System.Drawing.Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData); return(resultBitmap); }
/// <summary> /// Cartoon effect filter. /// </summary> /// <param name="data">Image data.</param> /// <param name="filterType">Filter type.</param> /// <param name="derivativeLevel">Derivative</param> /// <param name="rFactor">Red factor</param> /// <param name="gFactor">Green factor.</param> /// <param name="bFactor">Blue factor.</param> /// <param name="threshold">Threshold.</param> /// <returns>Execution time.</returns> public static TimeSpan EdgeDetection_GradientBased(ImageData data, EdgeFilterType filterType, DerivativeLevel derivativeLevel, double rFactor = 1.0, double gFactor = 1.0, double bFactor = 1.0, byte threshold = 0) { // Lock the bitmap's bits. BitmapData bmpData = data.M_bitmap.LockBits(new Rectangle(0, 0, data.M_width, data.M_height), ImageLockMode.ReadWrite, data.M_bitmap.PixelFormat); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare 2 arrays to hold the bytes of the bitmap. // The first to read from and then write to the scond. int bytes = bmpData.Stride*bmpData.Height; byte[] rgbValues = new byte[bytes]; byte[] bgrValues = new byte[bytes]; int derivative = (int)derivativeLevel; // Get the bytes per pixel value. int bytesPerPixel = Image.GetPixelFormatSize(data.M_bitmap.PixelFormat)/8; Stopwatch watch = Stopwatch.StartNew(); // Copy the RGB values into the array. Marshal.Copy(ptr, rgbValues, 0, bytes); #region Algorithm for (int i = 1; i < bmpData.Height - 1; i++) { for (int j = 1; j < bmpData.Width - 1; j++) { int index = i*bmpData.Stride + j*bytesPerPixel; int bGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel])/derivative; int gGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel])/derivative; int rGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel])/derivative; bGradient += Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride])/derivative; gGradient += Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride])/derivative; rGradient += Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride])/derivative; bool exceedsThreshold = false; if (bGradient + gGradient + rGradient > threshold) { exceedsThreshold = true; } else { bGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel]); gGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel]); rGradient = Math.Abs(rgbValues[index - bytesPerPixel] - rgbValues[index + bytesPerPixel]); if (bGradient + gGradient + rGradient > threshold) { exceedsThreshold = true; } else { bGradient = Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride]); gGradient = Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride]); rGradient = Math.Abs(rgbValues[index - bmpData.Stride] - rgbValues[index + bmpData.Stride]); if (bGradient + gGradient + rGradient > threshold) { exceedsThreshold = true; } else { bGradient = Math.Abs(rgbValues[index - bytesPerPixel - bmpData.Stride] - rgbValues[index + bytesPerPixel + bmpData.Stride])/derivative; gGradient = Math.Abs(rgbValues[index - bytesPerPixel - bmpData.Stride] - rgbValues[index + bytesPerPixel + bmpData.Stride])/derivative; rGradient = Math.Abs(rgbValues[index - bytesPerPixel - bmpData.Stride] - rgbValues[index + bytesPerPixel + bmpData.Stride])/derivative; gGradient += Math.Abs(rgbValues[index - bmpData.Stride + bytesPerPixel] - rgbValues[index + bmpData.Stride - bytesPerPixel])/derivative; bGradient += Math.Abs(rgbValues[index - bmpData.Stride + bytesPerPixel] - rgbValues[index + bmpData.Stride - bytesPerPixel])/derivative; rGradient += Math.Abs(rgbValues[index - bmpData.Stride + bytesPerPixel] - rgbValues[index + bmpData.Stride - bytesPerPixel])/derivative; if (bGradient + gGradient + rGradient > threshold) { exceedsThreshold = true; } else { exceedsThreshold = false; } } } } double b = 0.0; double g = 0.0; double r = 0.0; if (exceedsThreshold) { switch (filterType) { case EdgeFilterType.EdgeDetectMono: b = g = r = 255; break; case EdgeFilterType.EdgeDetectGradient: b = bGradient*bFactor; g = gGradient*gFactor; r = rGradient*rFactor; break; case EdgeFilterType.Sharpen: b = rgbValues[index]*bFactor; g = rgbValues[index + 1]*gFactor; r = rgbValues[index + 2]*rFactor; break; case EdgeFilterType.SharpenGradient: b = rgbValues[index] + bGradient*bFactor; g = rgbValues[index + 1] + gGradient*gFactor; r = rgbValues[index + 2] + rGradient*rFactor; break; } } else { if (filterType == EdgeFilterType.EdgeDetectMono || filterType == EdgeFilterType.EdgeDetectGradient) { b = g = r = 0; } else if (filterType == EdgeFilterType.Sharpen || filterType == EdgeFilterType.SharpenGradient) { b = rgbValues[index]; g = rgbValues[index + 1]; r = rgbValues[index + 2]; } } if (b > 255.0) { b = 255.0; } else if (b < 0.0) { b = 0.0; } if (g > 255.0) { g = 255.0; } else if (g < 0.0) { g = 0.0; } if (r > 255.0) { r = 255.0; } else if (r < 0.0) { r = 0.0; } bgrValues[index] = (byte)b; bgrValues[index + 1] = (byte)g; bgrValues[index + 2] = (byte)r; } } #endregion Marshal.Copy(bgrValues, 0, ptr, bytes); watch.Stop(); TimeSpan elapsedTime = watch.Elapsed; // Unlock the bits. data.M_bitmap.UnlockBits(bmpData); return elapsedTime; }