예제 #1
0
        private void ApplyFilter()
        {
            if (previewBitmap == null || cmbSmoothingFilter.SelectedIndex == -1)
            {
                return;
            }
            if (previewBitmap != null)
            {
                SmoothingFilterType filterType = ((SmoothingFilterType)cmbSmoothingFilter.SelectedItem);

                resultBitmap = previewBitmap.CartoonEffectFilter(this, filterType);
            }
        }
        public static Bitmap CartoonEffectFilter(
            Bitmap sourceBitmap,
            byte threshold = 0,
            SmoothingFilterType smoothFilter
            = SmoothingFilterType.None)
        {
            sourceBitmap = SmoothingFilter(sourceBitmap, smoothFilter);

            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    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]);

                    blueGradient +=
                        Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] -
                                 pixelBuffer[byteOffset + sourceData.Stride]);

                    byteOffset++;

                    greenGradient =
                        Math.Abs(pixelBuffer[byteOffset - 4] -
                                 pixelBuffer[byteOffset + 4]);

                    greenGradient +=
                        Math.Abs(pixelBuffer[byteOffset - sourceData.Stride] -
                                 pixelBuffer[byteOffset + sourceData.Stride]);

                    byteOffset++;

                    redGradient =
                        Math.Abs(pixelBuffer[byteOffset - 4] -
                                 pixelBuffer[byteOffset + 4]);

                    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] -
                                                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]);

                                blueGradient +=
                                    Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] -
                                             pixelBuffer[byteOffset + sourceData.Stride - 4]);

                                byteOffset++;

                                greenGradient =
                                    Math.Abs(pixelBuffer[byteOffset - 4 - sourceData.Stride] -
                                             pixelBuffer[byteOffset + 4 + sourceData.Stride]);

                                greenGradient +=
                                    Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] -
                                             pixelBuffer[byteOffset + sourceData.Stride - 4]);

                                byteOffset++;

                                redGradient =
                                    Math.Abs(pixelBuffer[byteOffset - 4 - sourceData.Stride] -
                                             pixelBuffer[byteOffset + 4 + sourceData.Stride]);

                                redGradient +=
                                    Math.Abs(pixelBuffer[byteOffset - sourceData.Stride + 4] -
                                             pixelBuffer[byteOffset + sourceData.Stride - 4]);

                                if (blueGradient + greenGradient + redGradient > threshold)
                                {
                                    exceedsThreshold = true;
                                }
                                else
                                {
                                    exceedsThreshold = false;
                                }
                            }
                        }
                    }

                    byteOffset -= 2;

                    if (exceedsThreshold)
                    {
                        blue  = 0;
                        green = 0;
                        red   = 0;
                    }
                    else
                    {
                        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;
                }
            }

            Bitmap resultBitmap = new 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);
        }
        public static Bitmap SmoothingFilter(Bitmap sourceBitmap,
                                             SmoothingFilterType smoothFilter =
                                             SmoothingFilterType.None)
        {
            Bitmap inputBitmap = null;

            switch (smoothFilter)
            {
            case SmoothingFilterType.None:
            {
                inputBitmap = sourceBitmap;
            }
            break;

            case SmoothingFilterType.Gaussian3x3:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Gaussian3x3, 1.0 / 16.0, 0);
            }
            break;

            case SmoothingFilterType.Gaussian5x5:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Gaussian5x5, 1.0 / 159.0, 0);
            }
            break;

            case SmoothingFilterType.Gaussian7x7:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Gaussian7x7, 1.0 / 136.0, 0);
            }
            break;

            case SmoothingFilterType.Median3x3:
            {
                inputBitmap = MedianFilter(sourceBitmap, 3);
            }
            break;

            case SmoothingFilterType.Median5x5:
            {
                inputBitmap = MedianFilter(sourceBitmap, 5);
            }
            break;

            case SmoothingFilterType.Median7x7:
            {
                inputBitmap = MedianFilter(sourceBitmap, 7);
            }
            break;

            case SmoothingFilterType.Median9x9:
            {
                inputBitmap = MedianFilter(sourceBitmap, 9);
            }
            break;

            case SmoothingFilterType.Mean3x3:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Mean3x3, 1.0 / 9.0, 0);
            }
            break;

            case SmoothingFilterType.Mean5x5:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Mean5x5, 1.0 / 25.0, 0);
            }
            break;

            case SmoothingFilterType.LowPass3x3:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.LowPass3x3, 1.0 / 16.0, 0);
            }
            break;

            case SmoothingFilterType.LowPass5x5:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.LowPass5x5, 1.0 / 60.0, 0);
            }
            break;

            case SmoothingFilterType.Sharpen3x3:
            {
                inputBitmap = ConvolutionFilter(sourceBitmap,
                                                Matrix.Sharpen3x3, 1.0 / 8.0, 0);
            }
            break;
            }

            return(inputBitmap);
        }
예제 #4
0
 public static Bitmap CartoonEffectFilter(this Bitmap sourceBitmap, MainForm form, SmoothingFilterType smoothFilter = SmoothingFilterType.Nenhum)
 {
     sourceBitmap = sourceBitmap.SmoothingFilter(form, smoothFilter);
     return(sourceBitmap);
 }
예제 #5
0
        public static Bitmap SmoothingFilter(this Bitmap sourceBitmap, MainForm form,
                                             SmoothingFilterType smoothFilter =
                                             SmoothingFilterType.Nenhum)
        {
            Bitmap inputBitmap = null;

            //Progress bar
            form.algorithmProgress = 0;

            switch (smoothFilter)
            {
            case SmoothingFilterType.Nenhum:
            {
                inputBitmap = sourceBitmap;
            } break;

            case SmoothingFilterType.Gaussiano3x3:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Gaussian3x3, 1.0 / 16.0, 0);
            } break;

            case SmoothingFilterType.Gaussiano5x5:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Gaussian5x5, 1.0 / 159.0, 0);
            } break;

            case SmoothingFilterType.Gaussiano7x7:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Gaussian7x7, 1.0 / 136.0, 0);
            } break;

            case SmoothingFilterType.Mediano3x3:
            {
                inputBitmap = sourceBitmap.MedianFilter(3);
            } break;

            case SmoothingFilterType.Mediano5x5:
            {
                inputBitmap = sourceBitmap.MedianFilter(5);
            } break;

            case SmoothingFilterType.Mediano7x7:
            {
                inputBitmap = sourceBitmap.MedianFilter(7);
            } break;

            case SmoothingFilterType.Mediano9x9:
            {
                inputBitmap = sourceBitmap.MedianFilter(9);
            } break;

            case SmoothingFilterType.Mean3x3:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Mean3x3, 1.0 / 9.0, 0);
            } break;

            case SmoothingFilterType.Mean5x5:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Mean5x5, 1.0 / 25.0, 0);
            } break;

            case SmoothingFilterType.LowPass3x3:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.LowPass3x3, 1.0 / 16.0, 0);
            } break;

            case SmoothingFilterType.LowPass5x5:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.LowPass5x5, 1.0 / 60.0, 0);
            } break;

            case SmoothingFilterType.Sharpen3x3:
            {
                inputBitmap = sourceBitmap.ConvolutionFilter(
                    Matrix.Sharpen3x3, 1.0 / 8.0, 0);
            } break;
            }

            //Progress bar
            form.algorithmProgress = 20;


            // START additional filters ADDED BY GABRIEL
            inputBitmap = AForge.Imaging.Image.Clone(inputBitmap, PixelFormat.Format24bppRgb); //Accepted format
            Bilateral           filterB = new Bilateral();
            Grayscale           filterG = new Grayscale(0.2125, 0.7154, 0.0721);               //arbitrary values
            CannyEdgeDetector   filterE = new CannyEdgeDetector();
            ColorImageQuantizer filterC = new ColorImageQuantizer(new MedianCutQuantizer());
            Dilatation          filterD = new Dilatation();

            //Bilateral filter as present in the article
            filterB.KernelSize    = form.kernelValue;
            filterB.SpatialFactor = form.spatialFactor;
            filterB.ColorFactor   = form.colorFactor;
            filterB.ColorPower    = form.colorPower;
            filterB.ApplyInPlace(inputBitmap);

            form.algorithmProgress = 40;

            /* GENERATING BORDERS */
            //Generate a grayscale version for edge detection
            Bitmap edges = filterG.Apply(inputBitmap);

            filterE.HighThreshold = form.highThreshold;
            filterE.LowThreshold  = form.lowThreshold;
            filterE.ApplyInPlace(edges); // a new image, edges, is created here defining the edges of inputBitmap
            //Dilatation filter
            edges = filterD.Apply(edges);
            generateBorder(edges);
            //Making bg transparent
            edges.MakeTransparent(Color.White);


            form.algorithmProgress = 70;


            // Color reduction as present in the article
            inputBitmap = filterC.ReduceColors(inputBitmap, form.colorReductionFactor);         // reduces to 24 variation

            inputBitmap = AForge.Imaging.Image.Clone(inputBitmap, PixelFormat.Format32bppArgb); //Accepted format

            // images merge
            Bitmap   bitmapResult = new Bitmap(inputBitmap.Width, inputBitmap.Height, inputBitmap.PixelFormat);
            Graphics g            = Graphics.FromImage(bitmapResult);

            g.DrawImage(inputBitmap, 0, 0, inputBitmap.Width, inputBitmap.Height);
            g.DrawImage(edges, 0, 0, inputBitmap.Width, inputBitmap.Height);
            // END additional filters ADDED BY GABRIEL

            form.algorithmProgress = 100;

            return(bitmapResult); // it was returning input Bitmap before
        }
예제 #6
0
        /// <summary>
        /// Smoothing Filter
        /// </summary>
        /// <param name="sourceBitmap">Set source Bitmap</param>
        /// <param name="smoothFilter">Set smoothing filter</param>
        /// <returns></returns>
        public static System.Drawing.Bitmap SmoothingFilter(this System.Drawing.Bitmap sourceBitmap,
                                                            SmoothingFilterType smoothFilter =
                                                            SmoothingFilterType.None)
        {
            System.Drawing.Bitmap inputBitmap = null;

            switch (smoothFilter)
            {
            case SmoothingFilterType.None:
            {
                inputBitmap = sourceBitmap;
            } break;

            case SmoothingFilterType.Gaussian3x3:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Gaussian3x3, 1.0 / 16.0, 0);
            } break;

            case SmoothingFilterType.Gaussian5x5:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Gaussian5x5, 1.0 / 159.0, 0);
            } break;

            case SmoothingFilterType.Gaussian7x7:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Gaussian7x7, 1.0 / 136.0, 0);
            } break;

            case SmoothingFilterType.Median3x3:
            {
                inputBitmap = sourceBitmap.CartoonMedianFilter(3);
            } break;

            case SmoothingFilterType.Median5x5:
            {
                inputBitmap = sourceBitmap.CartoonMedianFilter(5);
            } break;

            case SmoothingFilterType.Median7x7:
            {
                inputBitmap = sourceBitmap.CartoonMedianFilter(7);
            } break;

            case SmoothingFilterType.Median9x9:
            {
                inputBitmap = sourceBitmap.CartoonMedianFilter(9);
            } break;

            case SmoothingFilterType.Mean3x3:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Mean3x3, 1.0 / 9.0, 0);
            } break;

            case SmoothingFilterType.Mean5x5:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Mean5x5, 1.0 / 25.0, 0);
            } break;

            case SmoothingFilterType.LowPass3x3:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.LowPass3x3, 1.0 / 16.0, 0);
            } break;

            case SmoothingFilterType.LowPass5x5:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.LowPass5x5, 1.0 / 60.0, 0);
            } break;

            case SmoothingFilterType.Sharpen3x3:
            {
                inputBitmap = sourceBitmap.CartoonConvolutionFilter(
                    Matrix.Sharpen3x3, 1.0 / 8.0, 0);
            } break;
            }

            return(inputBitmap);
        }