zoukankan      html  css  js  c++  java
  • 图像处理之基础---滤波器之高斯低通滤波器的高斯模板生成c实现

    ()代码实现

    对原图进行高斯平滑,去除图像中的计算噪声
    void Bmp::MakeGauss(double sigma,double **pdKernel,int *pnWindowSize){
     //循环控制变量
     int i;
     //数组的中心点
     int nCenter;
     //数组的某一点到中心点的距离
     double dDis;
     //中间变量
     double dValue;
     double dSum;
     dSum = 0;

     //数组长度,根据概率论的知识,选取[-3*sigma,3*sigma]以内的数据
     //这些数据会覆盖绝大部分的滤波系数
     *pnWindowSize = 1 + 2*ceil(3*sigma);

     //中心
     nCenter = (*pnWindowSize)/2;
     //分配内存
     *pdKernel = new double[*pnWindowSize];

     //生成高斯数据
     for ( i =0;i<(*pnWindowSize);i++)
     {
      dDis = (double)(i-nCenter);
      dValue = exp(-(1/2)*dDis*dDis/(sigma*sigma))/(sqrt(2*PI)*sigma);
      (*pdKernel)[i]=dValue;
      dSum+=dValue;
     }

     //归一化
     for (i = 0;i<(*pnWindowSize);i++)
     {
      (*pdKernel)[i]/=dSum;
     }
     
    }

    void Bmp::GaussianSmooth(u8_t *pUnchImg,int nWidth,int nHeight,double sigma,u8_t *pUnchSmthdImg){
     //循环变量
     int y,x,i;
        
     //高斯滤波器的数组长度
     int nWindowSize;
     //窗口长度的1/2
     int nHalfLen;
     //一维高斯数据滤波器
        double *pdKernel;

     //高斯系数与图像数据的点乘
     double dDotMul;
     //高斯滤波系数的总和
     double dWeightSum;
     //中间变量
     double *pdTmp;

     //分配内存
     pdTmp = new double[nWidth*nHeight];

     //产生一维高斯数据滤波器
     MakeGauss(sigma,&pdKernel,&nWindowSize);

     //MakeGauss返回窗口的长度,利用此变量计算窗口的半长
     nHalfLen = nWindowSize/2;

     //x方向进行滤波
     for (y=0;y<nHeight;y++)
     {
      for (x=0;x<nWidth;x++)
      {
       dDotMul = 0;
       dWeightSum = 0;
       for (i=(-nHalfLen);i<=nHalfLen;i++)
       {
        //判断是否在图像内部
        if ((i+x)>=0 && (i+x)<nWidth)
        {
         //利用高斯系数对图像数据滤波
         dDotMul += (double)pUnchImg[y*nWidth + (i+x)] * pdKernel[nHalfLen+i]; 
            dWeightSum += pdKernel[nHalfLen + i];
        }
       }
       pdTmp[y*nWidth+x]=dDotMul/dWeightSum;
       //pUnchSmthdImg[y*nWidth+x]=(u8_t)(int)dDotMul/dWeightSum;
      }//end for x
     }//end for y

        //y方向进行滤波
     for (x=0;x<nWidth;x++)
     {
      for (y=0;y<nHeight;y++)
      {
       dDotMul = 0;
       dWeightSum = 0;
       for (i=(-nHalfLen);i<=nHalfLen;i++)
       {
        //判断是否在图像内部
        if ((i+y)>=0 && (i+y)<nHeight)
        {
         //利用高斯系数对图像数据滤波
         dDotMul += (double)pdTmp[(y+i)*nWidth + x] * pdKernel[nHalfLen+i]; 
            dWeightSum += pdKernel[nHalfLen + i];
        }
       }
       pUnchSmthdImg[y*nWidth+x]=(u8_t)(int)dDotMul/dWeightSum;
      }//end for y
     }//end for x
     
     //释放内存
     delete[]pdKernel;
     pdKernel = NULL;
     delete[]pdTmp;
     pdTmp = NULL;

    main(){

     u8_t **new_temp_data;
     u8_t *new_temp;
     u32_t width,height;
     width = bmp_head->img_head->width;
     height = bmp_head->img_head->height;
     new_temp_data = (u8_t **)malloc((u32_t)width*height);
     memset(new_temp_data,(u8_t)255,(u32_t)width*height);
     new_temp = (u8_t *)new_temp_data;
     memcpy(new_temp_data,bmp_head->buf,(u32_t)width*height);

     GaussianSmooth((u8_t *)bmp_head->buf,width,height,0.05,new_temp);
     bmp_head->buf = new_temp_data;

    }

    http://blog.csdn.net/yang1994/article/details/1492815 高斯完整调用

    ()产生理论

    void MakeGauss()
    {
     double sigma = 1.4;     // σ是正态分布的标准偏差 这里为 1.4
     double dResult[5][5];    // 用于存储结果
     double dResult1[5][5];    // 用于存储结果
     
     // 数组的中心点
     int nCenterX = 2, nCenterY = 2;  // 中心点位置以1开始的吧
     int nSize = 5;
     // 数组的某一点到中心点的距离
     double  dDis; 
     double PI = 3.1415926535;
     // 中间变量
     double  dValue; 
     double  dSum  ;
     dSum = 0 ; 
     int i, j;
     
     for(i = 0; i< nSize; ++i)
     {
      for(j = 0; j < nSize; ++j)
      {
       dDis = (i - nCenterX) * (i - nCenterX) + (j  - nCenterY) * (j - nCenterY);
       dValue = exp( - dDis / (2 * sigma * sigma)) /
           (2 * PI * sigma * sigma);
       dResult[i][j] = dValue;
       dSum += dValue;
      }
     }
     // 归一化
     for(i = 0; i< nSize; ++i)
     {
      for(j = 0; j < nSize; ++j)
      {
       dResult1[i][j] = dResult[i][j] / dSum;
      }
     }
     std::cout << dSum << std::endl;
     for(i = 0; i< nSize; ++i)
     {
      for(j = 0; j < nSize; ++j)
      {
       // dResult1才是高斯的结果, 但是dResult * 1.95 * 100却得到了文章上说的结果
    // 一个标准差为1.4的高斯5x5的卷积核
       // 暂时不知道为什么。
       std::cout << (int)(dResult[i][j] * 1.95 * 100) << "  ";
      }
      std::cout << std::endl;
     }
    }
    void Gauss()
    {
        int h_size;
     float siz,sigma;
     int i, j;
     printf("Please input size of gaussian core/n");
     scanf("%d",&h_size);
     printf("Please input sigma:/n");
     scanf("%f",&sigma);
     siz=(h_size-1)/2;
     float **a,**b;
     a=new float*[h_size];
      for(int i=0;i<h_size;i++)   a[i]=new float[h_size];
     b=new float*[h_size];
         for( i=0;i<h_size;i++)   b[i]=new float[h_size];
     for(i=0;i<h_size;i++)
     {
      for(j=0;j<h_size;j++)
      {
       a[i][j]=-siz+j;
       printf("%4.2f ",a[i][j]);
      }
      printf("/n");
     }
     printf("/n");
     for( i=0;i<h_size;i++)
     {
      for(j=0;j<h_size;j++)
      {
       b[i][j]=a[j][i];
       printf("%4.2f ",b[i][j]);
      }
      printf("/n");
     }
     printf("/n");
     float h_sum=0;
     for( i=0;i<h_size;i++)
     {
      for(j=0;j<h_size;j++)
      {
       a[i][j]=a[i][j]*a[i][j];
       b[i][j]=b[i][j]*b[i][j];
       a[i][j]=-(a[i][j]+b[i][j])/(2*sigma*sigma);
       a[i][j]=exp(a[i][j]);
       if(a[i][j]<0.0001) a[i][j]=0;
       h_sum=h_sum+a[i][j];
      }
     }
     
     for(i=0;i<h_size;i++)
     {
      for(j=0;j<h_size;j++)
      {
       a[i][j]=a[i][j]/h_sum;
      }
     }
     for(i=0;i<h_size;i++)
     {
      for(j=0;j<h_size;j++)
      {
       printf("%4.4f ",a[i][j]);
      }
      printf("/n");
     }
    }

    http://blog.sina.com.cn/s/blog_71fa0df50100wodv.html

    ()高斯滤波器参数的确定

    http://tsindahui.blog.sohu.com/166075850.html

    opencv的实现,在cvFilter.cpp的init_gaussian_kernel函数中:

    sigmaX = sigma > 0 ? sigma : (n/2 – 1)*0.3 + 0.8;

    彩色图像的高斯平滑处理

    ()图文说明

    http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

    ()维基百科和中文百科

    http://en.wikipedia.org/wiki/Convolution

    http://www.zwbk.org/MyLemmaShow.aspx?lid=126233

    ()二维优化

    http://www.cnblogs.com/easymind223/archive/2012/11/13/2768680.html

    http://blog.csdn.net/lanbing510/article/details/28696833

  • 相关阅读:
    关于数据库的索引知识
    RESTful API设计相关
    Coroutine(协程)模式与线程
    Python网络编程中的服务器架构(负载均衡、单线程、多线程和同步、异步等)
    读懂diff
    Linux学习笔记——如何使用echo指令向文件写入内容
    ubuntu中执行定时任务crontab
    网络编程之异步IO,rabbitMQ笔记
    走进docker的世界之入门篇
    xml基础
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/4044303.html
Copyright © 2011-2022 走看看