private void gauss_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                gauss gaussFilter = new gauss();
                if (gaussFilter.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);                    double[] tempArray;
                    double[] tempImage = new double[bytes];
                    double sigma = gaussFilter.GetSigma;
                    for (int i = 0; i < bytes; i++)
                    {
                        tempImage[i] = Convert.ToDouble(grayValues[i]);
                    }                    gaussSmooth(tempImage, out tempArray, sigma);                    for (int i = 0; i < bytes; i++)
                    {
                        if (tempArray[i] > 255)
                            grayValues[i] = 255;
                        else if (tempArray[i] < 0)
                            grayValues[i] = 0;
                        else
                            grayValues[i] = Convert.ToByte(tempArray[i]);
                    }                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }                Invalidate();
            }
        }
private void gaussSmooth(double[] inputImage, out double[] outputImage, double sigma)
        {
            double std2 = 2 * sigma * sigma;
            int radius = Convert.ToInt16(Math.Ceiling(3 * sigma));
            int filterWidth = 2 * radius + 1;
            double[] filter = new double[filterWidth];
            outputImage = new double[inputImage.Length];
            int length = Convert.ToInt16(Math.Sqrt(inputImage.Length));
            double[] tempImage = new double[inputImage.Length];            double sum = 0;
            for (int i = 0; i < filterWidth; i++)
            {
                int xx = (i - radius) * (i - radius);
                filter[i] = Math.Exp(-xx / std2);
                sum += filter[i];
            }
            for (int i = 0; i < filterWidth; i++)
            {
                filter[i] = filter[i] / sum;
            }            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(j + k)) % length;
                        temp += inputImage[i * length + rem] * filter[k + radius];
                    }
                    tempImage[i * length + j] = temp;
                }
            }
            for (int j = 0; j < length; j++)
            {
                for (int i = 0; i < length; i++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(i + k)) % length;
                        temp += tempImage[rem * length + j] * filter[k + radius];
                    }
                    outputImage[i * length + j] = temp;
                }
            }
        }
这个高斯滤波算法有些错误,我没看出来,求指点

解决方案 »

  1.   

    private void gauss_Click(object sender, EventArgs e)
      {
      if (curBitmap != null)
      {
      gauss gaussFilter = new gauss();
      if (gaussFilter.ShowDialog() == DialogResult.OK)
      {
      Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
      System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
      IntPtr ptr = bmpData.Scan0;
      int bytes = curBitmap.Width * curBitmap.Height;
      byte[] grayValues = new byte[bytes];
      System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);  double[] tempArray;
      double[] tempImage = new double[bytes];
      double sigma = gaussFilter.GetSigma;
      for (int i = 0; i < bytes; i++)
      {
      tempImage[i] = Convert.ToDouble(grayValues[i]);
      }  gaussSmooth(tempImage, out tempArray, sigma);  for (int i = 0; i < bytes; i++)
      {
      if (tempArray[i] > 255)
      grayValues[i] = 255;
      else if (tempArray[i] < 0)
      grayValues[i] = 0;
      else
      grayValues[i] = Convert.ToByte(tempArray[i]);
      }  System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
      curBitmap.UnlockBits(bmpData);
      }  Invalidate();
      }
      }
    private void gaussSmooth(double[] inputImage, out double[] outputImage, double sigma)
      {
      double std2 = 2 * sigma * sigma;
      int radius = Convert.ToInt16(Math.Ceiling(3 * sigma));
      int filterWidth = 2 * radius + 1;
      double[] filter = new double[filterWidth];
      outputImage = new double[inputImage.Length];
      int length = Convert.ToInt16(Math.Sqrt(inputImage.Length));
      double[] tempImage = new double[inputImage.Length];  double sum = 0;
      for (int i = 0; i < filterWidth; i++)
      {
      int xx = (i - radius) * (i - radius);
      filter[i] = Math.Exp(-xx / std2);
      sum += filter[i];
      }
      for (int i = 0; i < filterWidth; i++)
      {
      filter[i] = filter[i] / sum;
      }  for (int i = 0; i < length; i++)
      {
      for (int j = 0; j < length; j++)
      {
      double temp = 0;
      for (int k = -radius; k <= radius; k++)
      {
      int rem = (Math.Abs(j + k)) % length;
      temp += inputImage[i * length + rem] * filter[k + radius];
      }
      tempImage[i * length + j] = temp;
      }
      }
      for (int j = 0; j < length; j++)
      {
      for (int i = 0; i < length; i++)
      {
      double temp = 0;
      for (int k = -radius; k <= radius; k++)
      {
      int rem = (Math.Abs(i + k)) % length;
      temp += tempImage[rem * length + j] * filter[k + radius];
      }
      outputImage[i * length + j] = temp;
      }
      }
      }这个高斯滤波算法有些错误,我没看出来,求指点
      

  2.   

    算法没问题,他对图片做了限制只是方形的图片 
    int bytes = curBitmap.Width * curBitmap.Height;
    ########
    int length = Convert.ToInt16(Math.Sqrt(inputImage.Length));
    只有方形的图才能这样处理。
    ,且是4的倍数才行(用的是width)