zoukankan      html  css  js  c++  java
  • 高斯滤波代码

    #region 二维高斯滤波
            //高斯滤波器
            private double[,] gaussFilter(int size,double sigma)
            {
                double[,] arr=new double[size,size];
                double sum = 0.0;
                int center = size; //以第一个点的坐标为原点,求出中心点的坐标
                for (int i = 0; i < size; ++i)
                    for (int j = 0; j < size; ++j) 
                        sum += arr[i,j] = Math.Exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (2 * sigma*sigma));
                for (int i = 0; i < size; ++i)
                    for (int j = 0; j < size; ++j)
                        arr[i,j] /= sum;
                return arr;
                //for (int i = 0; i < size; ++i) {
                //    for (int j = 0; j < size; ++j)
                //        Console.Write(arr[i,j]+" ");
                //    Console.WriteLine();
                //}
            }
            //高斯滤波算法
            private void myGaussFilter(short[,] data)
            {
                int w_Data = data.GetLength(0);
                int h_Data = data.GetLength(1);
                double[,] arr=gaussFilter(3,1.5);
                for (int i = 2; i < w_Data-1; i++)
                {
                    for (int j = 2; j < h_Data-1; j++)
                    {
                        bool judgeBool = false;
                        for (int a = i - 1; a <= i + 1; a++)
                        {
                            for (int b = j - 1; b <= j + 1; b++)
                            {
                                if (Math.Abs(a - i) == 1 || Math.Abs(b - j) == 1)
                                {
                                    if (data[a, b] == 0)
                                    {
                                        judgeBool=true;
                                        break;
                                    }
                                }
                            }
                            if (judgeBool)
                            {
                                break;
                            }
                        }
                        if (judgeBool)
                        {
                            //if (data[i, j] > 0)
                            //{
                            //    short[,] shortTmp = (short[,])data.Clone();
                            //    data[i, j] = edgeBianTong(shortTmp, new Point(i, j), arr);
                            //}
                            continue;
                        }
                        double tmpValue = 0;
                        for (int x = 0; x < 3; x++)
                        {
                            for (int y = 0; y < 3; y++)
                            {
                                tmpValue += data[i + 1 - x, j + 1 - y] * arr[x, y];//高斯滤波矩阵是对称的
                                
                            }
                        }
                        data[i, j] = (short)tmpValue;
                    }
                }
            }
            private void myGaussFilter123(short[,] data)
            {
                int w_Data = data.GetLength(0);
                int h_Data = data.GetLength(1);
                double[,] arr = gaussFilter(3, 1.5);
                for (int i = 2; i < w_Data - 1; i++)
                {
                    for (int j = 2; j < h_Data - 1; j++)
                    {
                        bool judgeBool = false;
                        for (int a = i - 1; a <= i + 1; a++)
                        {
                            for (int b = j - 1; b <= j + 1; b++)
                            {
                                if (Math.Abs(a - i) == 1 || Math.Abs(b - j) == 1)
                                {
                                    if (data[a, b] == 0)
                                    {
                                        judgeBool = true;
                                        break;
                                    }
                                }
                            }
                            if (judgeBool)
                            {
                                break;
                            }
                        }
                        if (judgeBool)
                        {
                            if (data[i, j] > 0)
                            {
                                short[,] shortTmp = (short[,])data.Clone();
                                data[i, j] = edgeBianTong(shortTmp, new Point(i, j), arr);
                            }
                            continue;
                        }
                        double tmpValue = 0;
                        for (int x = 0; x < 3; x++)
                        {
                            for (int y = 0; y < 3; y++)
                            {
                                tmpValue += data[i + 1 - x, j + 1 - y] * arr[x, y];//高斯滤波矩阵是对称的
    
                            }
                        }
                        data[i, j] = (short)tmpValue;
                    }
                }
            }
            //边界变通
            private short edgeBianTong(short[,] data, Point point, double[,] arr)
            {
                //扩充边界和高斯滤波同时进行
                double tmpValue = 0;
                for (int i = point.X - 1 ,a=0; i <= point.X + 1; i++,a++)
                {
                    for (int j = point.Y - 1 ,b=0; j <= point.Y + 1; j++,b++)
                    {
                        if (data[i, j] == 0)
                        {
                            data[i, j] = data[point.X,point.Y];
                        }
                        //tmpValue += data[i, j] * arr[1-Math.Abs(i - point.X), 1-Math.Abs(j - point.Y)];
                        tmpValue += data[i, j] * arr[a,b];
                    }
                }
                return (short)tmpValue;
            }
            #endregion

    注:

      1.本例子是红外图像做差得到的人体图像,非人体图像温度数值都为0.

      2.myGaussFilter123含边界点(未全包含:整幅图像的边界未包含,仅涵盖了图像(不不包括图像边界)中的人体边缘点)。

      3.myGaussFilter不含边界点,经测试发现,对边界去毛边并未有区别(也许与自己扩充边界用原值复制相关,有待进一步测试),所以对于整幅图像的边界点不再进行高斯滤波处理了。

      4.不过对于颗粒度有点强的图像,用高斯滤波圆润挺好的。

  • 相关阅读:
    临界区,互斥量,信号量,事件的区别
    解决位图失真-SetStretchBltMode()
    Invalidate、RedrawWindow与UpdateWindow
    Shlwapi.h Shlwapi.dll 动态库
    C++ _access和_waccess的使用方法
    纯C++ 连接SQL Server2005 数据库读写操作的小例子
    测试代码执行时间的帮助类
    BUG: GetDC() ReleaseDC()引起的内存泄漏
    DebugView图文教程
    CreateFile函数详解
  • 原文地址:https://www.cnblogs.com/gaara-zhang/p/9565091.html
Copyright © 2011-2022 走看看