一维高斯滤波java_图像处理之基础---滤波器之高斯低通滤波器3c代码实现yuv,rgb...

()高斯理论简介

()

()代码实现

四 使用高斯滤波器进行图像的平滑

()高斯简介

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

1335629571_9781.jpg

生成高斯核

/*************************************************************************

*

* \函数名称:

*   MakeGauss()

*

* \输入参数:

*   double sigma                                            - 高斯函数的标准差

*   double **pdKernel                                        - 指向高斯数据数组的指针

*   int *pnWindowSize                                        - 数据的长度

*

* \返回值:

*   无

*

* \说明:

*   这个函数可以生成一个一维的高斯函数的数字数据,理论上高斯数据的长度应

*   该是无限长的,但是为了计算的简单和速度,实际的高斯数据只能是有限长的

*   pnWindowSize就是数据长度

*

*************************************************************************

*/

void MakeGauss(double sigma, double **pdKernel, int *pnWindowSize)

{

// 循环控制变量

int i   ;

// 数组的中心点

int nCenter;

// 数组的某一点到中心点的距离

double  dDis  ;

double PI = 3.14159;

// 中间变量

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

{

(*pdKernel)[i] /= dSum;

}

}

高斯滤波

/*************************************************************************

*

* \函数名称:

*   GaussianSmooth()

*

* \输入参数:

*   unsigned char * pUnchImg                - 指向图象数据的指针

*   int nWidth                                            - 图象数据宽度

*   int nHeight                                        - 图象数据高度

*   double dSigma                                    - 高斯函数的标准差

*   unsigned char * pUnchSmthdImg    - 指向经过平滑之后的图象数据

*

* \返回值:

*   无

*

* \说明:

*   为了抑止噪声,采用高斯滤波对图象进行滤波,滤波先对x方向进行,然后对

*   y方向进行。

*

*************************************************************************

*/

void GaussianSmooth(unsigned char *pUnchImg, int nWidth, int nHeight,

double sigma, unsigned char * pUnchSmthdImg)

{

// 循环控制变量

int y;

int x;

int i;

// 高斯滤波器的数组长度

int nWindowSize;

//  窗口长度的1/2

int    nHalfLen;

// 一维高斯数据滤波器

double *pdKernel ;

// 高斯系数与图象数据的点乘

double  dDotMul     ;

// 高斯滤波系数的总和

double  dWeightSum     ;

// 中间变量

double * pdTmp ;

// 分配内存

pdTmp = new double[nWidth*nHeight];

// 产生一维高斯数据滤波器

// MakeGauss(sigma, &dKernel, &nWindowSize);

MakeGauss(sigma, &pdKernel, &nWindowSize) ;

// MakeGauss返回窗口的长度,利用此变量计算窗口的半长

nHalfLen = nWindowSize / 2;

// x方向进行滤波

for(y=0; y

{

for(x=0; 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 ;

}

}

// y方向进行滤波

for(x=0; x

{

for(y=0; 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] = (unsigned char)(int)dDotMul/dWeightSum ;

}

}

// 释放内存

delete []pdKernel;

pdKernel = NULL ;

delete []pdTmp;

pdTmp = NULL;

}

void gaussianFilter(uchar* data,int width,int height)

02

{

03

int i, j, index, sum;

04

int templates[9] = { 1, 2, 1,

05

2, 4, 2,

06

1, 2, 1 };

07

sum = height * width *sizeof(uchar);

08

uchar *tmpdata = (uchar*)malloc(sum);

09

memcpy((char*)tmpdata,(char*)data, sum);

10

for(i = 1;i < height - 1;i++)

11

{

12

for(j = 1;j < width - 1;j++)

13

{

14

index = sum = 0;

15

for(int m = i - 1;m < i + 2;m++)

16

{

17

for(int n = j - 1; n < j + 2;n++)

18

{

19

sum +=

20

tmpdata[m * width + n] *

21

templates[index++];

22

}

23

}

24

data[i * width + j] = sum / 16;

25

}

26

}

27

free(tmpdata);

28

}

一个模板

//**********************************************************************

//模板操作

//图像信息头

//图像数据

//模板大小       以0开始

//模板中心元素   以0开始

//模板数据

//模板系数

//**********************************************************************

BOOL ImgTemplate(BITMAPINFO* pbmpinfo,BYTE* pbmpdata,CSize TemplateSize,CSize TemplateCertel ,int *template_box,float coef)

{

LONG imagewidth=pbmpinfo->bmiHeader.biWidth;

LONG imageheigth=pbmpinfo->bmiHeader.biHeight;

LONG i=0,j=0,k=0,heigth=0,width=0;

//data is not null

if (pbmpdata == NULL)

{

return FALSE;

}

//image size

if (imageheigth <= TemplateSize.cy || imagewidth <= TemplateSize.cx)

{

return FALSE;

}

if (TemplateCertel.cx < 0 ||  TemplateCertel.cy < 0 || TemplateCertel.cx > TemplateSize.cx || TemplateCertel.cy > TemplateSize.cy)

{

return FALSE;

}

//color must be gray

if (pbmpinfo->bmiHeader.biBitCount != 8)

{

AfxMessageBox("只对灰度图像进行操作!");

return FALSE;

}

//image size

LONG  Linebyte =( pbmpinfo->bmiHeader.biBitCount * imagewidth +31)/32*4;

LONG  ImageSize=Linebyte * imageheigth;

//分配空间

BYTE *pNewbmpdata=(BYTE*)malloc(ImageSize);

//copy data

if (pNewbmpdata == NULL)

{

return FALSE;

}

memcpy(pNewbmpdata,pbmpdata,ImageSize);

BYTE *psrc=NULL;

BYTE *pdest=NULL;

LONG result=0;

for (heigth = TemplateCertel.cy ; heigth < imageheigth - TemplateSize.cy + TemplateCertel.cy + 1  ;heigth++  )

{

for ( width = TemplateCertel.cx ; width < imagewidth - TemplateSize.cx + TemplateCertel.cx + 1 ; width++)

{

psrc  = (unsigned char *)pbmpdata+(ImageSize-Linebyte-

heigth*Linebyte)+width;

pdest = (unsigned char *)pNewbmpdata+(ImageSize-Linebyte-

heigth*Linebyte)+width;

j=0;

result=0;

for ( i =  - TemplateCertel.cy ; i

{

for (k =  - TemplateCertel.cx ; k

{

result += (LONG)(*(psrc + i * Linebyte + k)) * template_box[j++];

}

}

result = (LONG)(result  *  coef);

if (result>255)

{

result=255;

}

if (result<0)

{

result=0;

}

*pdest=(unsigned char)result;

}

}

memcpy(pbmpdata,pNewbmpdata,ImageSize);

free(pNewbmpdata);

return TRUE;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值