影像處理之基礎---濾波器之高斯低通濾波器的高斯模板產生c實現

來源:互聯網
上載者:User

標籤:blog   http   io   ar   for   sp   資料   on   art   

()代碼實現

對原圖進行高斯平滑,去除映像中的計算雜訊
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

影像處理之基礎---濾波器之高斯低通濾波器的高斯模板產生c實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.