LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C code for median filter on color images (https://www.linuxquestions.org/questions/programming-9/c-code-for-median-filter-on-color-images-434793/)

tomazN 04-13-2006 08:57 AM

C code for median filter on color images
 
Somebody has maybe somewhere color median filter code written in C to filter out a color picture with it. I have read image to image_pointer but i dont know the algorithm to do median filtering on it. I made it for gray pictures which is easy, but i am stuck for color pictures. If somebody maybe has this filter already written or seen it somewhere i would appreciate it. BTW. using some opencv or some other image processing plugin or whatever doesnt come into account :) I need to have the C code for it.

Thx.

paulsm4 04-13-2006 09:52 AM

http://www.imagemagick.org

tomazN 04-13-2006 09:56 AM

Yah, i know this url, it doesnt help me. It needs libs from that software, i have to use pure C (have to reinvent the whole thing, dont ask why its a damn school project ...).

For exmpl. this is median for gray pictures:

Code:

#include <stdio.h>
#include "../ip.h"


/***************************************************************************
 * Func: median_filt                                                      *
 *                                                                        *
 * Desc: median filters an image using a block mask                        *
 *                                                                        *
 * Params: source - pointer to image in memory                            *
 *        cols - number of columns in image                              *
 *        rows - number of rows in image                                  *
 *        filename - name of output file                                  *
 *        side - width of block                                          *
  ***************************************************************************/
main()
{
}

void median_filt(image_ptr source, int cols, int rows, char *filename,
                int side)
    {
    int x, y, i;            /* image loop variables */
    int index;              /* image index */
    int winx, winy;          /* index into the samples window */
    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 */
    char dest[1024];        /* destination image line */
    FILE *fp;                /* output file pointer */
    int *window;            /* window for block samples */
    unsigned char left[25];  /* storage for left edge pixel duplication */
    unsigned char right[25]; /* storage for right edge pixel duplication */
    int xpad, ypad;          /* size of padding */
    int last_line;          /* last line to process */
    int new_pixel;          /* newly processed pixel */
    int wsize;              /* number of elements in block */

    wsize = side * side;
    yextra = (side/2)*2;
    ypad = yextra/2;
    xextra = yextra;
    xpad = ypad;
    conv_line = cols - xextra;

    window = malloc(wsize * sizeof(int));
    if((fp=fopen(filename, "wb")) == NULL)
        {
        printf("Unable to open %s for output\n",filename);
        exit(1);
        }
    fprintf(fp, "P5\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(winy=0; winy<side; winy++)
              for(winx=0; winx<side; winx++)
                  {
                  sourceadd=sourcebase+winx+winy*cols;
                  window[index++] = (int) source[sourceadd];
                  }
          new_pixel = median(window, wsize);
          dest[destadd++]=(unsigned char) new_pixel;
          sourcebase++;
          } /* for x */
        for(i=0; i<xpad; i++)
          left[i]=dest[0];
        for(i=0; i<xpad; i++)
          right[i]=dest[conv_line-1];
        if(y==0)
            for(i=0; i<ypad; i++)
            {
            fwrite(left, 1, xpad, fp);
            fwrite(dest, 1, conv_line, fp);
            fwrite(right, 1, xpad, fp);
            }
        fwrite(left, 1, xpad, fp);
        fwrite(dest, 1, conv_line, fp);
        fwrite(right, 1, xpad, fp);
        if(y==(last_line-1))
            for(i=0; i<ypad; i++)
                {
                fwrite(left, 1, xpad, fp);
                fwrite(dest, 1, conv_line, fp);
                fwrite(right, 1, xpad, fp);
                }
    } /* for y */
    free(window);
    }

/****************************************************************************
 * Func: median                                                            *
 *                                                                          *
 * Desc: finds median value of an image block                              *
 *                                                                          *
 * Param: window - 3x3 window of source image                              *
 *                                                                          *
 * Returns: the median value                                                *
 ****************************************************************************/

int median(int *window, int wsize)
    {
    quicksort(window, 0, wsize);
    return window[wsize/2];
    }

/***************************************************************************
 * Func: quicksort                                                        *
 *                                                                        *
 * Desc: sorts an array of integers using the quicksort algorithm        *
 *                                                                        *
 * Params: array - the array of integers                                  *
 *        left - leftmost entry in array                                *
 *        right - rightmost entry in array                              *
 ***************************************************************************/

void quicksort(int *array, int left, int right)
    {
    int i, last;

    if(left >= right)
        return;
    swap(array, left, (left + right)/2);
    last = left;
    for( i = left + 1; i<= right; i++)
        if(array[i] < array[left])
            swap(array, ++last, i);
    swap(array, left, last);
    quicksort(array, left, last-1);
    quicksort(array, last+1, right);
    }

/***************************************************************************
 * Func: swap                                                              *
 *                                                                        *
 * Desc: swaps two elements in an array                                    *
 *                                                                        *
 * Params: array - array of element (two of which will be swapped)        *
 *        i - first element in array to swap                              *
 *        j - second element in array to swap                            *
 ***************************************************************************/
void swap(int *array, int i, int j)
    {
    int temp;

    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }


slantoflight 04-13-2006 12:32 PM

Its looks like you need to add checking for 16bit and 24 bit color images. You are aware of little endianess, right? Your swap array is only effective on 4bit images(16 color grayscale) because it only works with two bytes.


Code:

void swap(int *array, int i, int j)
    {
    int temp;

    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }

It would be better to reverse the order all together,but I realise that in order for your program to work properly it has to operate in bit chunks. So maybe if you grab 24 bits(which is the maximux bit depth of any color image) at a time and adjust your algorithm. add 24 bit 16bit 4 bit command line options. That should do it.

tomazN 04-13-2006 12:39 PM

The thing i have for grayscal images is ok, because i use pgm files. I need algorithm for median for color images (RGB) format ppm.

tomazN 04-13-2006 12:47 PM

I have already stored image in memory as image_ptr. I only need the algorithm what to do with pixels. I know how to write the image back aswell.

slantoflight 04-13-2006 12:53 PM

Quote:

Originally Posted by tomazN
I have already stored image in memory as image_ptr. I only need the algorithm what to do with pixels. I know how to write the image back aswell.

I think your main function for calculating median is ok. I mean calculating mean is the same everywhere right? you just have to fix your swap function.

tomazN 04-13-2006 12:56 PM

gray pixture is like this: valuse from 1-255 '23 34 45 234 12' each representing one pixel. RGB picture on the other hand is like this: 23 34 56 78 34 120 first three values reperesent one pixel with first number being R second G third B. Now you have to do meadian somehow based on that, so no i cant use gray median for this not even close :) I am stuck :(

tomazN 04-13-2006 12:57 PM

pgm - see http://netpbm.sourceforge.net/doc//pgm.html
ppm - see http://netpbm.sourceforge.net/doc//ppm.html

for some reference :)

slantoflight 04-13-2006 01:55 PM

they look nearly the same, except the last two values are swapped. But are they really both 32bit in length? That seems wasteful for a grayscale.

But ahh I see

Quote:

The PGM format is a lowest common denominator grayscale file format. It is designed to be extremely easy to learn and write programs for. (It's so simple that most people will simply reverse engineer it because it's easier than reading this specification).
Then the only it appears you need to worry about is bit 7 out of each 32 bit chunk.

tomazN 04-13-2006 02:03 PM

I cant make same procedure to get median value on color picture. Because you cant make median on three pixels. you must make median on a window of 3x3 for example on R and then on G and on B then u write back all those components to get next pixel with RGB, or else you would get just diffrent colors if not all black.

I just need the algorithm for this procedure, i can manage other myself, just dont know the logic part of the algorithm. :(

anne_regina 11-26-2006 12:16 PM

Request for ip.h file
 
Quote:

Originally Posted by tomazN
Yah, i know this url, it doesnt help me. It needs libs from that software, i have to use pure C (have to reinvent the whole thing, dont ask why its a damn school project ...).

For exmpl. this is median for gray pictures:

Code:

#include <stdio.h>
#include "../ip.h"


/***************************************************************************
 * Func: median_filt                                                      *
 *                                                                        *
 * Desc: median filters an image using a block mask                        *
 *                                                                        *
 * Params: source - pointer to image in memory                            *
 *        cols - number of columns in image                              *
 *        rows - number of rows in image                                  *
 *        filename - name of output file                                  *
 *        side - width of block                                          *
  ***************************************************************************/
main()
{
}

void median_filt(image_ptr source, int cols, int rows, char *filename,
                int side)
    {
    int x, y, i;            /* image loop variables */
    int index;              /* image index */
    int winx, winy;          /* index into the samples window */
    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 */
    char dest[1024];        /* destination image line */
    FILE *fp;                /* output file pointer */
    int *window;            /* window for block samples */
    unsigned char left[25];  /* storage for left edge pixel duplication */
    unsigned char right[25]; /* storage for right edge pixel duplication */
    int xpad, ypad;          /* size of padding */
    int last_line;          /* last line to process */
    int new_pixel;          /* newly processed pixel */
    int wsize;              /* number of elements in block */

    wsize = side * side;
    yextra = (side/2)*2;
    ypad = yextra/2;
    xextra = yextra;
    xpad = ypad;
    conv_line = cols - xextra;

    window = malloc(wsize * sizeof(int));
    if((fp=fopen(filename, "wb")) == NULL)
        {
        printf("Unable to open %s for output\n",filename);
        exit(1);
        }
    fprintf(fp, "P5\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(winy=0; winy<side; winy++)
              for(winx=0; winx<side; winx++)
                  {
                  sourceadd=sourcebase+winx+winy*cols;
                  window[index++] = (int) source[sourceadd];
                  }
          new_pixel = median(window, wsize);
          dest[destadd++]=(unsigned char) new_pixel;
          sourcebase++;
          } /* for x */
        for(i=0; i<xpad; i++)
          left[i]=dest[0];
        for(i=0; i<xpad; i++)
          right[i]=dest[conv_line-1];
        if(y==0)
            for(i=0; i<ypad; i++)
            {
            fwrite(left, 1, xpad, fp);
            fwrite(dest, 1, conv_line, fp);
            fwrite(right, 1, xpad, fp);
            }
        fwrite(left, 1, xpad, fp);
        fwrite(dest, 1, conv_line, fp);
        fwrite(right, 1, xpad, fp);
        if(y==(last_line-1))
            for(i=0; i<ypad; i++)
                {
                fwrite(left, 1, xpad, fp);
                fwrite(dest, 1, conv_line, fp);
                fwrite(right, 1, xpad, fp);
                }
    } /* for y */
    free(window);
    }

/****************************************************************************
 * Func: median                                                            *
 *                                                                          *
 * Desc: finds median value of an image block                              *
 *                                                                          *
 * Param: window - 3x3 window of source image                              *
 *                                                                          *
 * Returns: the median value                                                *
 ****************************************************************************/

int median(int *window, int wsize)
    {
    quicksort(window, 0, wsize);
    return window[wsize/2];
    }

/***************************************************************************
 * Func: quicksort                                                        *
 *                                                                        *
 * Desc: sorts an array of integers using the quicksort algorithm        *
 *                                                                        *
 * Params: array - the array of integers                                  *
 *        left - leftmost entry in array                                *
 *        right - rightmost entry in array                              *
 ***************************************************************************/

void quicksort(int *array, int left, int right)
    {
    int i, last;

    if(left >= right)
        return;
    swap(array, left, (left + right)/2);
    last = left;
    for( i = left + 1; i<= right; i++)
        if(array[i] < array[left])
            swap(array, ++last, i);
    swap(array, left, last);
    quicksort(array, left, last-1);
    quicksort(array, last+1, right);
    }

/***************************************************************************
 * Func: swap                                                              *
 *                                                                        *
 * Desc: swaps two elements in an array                                    *
 *                                                                        *
 * Params: array - array of element (two of which will be swapped)        *
 *        i - first element in array to swap                              *
 *        j - second element in array to swap                            *
 ***************************************************************************/
void swap(int *array, int i, int j)
    {
    int temp;

    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }


Hi, I would like to request for the file ip.h from the book "A simplified approach to image processing" please? I have the other snippets but without the ip.h, i can't run the code...I'm doing project on image processing using median filter.. really appreciate it if you could send to my email: anne_regina@yahoo.com ..Thanks!

jayshri 02-20-2012 01:12 AM

image processing
 
hello people m also doing a project in image processing... i have already devloped the code that reads the image pixel by pixel. now i want to do median filtering.... i have to make a structured program.. i.e i hav to incude the median filter code in the code which is reading pixel value... can nebody help me with the coding of median filtering..
i need it in c.
thank u.
regards

firstfire 02-20-2012 05:11 AM

Quote:

Originally Posted by jayshri (Post 4607078)
hello people m also doing a project in image processing... i have already devloped the code that reads the image pixel by pixel. now i want to do median filtering.... i have to make a structured program.. i.e i hav to incude the median filter code in the code which is reading pixel value... can nebody help me with the coding of median filtering..
i need it in c.
thank u.
regards

Hi.
Welcome to LQ!
Take a look at this Wikipedia article. You will find the pseudo code for median filtering there as well as a link to rosettacode.org with implementations in different languages (including C).

Hope this helps.

jayshri 02-20-2012 05:31 AM

image processing
 
thank u...:)


All times are GMT -5. The time now is 10:36 AM.