对原图进行高斯平滑,去除图像中的计算噪声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;
}
