H
Harris Kosmidis
I have a problem which I think is due to overflow/underflow.
I want to segment an Image using SOM network. Code follows:
==============================================================================================
struct MyImage
{
int width, height;
long int num_pixels;
short int *tag;
unsigned char *R, *B, *G;
};
struct _SOMgrid {
int width,height;
int N;
int *R,*B,*G;
};
The functions with which I update the SOM's weights is:
void UpdateWeightsSmall(struct _SOMgrid *SOMgrid,struct MyImage
*Image,int min_index,int epoch,long int current) {
int j;
float n,s,h,dist;
int cR=0,cB=0,cG=0;
int current_x,current_y,loop_x,loop_y,mindimension,radius;
current_y=min_index/SOMgrid->width;
current_x=min_index-current_y*SOMgrid->width;
//Find learning rate
n=0.9*(1-(epoch*1.0/(SOM_EPOCHS*2)));
//Set radius as portion of image size
mindimension=(SOMgrid->width<SOMgrid->height)?SOMgrid->width:SOMgrid->height;
radius=(int)rint(mindimension*0.2);
//Find s
s=radius*(1-epoch*1.0/SOM_EPOCHS)+1;
for(j=0;j<SOMgrid->N;j++) {
loop_y=j/SOMgrid->width;
loop_x=j-loop_y*SOMgrid->width;
dist=sqrtf((loop_x-current_x)*(loop_x-current_x) +
(loop_y-current_y)*(loop_y-current_y));
h=expf(-powf(dist,2)/(2*powf(s,2)));
cR=(int)lrintf(n*h*((float)SOMgrid->R[min_index]-SOMgrid->R[j]));
cG=(int)lrintf(n*h*((float)SOMgrid->G[min_index]-SOMgrid->G[j]));
cB=(int)lrintf(n*h*((float)SOMgrid->B[min_index]-SOMgrid->B[j]));
SOMgrid->R[j]+=cR;
SOMgrid->B[j]+=cB;
SOMgrid->G[j]+=cG;
if(SOMgrid->R[j]>255 || SOMgrid->R[j]<0 || SOMgrid->G[j]>255 ||
SOMgrid->G[j]<0 || SOMgrid->B[j]>255 || SOMgrid->B[j]<0 ) {
printf("changes:: (%d),input=(%d,%d), loop=(%d,%d), radius=%d, n=%f,
s=%f, dist=%f, h=%f, input=(%u,%u,%u), SOM=(%u,%u,%u), change=(%u,%u,%u)
%u,%f,%f\n",
epoch,current_x,current_y,loop_x,loop_y,
radius,n,s,dist,h,Image->R[current],Image->G[current],Image->B[current],SOMgrid->R[j],SOMgrid->G[j],SOMgrid->B[j],
cR,cG,cB,(unsigned int)tmpR,tmpG,tmpB);
exit(1);
}
}
}
=======================================================================================
The inputs to the following function are checked and are ok. Outside the
function in my main loop where I feed the inputs I have:
printf("%ld %d,%d,%d\n",i,SOMgrid->R,SOMgrid->G,SOMgrid->B);
where i is the curent input --a pixel of my image.
At some time this prints something like (different numbers on every run):
305 -1633772131,2071692934,2088531831
306 -1633771874,2038003318,-2021162623
307 -1616928865,-2105377154,-1835889267
308 -1616928608,-1903261560,-1633773673
309 -1684300387,-1785359726,-1381128538
As you can see In my update function I do an if() check whether weights
exceed 0 or 255 and it passes without any errors. Why does printf gives
me this? The programm ends "correctly" but the output is messy.
Can anybody help me? I'm stuck in C with those stupid number
conversions. Thanks a lot.
I want to segment an Image using SOM network. Code follows:
==============================================================================================
struct MyImage
{
int width, height;
long int num_pixels;
short int *tag;
unsigned char *R, *B, *G;
};
struct _SOMgrid {
int width,height;
int N;
int *R,*B,*G;
};
The functions with which I update the SOM's weights is:
void UpdateWeightsSmall(struct _SOMgrid *SOMgrid,struct MyImage
*Image,int min_index,int epoch,long int current) {
int j;
float n,s,h,dist;
int cR=0,cB=0,cG=0;
int current_x,current_y,loop_x,loop_y,mindimension,radius;
current_y=min_index/SOMgrid->width;
current_x=min_index-current_y*SOMgrid->width;
//Find learning rate
n=0.9*(1-(epoch*1.0/(SOM_EPOCHS*2)));
//Set radius as portion of image size
mindimension=(SOMgrid->width<SOMgrid->height)?SOMgrid->width:SOMgrid->height;
radius=(int)rint(mindimension*0.2);
//Find s
s=radius*(1-epoch*1.0/SOM_EPOCHS)+1;
for(j=0;j<SOMgrid->N;j++) {
loop_y=j/SOMgrid->width;
loop_x=j-loop_y*SOMgrid->width;
dist=sqrtf((loop_x-current_x)*(loop_x-current_x) +
(loop_y-current_y)*(loop_y-current_y));
h=expf(-powf(dist,2)/(2*powf(s,2)));
cR=(int)lrintf(n*h*((float)SOMgrid->R[min_index]-SOMgrid->R[j]));
cG=(int)lrintf(n*h*((float)SOMgrid->G[min_index]-SOMgrid->G[j]));
cB=(int)lrintf(n*h*((float)SOMgrid->B[min_index]-SOMgrid->B[j]));
SOMgrid->R[j]+=cR;
SOMgrid->B[j]+=cB;
SOMgrid->G[j]+=cG;
if(SOMgrid->R[j]>255 || SOMgrid->R[j]<0 || SOMgrid->G[j]>255 ||
SOMgrid->G[j]<0 || SOMgrid->B[j]>255 || SOMgrid->B[j]<0 ) {
printf("changes:: (%d),input=(%d,%d), loop=(%d,%d), radius=%d, n=%f,
s=%f, dist=%f, h=%f, input=(%u,%u,%u), SOM=(%u,%u,%u), change=(%u,%u,%u)
%u,%f,%f\n",
epoch,current_x,current_y,loop_x,loop_y,
radius,n,s,dist,h,Image->R[current],Image->G[current],Image->B[current],SOMgrid->R[j],SOMgrid->G[j],SOMgrid->B[j],
cR,cG,cB,(unsigned int)tmpR,tmpG,tmpB);
exit(1);
}
}
}
=======================================================================================
The inputs to the following function are checked and are ok. Outside the
function in my main loop where I feed the inputs I have:
printf("%ld %d,%d,%d\n",i,SOMgrid->R,SOMgrid->G,SOMgrid->B);
where i is the curent input --a pixel of my image.
At some time this prints something like (different numbers on every run):
305 -1633772131,2071692934,2088531831
306 -1633771874,2038003318,-2021162623
307 -1616928865,-2105377154,-1835889267
308 -1616928608,-1903261560,-1633773673
309 -1684300387,-1785359726,-1381128538
As you can see In my update function I do an if() check whether weights
exceed 0 or 255 and it passes without any errors. Why does printf gives
me this? The programm ends "correctly" but the output is messy.
Can anybody help me? I'm stuck in C with those stupid number
conversions. Thanks a lot.