標籤: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實現