#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
//#define DEBUG_DATA_OUT 1
#define MAX_WIDTH 200
#define MAX_HEIGHT 200
#define FILT_RAD 2
int Q,H,W;
int weight[5][5] = { { 0,1,2,1,0 },
{ 1,5,8,5,1 },
{ 2,8,10,8,2 },
{ 1,5,8,5,1 },
{ 0,1,2,1,0 }
};
#define IMGVAL_MAX 256
#define NOISEVAL_MAX 1000
int img[200][200];
int noise[200][200];
int noise1[200][200];
int noise_hit[200][200];
int noiselev_cnt[NOISEVAL_MAX];
#define SIM_DELTA 20
#define DIF_DELTA 70
#define VALID_TRESHOLD 600
void print_arr(int *arr,int Width, int Height)
{ int i,j;
-
for (j=0; j<Height; j++)
{ for (i=0; i<Width; i++)
printf("%3d ",arr
[MAX_WIDTH*j+i
]);
}
}
__inline int abs(int val)
{ return val < 0 ? -val : val;
}
void highpass(int expected,int *filtlev)
{ int total = 0;
int lev = 0;
-
#ifdef DEBUG_DATA_OUT
printf("HIGHPASS expected = %d\n",expected
);
#endif
for (lev=999; lev>=0 && total*100 < expected ; lev--)
{ total += noiselev_cnt[lev];
/*#ifdef DEBUG_DATA_OUT
printf("lev = %d cnt = %d | total = %d\n",lev,noiselev_cnt[lev],total);
#endif*/
}
if ( total*100 > expected )
lev++;
if (lev<0)
lev = 0;
*filtlev = lev;
#ifdef DEBUG_DATA_OUT
printf("HIGHPASS filtlev = %d\n",lev
);
#endif
}
void colregion_hit(int regstart,int regwidth,int Width,int Height)
{ int i,j;
int expected,filtlev;
-
#ifdef DEBUG_DATA_OUT
printf("COLREGION_HIT regstart = %d regwidth = %d\n",regstart,regwidth
);
#endif
-
-
memset(noiselev_cnt,0,sizeof(noiselev_cnt));
for (j=0; j<Height; j++)
{ for (i=0; i<Width; i++)
{ if ( img[j][i]>= regstart && img[j][i]<= regstart+regwidth )
{ noiselev_cnt[noise[j][i]]++;
}
}
}
-
expected = H*W*Q*regwidth/IMGVAL_MAX;
highpass(expected,&filtlev);
-
for (j=0; j<Height; j++)
{ for (i=0; i<Width; i++)
{ if ( img[j][i]>= regstart && img[j][i]<= regstart+regwidth )
{ noise_hit[j][i]++;
if ( noise[j][i] > filtlev )
noise1[j][i] += noise[j][i];
else if ( noise[j][i] > 2*filtlev/3 )
noise1[j][i] += noise[j][i] - 2*filtlev/3;
}
}
}
}
void colregion(int Width,int Height)
{ int size,k;
-
memset(noise1,0,sizeof(noise1));
memset(noise_hit,0,sizeof(noise_hit));
size = 15;
for (k=0; k+size < IMGVAL_MAX; k+= size+1)
{ colregion_hit(k,size,Width,Height);
}
}
int gaussfilter(int x,int y,int *estval,int *valid,int *nsim,int *ndif)
{ int i,j;
int estimate = 0, importance = 0, weightsum = 0;
int est_valid = 0, center_valid;
int thisval,neighval;
int imp, wght;
int centerimp;
-
*ndif = 0; *nsim = 0;
thisval = img[y][x];
for ( j=-FILT_RAD; j<=FILT_RAD; j++ )
{ if ( y+j >= 0 && y+j < MAX_HEIGHT )
for ( i=-FILT_RAD; i<=FILT_RAD; i++ )
{ if ( x+i >= 0 && x+i < MAX_WIDTH )
{ neighval = img[y+j][x+i];
wght = weight[j+FILT_RAD][i+FILT_RAD];
weightsum += wght;
imp = wght* ( NOISEVAL_MAX - noise[y+j][x+i] );
importance += imp;
estimate += imp*neighval;
if ( ! (i==0 && j==0) )
if ( NOISEVAL_MAX - noise[y+j][x+i] > VALID_TRESHOLD )
{ if ( abs(thisval-neighval) < SIM_DELTA )
(*nsim) +=100*wght;
if ( abs(thisval-neighval) > DIF_DELTA )
(*ndif) +=100*wght;
}
}
}
}
-
//вычисляем вклад центральной точки в указанные суммы
wght = weight[0+FILT_RAD][0+FILT_RAD];
centerimp = wght* ( NOISEVAL_MAX - noise[y][x] );
-
weightsum -= wght;
importance -= centerimp;
estimate -= centerimp*img[y][x];
estimate /= importance;
*nsim /= weightsum;
*ndif /= weightsum;
-
est_valid = importance/weightsum;
center_valid = NOISEVAL_MAX - noise[y][x];
*estval = estimate;
*valid = est_valid;
return 1;
}
int main()
{ int Ntest,test,pass;
int x,y;
int filtered,diff,filt_valid,cent_valid,nsim,ndif;
int filtlev,expected,total;
-
for (test=1; test<=Ntest; test++)
{ scanf("%d %d %d",&Q,&H,&W
);
expected = Q*H*W;
-
-
for (y=0; y<H; y++)
for (x=0; x<W; x++)
{ scanf("%d",&
(img
[y
][x
]));
}
-
memset(noise,0,sizeof(noise));
memset(noise1,0,sizeof(noise1));
-
for (pass=0; pass<5; pass++)
{
#ifdef DEBUG_DATA_OUT
printf("PASS NUMBER %d\n",pass
);
#endif
memset(noiselev_cnt,0,sizeof(noiselev_cnt));
for (y=0; y<H; y++)
{ for (x=0; x<W; x++)
{ gaussfilter(x,y,&filtered,&filt_valid,&nsim,&ndif);
cent_valid = NOISEVAL_MAX-noise[y][x];
-
diff = abs(filtered-img[y][x]);
#ifdef DEBUG_DATA_OUT
printf("%d %d v(%d %d) n(%d %d) ",filtered,noise
[y
][x
],filt_valid,cent_valid,nsim,ndif
);
#endif
if (nsim < 30)
noise1[y][x] = (30-nsim)*25 + diff;
if (ndif > 85)
noise1[y][x] += (100-ndif)*30 + diff;
if (noise1[y][x]<0)
noise1[y][x] = 0;
if (noise1[y][x]>=NOISEVAL_MAX)
noise1[y][x] = NOISEVAL_MAX-1;
-
noiselev_cnt[noise1[y][x]]++;
}
#ifdef DEBUG_DATA_OUT
#endif
}
-
-
#ifdef DEBUG_DATA_OUT
printf("NOISE1 before COLREGION\n");
print_arr(&(noise1[0][0]),W,H);
#endif
-
memcpy(noise,noise1,sizeof(noise1));
memset(noise1,0,sizeof(noise1));
-
-
colregion(W,H);
#ifdef DEBUG_DATA_OUT
printf("NOISE1 after COLREGION\n");
print_arr(&(noise1[0][0]),W,H);
#endif
-
-
/*
#ifdef DEBUG_DATA_OUT
printf("NOISE1 before HIGH_PASS_FILTER\n");
print_arr(&(noise1[0][0]),W,H);
-
printf("expected = %d\n",expected);
#endif
-
total = 0;
for (filtlev=999; filtlev>=0 && total*100 < expected ; filtlev--)
{ total += noiselev_cnt[filtlev];
#ifdef DEBUG_DATA_OUT
printf("lev = %d cnt = %d | total = %d\n",filtlev,noiselev_cnt[filtlev],total);
#endif
}
if ( total*100 > expected )
filtlev++;
if (filtlev<0)
filtlev = 0;
-
for (y=0; y<H; y++)
{ for (x=0; x<W; x++)
{ if (noise1[y][x]<=filtlev)
noise1[y][x]=0;
}
}
#ifdef DEBUG_DATA_OUT
printf("NOISE1 after HIGH_PASS_FILTER\n");
print_arr(&(noise1[0][0]),W,H);
#endif
*/
-
memcpy(noise,noise1,sizeof(noise1));
memset(noise1,0,sizeof(noise1));
}
-
for (y=0; y<H; y++)
{ for (x=0; x<W; x++)
{ if ( noise[y][x] > 50 )
{ gaussfilter(x,y,&filtered,&filt_valid,&nsim,&ndif);
}
else
}
}
-
}
return 0;
}