写的一个非局部均匀滤波,结果由一小块出现问题
按照matlab源程序用C写的一段NLM代码,运行结果由一小块出现-2147483648,经过测试发现是在507行开始到511行的第130列到150列左右那矩阵MUL有问题。但是我不知道为啥会出现这样的计算错误,计算的average=1.#INF00,sweight=1.#INF00求大神解答啊。
程序代码:#define _CRT_SECURE_NO_DEPRECATE
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <iostream>
//定义图像尺寸
#define height 512
#define width 512
//定义相似窗口和搜索窗口维度
#define f 3
#define t 9
#define sigma 25
#define degree 4
#define h degree*sigma
//定义数组
int source[height][width];
int mir_source[height+2*f][width+2*f];
int W1[2*f+1][2*f+1];
int W2[2*f+1][2*f+1];
int MUL[2*f+1][2*f+1];
int SUB1[2*f+1][2*f+1];
int SUB2[2*f+1][2*f+1];
int result[height][width];
int psnr_c[height][width];
//定义变量
double w;
double d;
double wmax;
double sweight;
double average;
double PSNR;
//读入矩阵
void read()
{
//读入矩阵文件,并将其赋给alldata
FILE* fp=fopen("baboon_噪声.txt","r");
//FILE* source=fopen("mat.txt","r");
if(source==NULL)
{
//freopen("runhistory.txt", "a+", stdout);
printf("ERROR!\n");
return;
}
////将mat读入二维数组alldata
int i,j;
for(i=0;i<height;++i)
for(j=0;j<width;++j)
{
fscanf(fp, "%d ",&source[i][j]);//这里alldata[i][j]前一定要加&,因为这里是取地址的,和之后的输出alldata[i][j]这个数不同
}
}
//镜像函数;
void mirror()//我把行列搞反了.第三个地方出错
{
int i,j;
for(i=0;i<height+2*f;i++)
for(j=0;j<width+2*f;j++)//在mir_sourcedata[][]里进行遍历
{
if(i>(f-1)&&j>(f-1)&&i<(height+f)&&j<(width+f))//顺时针判断i,j
mir_source[i][j]=source[i-f][j-f];
else if(i<f&&j<f)//1
mir_source[i][j]=source[f-i][f-j];
else if(j>f&&i<f&&j<(width+f-1))//2
mir_source[i][j]=source[f-i][j-f];
else if(j>(width+f-1)&&i<f)//3
mir_source[i][j]=source[f-i][2*width+f-j-2];
else if(j>(width+f-1)&&i>f&&i<(height+f-1))//4
mir_source[i][j]=source[i-f][2*width+f-j-2];
else if(j>(width+f-1)&&i>(height+f-1))//5
mir_source[i][j]=source[2*height+f-i-2][2*width+f-j-2];
else if(j>f&&j<(width+f-1)&&i>(height+f-1))//6
mir_source[i][j]=source[2*height+f-i-2][j-f];
else if(j<f&&i>(height+f-1))//7
mir_source[i][j]=source[2*height+f-i-2][f-j];
else if(j<f&&i>f&&i<(height+f-1))//8
mir_source[i][j]=source[i-f][f-j];
}
}
/*
备份,正确的镜像函数
void mirror()//我把行列搞反了.第三个地方出错
{
int i,j;
for(i=0;i<height+2*f;i++)
for(j=0;j<width+2*f;j++)//在mir_sourcedata[][]里进行遍历
{
if(i>(f-1)&&j>(f-1)&&i<(height+f)&&j<(width+f))//顺时针判断i,j
mir_source[i][j]=source[i-f][j-f];
else if(i<f&&j<f)//1
mir_source[i][j]=source[f-i][f-j];
else if(j>f&&i<f&&j<(width+f-1))//2
mir_source[i][j]=source[f-i][j-f];
else if(j>(width+f-1)&&i<f)//3
mir_source[i][j]=source[f-i][2*width+f-j-2];
else if(j>(width+f-1)&&i>f&&i<(height+f-1))//4
mir_source[i][j]=source[i-f][2*width+f-j-2];
else if(j>(width+f-1)&&i>(height+f-1))//5
mir_source[i][j]=source[2*height+f-i-2][2*width+f-j-2];
else if(j>f&&j<(width+f-1)&&i>(height+f-1))//6
mir_source[i][j]=source[2*height+f-i-2][j-f];
else if(j<f&&i>(height+f-1))//7
mir_source[i][j]=source[2*height+f-i-2][f-j];
else if(j<f&&i>f&&i<(height+f-1))//8
mir_source[i][j]=source[i-f][f-j];
}
}
*/
//求最大值函数
int max_value(int a,int b)
{
int L;
if(a>=b)
L=a;
else
L=b;
return L;
}
//求最小值
int min_value(int a,int b)
{
int L;
if(a<=b)
L=a;
else
L=b;
return L;
}
//将mir_source的相应数据写入W1,W2的函数,ab代表mir_source的相应块起点
void matrix_write(int W[2*f+1][2*f+1],int a,int b)
{
int i,j;
for(i=0;i<2*f+1;i++)
for(j=0;j<2*f+1;j++)
{
W[i][j]=mir_source[i+a][j+b];//!!!!!!这里是不是有点问题
}
}
//两个矩阵相减
void matrix_sub(int A[2*f+1][2*f+1],int B[2*f+1][2*f+1],int C[2*f+1][2*f+1])
{
for(int i=0;i<2*f+1;i++)
for( int j=0;j<2*f+1;j++)
C[i][j]=abs(A[i][j]-B[i][j]);//有没有可能出现负值
}
//求矩阵的和
double matrix_sum(int A[2*f+1][2*f+1])
{
double L=0;
for(int i=0;i<2*f+1;i++)
for(int j=0;j<2*f+1;j++)
L+=A[i][j];
return L;
}
//两个矩阵相乘
/*void matrix_mul(int A[2*f+1][2*f+1],int B[2*f+1][2*f+1],int C[2*f+1][2*f+1])
{
for(int i=0;i<2*f+1;i++)
for(int j=0;j<2*f+1;j++)
for(int k=0;k<2*f+1;k++)
C[i][j]+=A[i][k]*B[k][j];
}*/
void matrix_mul_point(int A[2*f+1][2*f+1],int B[2*f+1][2*f+1],int C[2*f+1][2*f+1])
{
for(int i=0;i<2*f+1;i++)
for(int j=0;j<2*f+1;j++)
C[i][j]=A[i][j]*B[i][j];
}
//sum_psnr
double psnr_sum(int matrix_data[height][width])
{
double L=0;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
L+=matrix_data[i][j];
return L;
}
//PSNR
void PSNR_VALUE()
{
double MSE;
double sum;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
psnr_c[i][j]=(result[i][j]-source[i][j])*(result[i][j]-source[i][j]);
sum=psnr_sum(psnr_c);
MSE=sum/(height*width);
PSNR=10*log10(255*255/MSE);
}
//输出debug时的W1,W2,MUL
/*void print_matrix_debug(int A[2*f+1][2*f+1])
{
for(int i=0;i<2*f+1;i++)
{
for(int j=0;j<2*f+1;j++)
{
printf("%d ",A[i][j]);
}
printf("\n");
}
printf("\n\n\n");
}*/
//NLM算法.将source传入mir_source后,就可以对其进行非局部均匀滤波了。步骤按照matlab程序来
void NLM()
{
int i,j,i1,j1;
for(i=0;i<height;i++)
for(j=0;j<width;j++)
{
i1=i+f;
j1=j+f;
matrix_write(W1,i1-f,j1-f);//是对的,因为txt里行太长以至于到下一行了
//对每个点的求权值开始,都average,sweight,wmax进行初始化
w=0;
wmax=0;
average=0;
sweight=0;
d=0;
int rmin=max(i1-t,f+1);
int rmax=min(i1+t,height+f);
int smin=max(j1-t,f+1);
int smax=min(j1+t,width+f);
//freopen("runhistory.txt","a+",stdout);
//printf("第%d %d个数据rmin,rmax,smin,smax分别是 %d %d %d %d\n\n",i,j,rmin,rmax,smin,smax);
/*int rmin=max_value(i1-t,f+1);
int rmax=min_value(i1+t,height+f);
int smin=max_value(j1-t,f+1);
int smax=min_value(j1+t,width+f);*/
//在搜索块里进行求权值
for(int r=rmin;r<(rmax+1);r++)//这里加了个等号,与matlab的矩阵元素表示形式不同
{
for(int s=smin;s<(smax+1);s++)
{
if(r==i1&&s==j1)
continue;
matrix_write(W2,r-f,s-f);
//W1和W2相乘
matrix_sub(W1,W2,SUB1);
matrix_sub(W1,W2,SUB2);
matrix_mul_point(SUB1,SUB2,MUL);//乘法这错了!!因为是点乘,是各个元素对应相乘
//debug用的输出三个短矩阵.找出来的原因是矩阵出错了,也就是MUL(也不一定)就是这矩阵MUL出错了,而且应该是最后一行出错
/*if(i>507&&j>130&&j<153)
{
freopen("matrix_debug.txt","a+",stdout);
print_matrix_debug(W1);
print_matrix_debug(W2);
print_matrix_debug(MUL);
}*/
d=matrix_sum(MUL);//d的值比matlab的多一个数量级
w=exp(-d/(h*h));
//freopen("runhistory1.txt","a+",stdout);
//printf("d的值是%f\n",d);
//printf("w的值是%f\n",w);
if(w>wmax)
wmax=w;
sweight+=w;
average+=w*mir_source[r][s];
}
}
//freopen("runhistory.txt","a+",stdout);//!!!!!!!!!从506,128开始,average和sweight就开始出错了
//printf("average和sweight分别是%f %f\n",average,sweight);
average+=wmax*mir_source[i1][j1];
sweight+=wmax;
if(sweight>0)
result[i][j]=(int)(average/sweight);
else
result[i][j]=source[i][j];
/*if(i>506&&j>132&&j<153)
{
freopen("runhistory.txt","a+",stdout);
printf("average=%f\n",average);
printf("sweight=%f\n",sweight);
printf("第%d %d个数=%d\n\n",i,j,result[i][j]);
}*/
//freopen("history.txt","a+",stdout);
printf("%d %d--%d:\n",i,j,result[i][j]);
}
}
//打印滤波后的结果
void print_result()
{
FILE* fp;
fp=fopen("滤波结果.txt","w");
if(!fp)
{
printf("打开输入镜像结果错误!\n");
exit(-1);
}
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
fprintf(fp,"%d ",result[i][j]);
}
fputc('\n',fp);
}
fclose(fp);
}
//打印镜像结果
void print_mir()
{
FILE* fp;
fp=fopen("镜像结果.txt","w");
if(!fp)
{
printf("打开输入镜像结果错误!\n");
exit(-1);
}
for(int i=0;i<height+2*f;i++)
{
for(int j=0;j<width+2*f;j++)
{
fprintf(fp,"%d ",mir_source[i][j]);
}
fputc('\n',fp);
}
fclose(fp);
}
//主函数
void main()
{
clock_t start,end;
start=clock();
read();
mirror();
NLM();
PSNR_VALUE();
end=clock();
print_result();
print_mir();
printf("%d 毫秒\n",end-start);
printf("PSNR是%f db\n",PSNR);
}









