维纳滤波实现(VC++)

来源:互联网 发布:网易闪电邮mac版官网 编辑:程序博客网 时间:2024/05/07 15:05

本代码中涉及到的相关函数见上篇“逆滤波的实现(VC++)”


//参数说明:

//LPSTR lpDIBBits:指向源DIB图像指针
//LONG  lWidth:源图像宽度(象素数)
//LONG  lHeight:源图像高度(象素数)
//函数说明:
//该函数用来对DIB图像进行维纳滤波复原操作。
BOOL WINAPI WienerDIB (LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源图像的指针
LPSTR lpSrc;
//循环变量
long i;
long j;
//像素值
unsigned char pixel;
// 图像每行的字节数
LONG lLineBytes;
//用于做FFT的数组
double *fftSrc,*fftKernel,*fftNoise;
double a,b,c,d,e,f,multi;
//二维FFT的长度和宽度
unsigned long nn[3];
//图像归一化因子
double MaxNum;

// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);

double dPower = log((double)lLineBytes)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
dPower = log((double)lHeight)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}

fftSrc = new double [lHeight*lLineBytes*2+1];
fftKernel = new double [lHeight*lLineBytes*2+1];
fftNoise = new double [lHeight*lLineBytes*2+1];

nn[1] = lHeight;
nn[2] = lLineBytes;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;

pixel = (unsigned char)*lpSrc;

fftSrc[(2*lLineBytes)*j + 2*i + 1] = (double)pixel;
fftSrc[(2*lLineBytes)*j + 2*i + 2] = 0.0;

if(i < 5 && j == 0)
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 1/5.0;
}
else
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 0.0;
}
fftKernel[(2*lLineBytes)*j + 2*i + 2] = 0.0;
if ( i + j == ((int)((i+j)/8))*8)
{
fftNoise [(2*lLineBytes)*j + 2*i + 1]= -16.0;
}
else
{
fftNoise [(2*lLineBytes)*j + 2*i + 1]= 0.0;
}
fftNoise[(2*lLineBytes)*j + 2*i + 2] = 0.0;
}
}

srand((unsigned)time(NULL));
//对源图像进行FFT
fourn(fftSrc,nn,2,1);
//对卷积核图像进行FFT
fourn(fftKernel,nn,2,1);
//对噪声图像进行FFT
fourn(fftNoise,nn,2,1);

for (i = 1;i <lHeight*lLineBytes*2;i+=2)
{
a = fftSrc[i];
b = fftSrc[i+1];
c = fftKernel[i];
d = fftKernel[i+1];
e = fftNoise[i];
f = fftNoise[i+1];
multi = (a*a + b*b)/(a*a + b*b - e*e - f*f);
if (c*c + d*d > 1e-3)
{
fftSrc[i] = ( a*c + b*d ) / ( c*c + d*d ) / multi;
fftSrc[i+1] = ( b*c - a*d ) / ( c*c + d*d )/multi;
}
}

//对结果图像进行反FFT
fourn(fftSrc,nn,2,-1);

//确定归一化因子
MaxNum = 0.0;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
fftSrc[(2*lLineBytes)*j + 2*i + 1] = 
sqrt(fftSrc[(2*lLineBytes)*j + 2*i + 1] * fftSrc[(2*lLineBytes)*j + 2*i + 1]\
+fftSrc[(2*lLineBytes)*j + 2*i + 2] * fftSrc[(2*lLineBytes)*j + 2*i + 2]);
if( MaxNum < fftSrc[(2*lLineBytes)*j + 2*i + 1])
MaxNum = fftSrc[(2*lLineBytes)*j + 2*i + 1];
}
}

//转换为图像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;

*lpSrc = (unsigned char) (fftSrc[(2*lLineBytes)*j + 2*i + 1]*255.0/MaxNum );
}
}

delete[] fftSrc;
delete[] fftKernel;
delete[] fftNoise;
// 返回
return true;
}
原创粉丝点击