/***************************************************************************
* Func: color_median *
* *
* Desc: Median filters a color image by finding the median of RGB using *
* absolute differences *
* *
* Params: source - pointer to color image in memory *
* cols - number of columns in image *
* rows - number of rows in image *
* kwidth - width of window *
* filename - name of output file *
***************************************************************************/
void color_median(pixel_ptr source, int cols, int rows,
int kwidth, char *filename)
{
int x, y, i; /* image loop variables */
int kernx, kerny; /* kernel loop variables */
int index; /* image index */
int xextra, yextra; /* size of boundary */
int conv_line; /* size of output line */
unsigned long destadd; /* destination image address */
unsigned long sourceadd, sourcebase; /* source addressing */
pixel dest[1024]; /* destination image line */
FILE *fp; /* output file pointer */
unsigned char left[25];/* left buffer */
unsigned char right[25];/* right buffer */
int xpad, ypad; /* number of rows and columns that must be copied*/
int last_line; /* last line that can be processed, others copied*/
int color_line; /* size of color line */
pixel_ptr window; /* window of pixel group being processed */
int wsize; /* number of elements in the window */
xextra = (kwidth/2)*2;
xpad = xextra/2;
yextra = xextra;
ypad = xpad;
conv_line = cols - xextra;
color_line = conv_line * 3;
wsize = kwidth * kwidth;
window = malloc(wsize * sizeof(pixel));
if((fp=fopen(filename, "wb")) == NULL)
{
printf("Unable to open %s for output\n",filename);
exit(1);
}
fprintf(fp, "P6\n%d %d\n255\n", cols, rows); /* print out header */
last_line = rows - yextra;
for(y=0; y<last_line; y++)
{
sourcebase=(unsigned long) cols * y;
destadd=0;
for(x=xpad; x<(cols - xpad); x++)
{
index=0;
for(kerny=0; kerny<kwidth; kerny++)
for(kernx=0; kernx<kwidth; kernx++)
{
sourceadd=sourcebase+kernx+kerny*cols;
window[index].r = source[sourceadd].r;
window[index].g = source[sourceadd].g;
window[index++].b = source[sourceadd].b;
}
index = find_color_median(window, wsize);
dest[destadd].r = window[index].r;
dest[destadd].g = window[index].g;
dest[destadd++].b = window[index].b;
sourcebase++;
} /* for x */
for(i=0; i<xpad*3; i+=3)
{
left[i]=dest[0].r;
left[i+1]=dest[0].g;
left[i+2]=dest[0].b;
}
for(i=0; i<xpad*3; i++)
{
right[i]=dest[conv_line-1].r;
right[i+1]=dest[conv_line-1].g;
right[i+2]=dest[conv_line-1].b;
}
if(y==0)
for(i=0; i<ypad; i++)
{
fwrite(left, 1, xpad*3, fp);
fwrite(dest, 1, color_line, fp);
fwrite(right, 1, xpad*3, fp);
}
fwrite(left, 1, xpad*3, fp);
fwrite(dest, 1, color_line, fp);
fwrite(right, 1, xpad*3, fp);
if(y==(last_line-1))
for(i=0; i<ypad; i++)
{
fwrite(left, 1, xpad*3, fp);
fwrite(dest, 1, color_line, fp);
fwrite(right, 1, xpad*3, fp);
}
} /* for y */
}
/***************************************************************************
* Func: find_color_median *
* *
* Desc: computes median pixel of group by determining the lowest sum of *
* differences between each pixel and all others within window *
* *
* Params: window - block of pixels being evaluated *
* wsize - number of elements in window *
***************************************************************************/
int find_color_median(pixel_ptr window, int wsize)
{
int i, j; /* loop variables */
unsigned int vec_sum; /* vector sum */
unsigned int min_sum; /* minimum vector sum so far */
int index; /* index of current minimum vector sum */
min_sum = 10000;
index = 0;
for(i=0; i<wsize; i++)
{
vec_sum = 0;
for(j=0; j<wsize; j++)
{
vec_sum += abs(window[i].r - window[j].r);
vec_sum += abs(window[i].g - window[j].g);
vec_sum += abs(window[i].b - window[j].b);
}
if(vec_sum <= min_sum)
{
min_sum = vec_sum;
index = i;
}
}
return index;
}
Median filters a color image by finding the median of RGB
最新推荐文章于 2015-10-24 14:52:59 发布