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...:)

firstfire 02-20-2012 06:07 AM

Just finished reading an article (from aforementioned wikipedia page). It turned out that time complexity of median filtering could be reduced to O(1) (that is made independent of kernel radius). The idea seems to be quite straightforward. You may take a look at it also.

jayshri 02-20-2012 09:38 AM

image processing
 
thanx alot... m reading it nw..:)

jayshri 02-20-2012 09:43 AM

image processing
 
i have got very little knowledge about C. also image processing is a new field 4 me... so itz gettng abit difficult 4 me . m tryng to solve it... thanx 4 d fast replies... i wil get back to u if i have any doubts further..
Regards.

jayshri 02-21-2012 02:22 AM

im
 
median_filter(the_image, out_image,
rows, cols, size)
int
size;
F.7. CODE LISTINGS FOR CHAPTER 7
short
long
**the_image,
**out_image;
rows, cols;
{
int
short
a, b, count, i, j, k,
length, sd2, sd2p1, ss, width;
*elements;
sd2
= size/2;
sd2p1 = sd2 + 1;
/**********************************************
*
*
Allocate the elements array large enough
*
to hold size*size shorts.
*
**********************************************/
ss
= size*size;
elements = (short *) malloc(ss * sizeof(short));
/***************************
*
*
Loop over image array
*
****************************/
printf("\n");
for(i=sd2; i<rows-sd2; i++){
if( (i%10) == 0) printf("%d ", i);
for(j=sd2; j<cols-sd2; j++){
count = 0;
for(a=-sd2; a<sd2p1; a++){
for(b=-sd2; b<sd2p1; b++){
elements[count] = the_image[i+a][j+b];
count++;
}
}
out_image[i][j] = median_of(elements, &ss);
} /* ends loop over j */
} /* ends loop over i */
free(elements);
fix_edges(out_image, sd2, rows-1, cols-1);

}
m using dis code for median filtering.. bt its showing 2 errors:
1.undefined refrence to median_of;
2.undefined refence to fix_edges.
as i am a newbie in C.. so m nt able to rectify it.
any help wil b appreciated.
Regards.

firstfire 02-21-2012 05:00 AM

Hi.

The following code I copied from this pdf file. Header files and empty main() function are also added. Compiles without errors.

Code:

#include <stdio.h>
#include <stdlib.h>

// Codes taken from
// http://www.google.com/url?sa=t&rct=j&q=f.7.%20code%20listings%20for%20chapter%207&source=web&cd=3&ved=0CDYQFjAC&url=http%3A%2F%2Fhomepages.inf.ed.ac.uk%2Frbf%2FBOOKS%2FPHILLIPS%2Fcips2ed.pdf&ei=LHFDT_DcKaiQ4gS5zv2sCA&usg=AFQjCNF5i_Hk7aXrDf94FyblENWwcGUtqQ&cad=rja

// Pp. 439--440
/***********************************************
 *
 * fix_edges(...
 *
 * This function fixes the edges of an image
 * array after convolution was performed.
 * It copies the points near the edge of the
 * array out to the edge of the array.
 *
 ***********************************************/
fix_edges(im, w, rows, cols)
        int w;
        short **im;
        long rows, cols;
{
        int i, j;
        printf("\nFIX> rows=%ld cols=%ld w=%d",rows,cols,w);
        /* four corners */
        for(i=w; i>0; i--){
                im[i-1][i-1] = im[i][i];
                im[i-1][cols-(i-1)] = im[i][cols-1-(i-1)];
                im[rows-(i-1)][i-1] = im[rows-1-(i-1)][i];
                im[rows-(i-1)][cols-(i-1)] = im[rows-1-(i-1)][cols-1-(i-1)];
        } /* ends four corners loop */
        for(i=0; i<rows; i++){
                for(j=w; j>0; j--){
                        im[i][j-1] = im[i][j];
                        im[i][cols-j] = im[i][cols-j-1];
                }
        }
        for(j=0; j<cols; j++){
                for(i=w; i>0; i--){
                        im[i-1][j] = im[i][j];
                        im[rows-i][j] = im[rows-i-1][j];
                }
        }
}
/* ends fix_edges */

// Pp.464--465
/***********************************************
 *
 *
 median_of(...
 *
 *
 This function finds and returns the
 *
 median value of the elements array.
 *
 *
 As a side result, it also sorts the
 *
 elements array.
 *
 ***********************************************/
median_of(elements, count)
        int *count;
        short elements[];
{
        short median;
        fsort_elements(elements, count);
        median = elements[*count/2];
        return(median);
} /* ends median_of */

/***********************************************
 *
 * fsort_elements(...
 *
 * This function performs a simple bubble
 * sort on the elements from the median
 * filter.
 *
 ***********************************************/
fsort_elements(elements, count)
        int *count;
        short elements[];
{
        int i, j;
        j = *count;
        while(j-- > 1){
                for(i=0; i<j; i++){
                        if(elements[i] > elements[i+1])
                                fswap(&elements[i], &elements[i+1]);
                }
        }
} /* ends fsort_elements */

/***********************************************
 *
 *
 fswap(...
 *
 *
 This function swaps two shorts.
 *
 ***********************************************/
fswap(a, b)
        short *a, *b;
{
        short temp;
        temp = *a;
        *a = *b;
        *b = temp;
} /* ends swap */


// Pp.462--463
median_filter(the_image, out_image,
                rows, cols, size)
int size;
short **the_image, **out_image;
long rows, cols;
{
        int a, b, count, i, j, k, length, sd2, sd2p1, ss, width;
        short *elements;
        sd2  = size/2;
        sd2p1 = sd2 + 1;
        /**********************************************
        *
        *
        Allocate the elements array large enough
        *
        to hold size*size shorts.
        *
        **********************************************/
        ss = size*size;
        elements = (short *) malloc(ss * sizeof(short));
        /***************************
        *
        *
        Loop over image array
        *
        ****************************/
        printf("\n");
        for(i=sd2; i<rows-sd2; i++){
                if( (i%10) == 0) printf("%d ", i);
                for(j=sd2; j<cols-sd2; j++){
                        count = 0;
                        for(a=-sd2; a<sd2p1; a++){
                                for(b=-sd2; b<sd2p1; b++){
                                        elements[count] = the_image[i+a][j+b];
                                        count++;
                                }
                        }
                        out_image[i][j] = median_of(elements, &ss);
                } /* ends loop over j */
        } /* ends loop over i */
        free(elements);
        fix_edges(out_image, sd2, rows-1, cols-1);

}

int main()
{

}

You should read that book carefully and figure out how to load an image, call the filter and save the result.

By the way here is a self-contained sample program from rosettacode.org, which compiles and run on PPM files well:
Code:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
 
typedef struct { unsigned char r, g, b; } rgb_t;
typedef struct {
        int w, h;
        rgb_t **pix;
} image_t, *image;
 
typedef struct {
        int r[256], g[256], b[256];
        int n;
} color_histo_t;
 
int write_ppm(image im, char *fn)
{
        FILE *fp = fopen(fn, "w");
        if (!fp) return 0;
        fprintf(fp, "P6\n%d %d\n255\n", im->w, im->h);
        fwrite(im->pix[0], 1, sizeof(rgb_t) * im->w * im->h, fp);
        fclose(fp);
        return 1;
}
 
image img_new(int w, int h)
{
        int i;
        image im = malloc(sizeof(image_t) + h * sizeof(rgb_t*)
                        + sizeof(rgb_t) * w * h);
        im->w = w; im->h = h;
        im->pix = (rgb_t**)(im + 1);
        for (im->pix[0] = (rgb_t*)(im->pix + h), i = 1; i < h; i++)
                im->pix[i] = im->pix[i - 1] + w;
        return im;
}
 
int read_num(FILE *f)
{
        int n;
        while (!fscanf(f, "%d ", &n)) {
                if ((n = fgetc(f)) == '#') {
                        while ((n = fgetc(f)) != '\n')
                                if (n == EOF) break;
                        if (n == '\n') continue;
                } else return 0;
        }
        return n;
}
 
image read_ppm(char *fn)
{
        FILE *fp = fopen(fn, "r");
        int w, h, maxval;
        image im = 0;
        if (!fp) return 0;
 
        if (fgetc(fp) != 'P' || fgetc(fp) != '6' || !isspace(fgetc(fp)))
                goto bail;
 
        w = read_num(fp);
        h = read_num(fp);
        maxval = read_num(fp);
        if (!w || !h || !maxval) goto bail;
 
        im = img_new(w, h);
        fread(im->pix[0], 1, sizeof(rgb_t) * w * h, fp);
bail:
        if (fp) fclose(fp);
        return im;
}
 
void del_pixels(image im, int row, int col, int size, color_histo_t *h)
{
        int i;
        rgb_t *pix;
 
        if (col < 0 || col >= im->w) return;
        for (i = row - size; i <= row + size && i < im->h; i++) {
                if (i < 0) continue;
                pix = im->pix[i] + col;
                h->r[pix->r]--;
                h->g[pix->g]--;
                h->b[pix->b]--;
                h->n--;
        }
}
 
void add_pixels(image im, int row, int col, int size, color_histo_t *h)
{
        int i;
        rgb_t *pix;
 
        if (col < 0 || col >= im->w) return;
        for (i = row - size; i <= row + size && i < im->h; i++) {
                if (i < 0) continue;
                pix = im->pix[i] + col;
                h->r[pix->r]++;
                h->g[pix->g]++;
                h->b[pix->b]++;
                h->n++;
        }
}
 
void init_histo(image im, int row, int size, color_histo_t*h)
{
        int j;
 
        memset(h, 0, sizeof(color_histo_t));
 
        for (j = 0; j < size && j < im->w; j++)
                add_pixels(im, row, j, size, h);
}
 
int median(const int *x, int n)
{
        int i;
        for (n /= 2, i = 0; i < 256 && (n -= x[i]) > 0; i++);
        return i;
}
 
void median_color(rgb_t *pix, const color_histo_t *h)
{
        pix->r = median(h->r, h->n);
        pix->g = median(h->g, h->n);
        pix->b = median(h->b, h->n);
}
 
image median_filter(image in, int size)
{
        int row, col;
        image out = img_new(in->w, in->h);
        color_histo_t h;
 
        for (row = 0; row < in->h; row ++) {
                for (col = 0; col < in->w; col++) {
                        if (!col) init_histo(in, row, size, &h);
                        else {
                                del_pixels(in, row, col - size, size, &h);
                                add_pixels(in, row, col + size, size, &h);
                        }
                        median_color(out->pix[row] + col, &h);
                }
        }
 
        return out;
}
 
int main(int c, char **v)
{
        int size;
        image in, out;
        if (c <= 3) {
                printf("Usage: %s size ppm_in ppm_out\n", v[0]);
                return 0;
        }
        size = atoi(v[1]);
        printf("filter size %d\n", size);
        if (size < 0) size = 1;
 
        in = read_ppm(v[2]);
        out = median_filter(in, size);
        write_ppm(out, v[3]);
        free(in);
        free(out);
 
        return 0;
}

Hope that helps.

jayshri 02-22-2012 01:52 AM

image processing
 
#include<stdio.h>
#include<stdlib.h>
//#include"medianfilter.h"
#include<memory.h>
#include<math.h>

#define OUTPUT_FILE "out.bmp"

long getImageInfo(FILE*,long,int);

int main(int argc,char *argv[])
{

FILE *bmpInput, *bmpOutput;
unsigned char *pixel;
char signature[2];
long nRows,nCols,nbits;
long xpixpeRm,ypixpeRm;
long nColors;
long fileSize;
long vectorSize;
long nBits;
long rasterOffset;
int i, j,k,l,m;
unsigned char databuff[512][512][3];

if(argc<2)
{
printf("Usage: %s <lena512.bmp>\n",argv[0]);
exit(0);
}

//Open the specified input file for reading.
printf("Reading %s ...\n",argv[1]);
if((bmpInput = fopen(argv[1],"rb"))==NULL)
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}

//open output file.
if((bmpOutput = fopen(argv[2],"w+"))==NULL)
{
if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}
}

//position the pointer to the beginning of the file.
fseek(bmpInput, 0L, SEEK_SET);

//read First two characters of the input file.
for(i=0; i<2; i++)
{
signature[i] = (char)getImageInfo(bmpInput,i,1);
}

//verify First two character of a BMP image file are BM
if((signature[0]=='B') && (signature[1]=='M'))
{
printf("It is verified that the image is in Bitmap format\n");
}
else
{
printf("The image is not a BMP format,quitting....\n");
exit(0);
}

//specifies number of bits per pixel in the image.
nBits = getImageInfo(bmpInput, 28, 2);
printf("The Image is \t%ld-bits per pixel. \n", nBits);

//offset from the begining of the file where the pixel data starts.
rasterOffset = getImageInfo(bmpInput,10,4);
printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

//size of the file in bytes.
fileSize=getImageInfo(bmpInput,2,4);
printf("File size is \t%ld byte\n",fileSize);

//number of columns in image.
nCols = getImageInfo(bmpInput,18,4);
printf("Width:\t\t%ld\n",nCols);

//number of rows in image.
nRows = getImageInfo(bmpInput,22,4);
printf("Height:\t%ld\n",nRows);


xpixpeRm = getImageInfo(bmpInput,38,4);
printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

ypixpeRm = getImageInfo(bmpInput,42,4);
printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

nColors = 1L<<nBits;
printf("There are \t%ld number of colors \n",nColors);

//it is the size of the array required to store the image pixel data.
vectorSize = nCols*nRows;
printf("vector Size is \t%ld\n",vectorSize);

//write the bmp header to the output file.
i = 0;
while(i < rasterOffset)
{
fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
i++;
}


//now declare an 2D array to store & manipulate the image pixel data.
pixel = (char *) malloc(sizeof(char)*nRows*nCols);

//Set all the array value to zero.
printf("\n\nResetting the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = 0x00;
i++;
// printf("%d ", i);
}

//Read the bitmap data into array:
printf("\n\nReading the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = (char)getImageInfo(bmpInput, i, 1);
i++;
// printf("%d ", i);
}

//Display or modify pixel values:
printf("\n\n Diplaying pixel values: \n\n");
i = 0;
j = 0;
while(i < nRows)
{
j = 0;
while(j < nCols)
{
printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
j++;
}
i++;
}
if((nRows!=512)||(nCols!=512)||(nBits!=8)){
printf(" this works only for 512x512 8-color bitmaps\n");
return 0;
}

//int main(void)
//{
// enum {nCols=512,nRows=512};
// const float in[nCols*nRows];
// float out[nCols*nRows];
// median(out,in,nCols,nRows);
// printf("the filterd image is:\n");
// for (int i=0;i<nRows;i++)
//{
// for (int j=0;j<nCols;j++)
//{
// printf("%0.f",out[i*nCols+j]);
// printf("\n");
//}
//
//return 0;
// Median filtering
void _medianfilter( element* image,element* result,int nCols,int nRows)
{
for(int m=1;m<nRows-1;++m)
for(int n=1;n<nCols-1;++n)
{
int k=0;
element window[9];
for(int j=m-1;j<m+2;++j)
for(int i=n-1;i<n+2;++i)
window[k++]=image[j*N+i];
for(int j=0;j<5;++j)
{
int min =j;
for(int l=j+1;l<9;++l)
if(window[l]<window[min])
min=l;
const element temp=window[j];
window[j]=window[min];
window[min]=temp;
result[(m-1)*(nCols-2)+n-1]=window[4];
}
}
}






//write the modified pixel array to the output file.
i = 0;
while(i < vectorSize)
{
fputc(pixel[i], bmpOutput);
i++;
}

//write the End-Of-File character the output file.
fputc(EOF, bmpOutput);

printf("\n");
fclose(bmpInput);
fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L, temp;
unsigned char dummy;
int i;

dummy = '0';
ptrC = &dummy;

//position the file pointer to the desired offset.
fseek(inputFile, offset, SEEK_SET);

//read the bytes into values (one byte at a time).
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC,sizeof(char),1,inputFile);
temp = *ptrC;
value = (long) (value + (temp<<(8*(i-1))));

}

return(value);
}



i am using this code.. it prints the pixel value of image of gray scale lena.. bt i am tryning to bulid a structured program.. i am nt able to do the median filtering. if we comrnt out median filtering part it wil display pixel value wid image.. can ne 1 plz suggest me what is going wrong in median filtering part...
regards..:(

firstfire 02-22-2012 04:40 AM

2 Attachment(s)
Hi.

Here is a reviewed code, which seems to do median filtering with 3x3 window. Previously erroneous places are marked with bold font.
Code:

#include<stdio.h>
#include<stdlib.h>
//#include"medianfilter.h"
#include<memory.h>
#include<math.h>

#define OUTPUT_FILE "out.bmp"

typedef char element;
long getImageInfo(FILE*,long,int);

// Median filtering
void _medianfilter( element* image,element* result,int nCols,int nRows)
{
        for(int m=1;m<nRows-1;++m)
                for(int n=1;n<nCols-1;++n)
                {
                        int k=0;
                        element window[9];
                        for(int j=m-1;j<m+2;++j)
                                for(int i=n-1;i<n+2;++i)
                                        window[k++]=image[j*nCols+i];
                        for(int j=0;j<5;++j)
                        {
                                int min =j;
                                for(int l=j+1;l<9;++l)
                                        if(window[l]<window[min])
                                                min=l;
                                const element temp=window[j];
                                window[j]=window[min];
                                window[min]=temp;
                                result[(m-1)*(nCols)+n-1]=window[4];
                        }
                }
}

int main(int argc,char *argv[])
{

        FILE *bmpInput, *bmpOutput;
        unsigned char *pixel;
        char signature[2];
        long nRows,nCols,nbits;
        long xpixpeRm,ypixpeRm;
        long nColors;
        long fileSize;
        long vectorSize;
        long nBits;
        long rasterOffset;
        int i, j,k,l,m;
        unsigned char databuff[512][512][3];

        if(argc<2)
        {
                printf("Usage: %s <lena512.bmp>\n",argv[0]);
                exit(0);
        }

        //Open the specified input file for reading.
        printf("Reading %s ...\n",argv[1]);
        if((bmpInput = fopen(argv[1],"rb"))==NULL)
        {
                printf("Cannot read %s \n", argv[1]);
                exit(0);
        }

        //open output file.
        if((bmpOutput = fopen(argv[2],"w+"))==NULL)
        {
                if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
                {
                        printf("Cannot read %s \n", argv[1]);
                        exit(0);
                }
        }

        //position the pointer to the beginning of the file.
        fseek(bmpInput, 0L, SEEK_SET);

        //read First two characters of the input file.
        for(i=0; i<2; i++)
        {
                signature[i] = (char)getImageInfo(bmpInput,i,1);
        }

        //verify First two character of a BMP image file are BM
        if((signature[0]=='B') && (signature[1]=='M'))
        {
                printf("It is verified that the image is in Bitmap format\n");
        }
        else
        {
                printf("The image is not a BMP format,quitting....\n");
                exit(0);
        }

        //specifies number of bits per pixel in the image.
        nBits = getImageInfo(bmpInput, 28, 2);
        printf("The Image is \t%ld-bits per pixel. \n", nBits);

        //offset from the begining of the file where the pixel data starts.
        rasterOffset = getImageInfo(bmpInput,10,4);
        printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

        //size of the file in bytes.
        fileSize=getImageInfo(bmpInput,2,4);
        printf("File size is \t%ld byte\n",fileSize);

        //number of columns in image.
        nCols = getImageInfo(bmpInput,18,4);
        printf("Width:\t\t%ld\n",nCols);

        //number of rows in image.
        nRows = getImageInfo(bmpInput,22,4);
        printf("Height:\t%ld\n",nRows);


        xpixpeRm = getImageInfo(bmpInput,38,4);
        printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

        ypixpeRm = getImageInfo(bmpInput,42,4);
        printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

        nColors = 1L<<nBits;
        printf("There are \t%ld number of colors \n",nColors);

        //it is the size of the array required to store the image pixel data.
        vectorSize = nCols*nRows;
        printf("vector Size is \t%ld\n",vectorSize);


        //write the bmp header to the output file.
        i = 0;
        while(i < rasterOffset)
        {
                fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
                i++;
        }


        //now declare an 2D array to store & manipulate the image pixel data.
        pixel = (char *) malloc(sizeof(char)*nRows*nCols);

        //Set all the array value to zero.
        printf("\n\nResetting the pixel array: ");
        i = 0;
        while(i < vectorSize)
        {
                pixel[i] = 0x00;
                i++;
                // printf("%d ", i);
        }

        //Read the bitmap data into array:
        printf("\n\nReading the pixel array: ");
        i = 0;
        while(i < vectorSize)
        {
                //NOTE: Pixel array starts at rasterOffset!!!
                pixel[i] = (char)getImageInfo(bmpInput, rasterOffset + i, 1);
                i++;
                // printf("%d ", i);
        }

        //Display or modify pixel values:
        printf("\n\n Diplaying pixel values: \n\n");
        i = 0;
        j = 0;
        while(i < nRows)
        {
                j = 0;
                while(j < nCols)
                {
                        printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
                        j++;
                }
                i++;
        }
        if((nRows!=512)||(nCols!=512)||(nBits!=8)){
                printf(" this works only for 512x512 8-color bitmaps\n");
                return 0;
        }

        _medianfilter( pixel, pixel, nCols, nRows);
        //write the modified pixel array to the output file.
        i = 0;
        while(i < vectorSize)
        {
                fputc(pixel[i], bmpOutput);
                i++;
        }

        //write the End-Of-File character the output file.
        fputc(EOF, bmpOutput);

        printf("\n");
        fclose(bmpInput);
        fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
        unsigned char *ptrC;
        long value = 0L, temp;
        unsigned char dummy;
        int i;

        dummy = '0';
        ptrC = &dummy;

        //position the file pointer to the desired offset.
        fseek(inputFile, offset, SEEK_SET);

        //read the bytes into values (one byte at a time).
        for(i=0; i<numberOfChars; i++)
        {
                fread(ptrC,sizeof(char),1,inputFile);
                temp = *ptrC;
                value = (long) (value + (temp<<(8*i)));
        }

        return(value);
}

Compile and run it with
Code:

$ gcc -std=c99  median.c && ./a.out lena512.bmp
Here are input and resulting images:

Attachment 9124 Attachment 9125

PS: To improve readability of your posts please put program sources into [code] ... [/code] tags.

Full list of available tags is here.

jayshri 02-22-2012 05:04 AM

image processing
 
Thanx alot.. u helpd a lot... m checking d code

jayshri 02-22-2012 05:45 AM

im
 
It worked.. thank u friend..:)

firstfire 02-22-2012 06:15 AM

You're welcome!

jayshri 02-27-2012 12:44 AM

image processing
 
helo firstfire,
m trying to do laplacian spatial filtering of my image for the sharpening purpose. I am easily gettng the codes in matlab.but for C i am not getting any specific codes.. can u help me with that???
Regards.:)

jayshri 02-27-2012 12:49 AM

image processing
 
/* laplacian.c */
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include "mypgm.h"

void laplacian_filtering( )
/* Spatial filtering of image data */
/* 8-neighbor Laplacian filter */
/* Input: image1[y][x] ---- Outout: image2[y][x] */
{
/* Definition of 8-neighbor Laplacian filter */
int weight[3][3] = {{ 1, 1, 1 },
{ 1, -8, 1 },
{ 1, 1, 1 }};
double pixel_value;
double min, max;
int x, y, i, j; /* Loop variable */

/* Maximum values calculation after filtering*/
printf("Now, filtering of input image is performed\n\n");
min = DBL_MAX;
max = -DBL_MAX;
for (y = 1; y < y_size1 - 1; y++) {
for (x = 1; x < x_size1 - 1; x++) {
pixel_value = 0.0;
for (j = - 1; j < 2; j++) {
for (i = -1; i < 2; i++) {
pixel_value += weight[j + 1][i + 1] * image1[y + j][x + i];
}
}
if (pixel_value < min) min = pixel_value;
if (pixel_value > max) max = pixel_value;
}
}
if ((int)(max - min) == 0) {
printf("Nothing exists!!!\n\n");
exit(1);
}

/* Initialization of image2[y][x] */
x_size2 = x_size1;
y_size2 = y_size1;
for (y = 0; y < y_size2; y++) {
for (x = 0; x < x_size2; x++) {
image2[y][x] = 0;
}
}

/* Generation of image2 after linear transformtion */
for (y = 1; y < y_size1 - 1; y++) {
for (x = 1; x < x_size1 - 1; x++) {
pixel_value = 0.0;
for (j = - 1; j < 2; j++) {
for (i = -1; i < 2; i++) {
pixel_value += weight[j + 1][i + 1] * image1[y + j][x + i];
}
}
pixel_value = MAX_BRIGHTNESS * (pixel_value - min) / (max - min);
image2[y][x] = (unsigned char)pixel_value;
}
}
}

main( )
{
load_image_data( ); /* Input of image1 */
laplacian_filtering( ); /* Laplacian filtering is applied to image1 */
save_image_data( ); /* Output of image2 */
return 0;
}.
I have this code with me.. but while putting it with the previous program with median filtering itz showing some error.. i am unable to figure it out... hw to apply this program with the previous 1 for spatial filtering??
Regards

firstfire 02-27-2012 03:41 AM

Hi.

Can you please post the exact code you are compiling with all necessary headers (like mypgm.h) and show exact error message. Also consider using [code] ... [/code] tags around your code.

jayshri 02-27-2012 04:32 AM

image processing
 
#include<stdio.h>
#include<stdlib.h>
//#include"medianfilter.h"
#include<memory.h>
#include<math.h>
#include"mypgm.h"

#define OUTPUT_FILE "out.bmp"
typedef char element;


long getImageInfo(FILE*,long,int);
void _medianfilter(element* image,element* result,int nCols,int nRows)
{
for(int m=1;m<nRows-1;++m)
for(int n=1;n<nCols-1;++n)
{
int k=0;
element window[9];
for(int j=m-1;j<m+2;++j)
for(int i=n-1;i<n+2;++i)
window[k++]=image[j*nCols+i];
for(int j=0;j<5;++j)
{
int min=j;
for(int l=j+1;l<9;++l)
if(window[l]<window[min])
min=l;
const element temp=window[j];
window[j]=window[min];
window[min]=temp;
result[(m-1)*(nCols)+n-1]=window[4];
}
}
}
void laplacian_filtering()
/* spatial filtering of image*/
/*8-neighbor Laplacian filter*/
/*input:image1[y][x]-Outout:image2[y][x]*/
{
/*Definition of 8-neighbour Laplacian filter*/
int weight[3][3]={{1,1,1},
{1,-8,1},
{1,1,1}};
double pixel_value;
double min,max;
int x,y,i,j;
/*Maximum values calculation after filtering*/
printf("Now,filtering of input image is performed\n\n");
min=DBL_MAX;
max=DBL_MAX;
for(y=1;y<y_size1-1;y++){
for(x=1;x<x_size1-1;x++){
pixel_value=0.0;
for(j=-1;j<2<j++){
for(i=-1;i<2;i++){
pixel_value+=weight[j+1][i+1]*image1[y+j][x+i];
}
}
if(pixe;_value<min)min=pixel_value;
if(pixel_value>max)max=pixel_value;
}
}
if((int)(max-min)==0){
printf("Nothing exist!!!\n\n");
exit(1);
}
//initialization of image2[y][x]
x_size2=x_size1;
y_size2=y_size1;
for(y=0;y<y_size2;y++){
for(x=0;x<x_size2;x++){
image2[y][x]=0;
}
}
//Generation of image 2 after linear transformation
for(y=1;y<y_size1-1;y++){
for(x=1;x<x_size1-1;x++){
pixel_value=0.0;
for(j=-1;j<2;j++){
for(i=-1;i<2;i++){
pixel_value+=weight[j+1][i+1]*image[y+j][x+i];
}
}
pixel_value=MAX_BRIGHTNESS*(pixel_value-min)/(max-min);
image2[y][x]=(unsigned char)pixel_value;
}
}
}



int main(int argc,char *argv[])
{

FILE *bmpInput, *bmpOutput;
unsigned char *pixel;
char signature[2];
long nRows,nCols,nbits;
long xpixpeRm,ypixpeRm;
long nColors;
long fileSize;
long vectorSize;
long nBits;
long rasterOffset;
int i, j,k,l,m;
unsigned char databuff[512][512][3];

if(argc<2)
{
printf("Usage: %s <lena512.bmp>\n",argv[0]);
exit(0);
}

//Open the specified input file for reading.
printf("Reading %s ...\n",argv[1]);
if((bmpInput = fopen(argv[1],"rb"))==NULL)
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}

//open output file.
if((bmpOutput = fopen(argv[2],"w+"))==NULL)
{
if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}
}

//position the pointer to the beginning of the file.
fseek(bmpInput, 0L, SEEK_SET);

//read First two characters of the input file.
for(i=0; i<2; i++)
{
signature[i] = (char)getImageInfo(bmpInput,i,1);
}

//verify First two character of a BMP image file are BM
if((signature[0]=='B') && (signature[1]=='M'))
{
printf("It is verified that the image is in Bitmap format\n");
}
else
{
printf("The image is not a BMP format,quitting....\n");
exit(0);
}

//specifies number of bits per pixel in the image.
nBits = getImageInfo(bmpInput, 28, 2);
printf("The Image is \t%ld-bits per pixel. \n", nBits);

//offset from the begining of the file where the pixel data starts.
rasterOffset = getImageInfo(bmpInput,10,4);
printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

//size of the file in bytes.
fileSize=getImageInfo(bmpInput,2,4);
printf("File size is \t%ld byte\n",fileSize);

//number of columns in image.
nCols = getImageInfo(bmpInput,18,4);
printf("Width:\t\t%ld\n",nCols);

//number of rows in image.
nRows = getImageInfo(bmpInput,22,4);
printf("Height:\t%ld\n",nRows);


xpixpeRm = getImageInfo(bmpInput,38,4);
printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

ypixpeRm = getImageInfo(bmpInput,42,4);
printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

nColors = 1L<<nBits;
printf("There are \t%ld number of colors \n",nColors);

//it is the size of the array required to store the image pixel data.
vectorSize = nCols*nRows;
printf("vector Size is \t%ld\n",vectorSize);

//write the bmp header to the output file.
i = 0;
while(i < rasterOffset)
{
fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
i++;
}


//now declare an 2D array to store & manipulate the image pixel data.
pixel = (char *) malloc(sizeof(char)*nRows*nCols);

//Set all the array value to zero.
printf("\n\nResetting the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = 0x00;
i++;
// printf("%d ", i);
}

//Read the bitmap data into array:
printf("\n\nReading the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = (char)getImageInfo(bmpInput,rasterOffset+ i, 1);
i++;
// printf("%d ", i);
}

//Display or modify pixel values:
printf("\n\n Diplaying pixel values: \n\n");
i = 0;
j = 0;
while(i < nRows)
{
j = 0;
while(j < nCols)
{
printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
j++;
}
i++;
}
if((nRows!=512)||(nCols!=512)||(nBits!=8)){
printf(" this works only for 512x512 8-color bitmaps\n");
return 0;
}

//int main(void)
//{
// enum {nCols=512,nRows=512};
// const float in[nCols*nRows];
// float out[nCols*nRows];
// median(out,in,nCols,nRows);
// printf("the filterd image is:\n");
// for (int i=0;i<nRows;i++)
//{
// for (int j=0;j<nCols;j++)
//{
// printf("%0.f",out[i*nCols+j]);
// printf("\n");
//}
//
//return 0;
_medianfilter(pixel,pixel,nCols,nRows);
load_image_data();//input of image1
laplacian_filtering();//laplacian filtering is applied to image1
save_image_data();//output of image2
return 0;


//write the modified pixel array to the output file.
i = 0;
while(i < vectorSize)
{
fputc(pixel[i], bmpOutput);
i++;
}

//write the End-Of-File character the output file.
fputc(EOF, bmpOutput);

printf("\n");
fclose(bmpInput);
fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L, temp;
unsigned char dummy;
int i;

dummy = '0';
ptrC = &dummy;

//position the file pointer to the desired offset.
fseek(inputFile, offset, SEEK_SET);

//read the bytes into values (one byte at a time).
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC,sizeof(char),1,inputFile);
temp = *ptrC;
value = (long) (value + (temp<<(8*(i-1))));

}

return(value);
}



here mypgm.h header is not accpted due to which itz showing errors like undeclared DBL_MAX,x_size1,y_size1,MAX_BRIGHTNESS..
any alternative option is there 4 doing the laplacian filtering???
Regards

firstfire 02-27-2012 06:04 AM

Hi.

Seems to work:
Code:

#include <stdio.h>
#include <stdlib.h>
//#include "medianfilter.h"
#include <memory.h>
#include <math.h>
#include <float.h>        // for DBL_MAX
//#include"mypgm.h"
#define MAX_BRIGHTNESS 80
#define OUTPUT_FILE "out.bmp"
typedef char element;


long getImageInfo(FILE*,long,int);

void _medianfilter(element* image,element* result,int nCols,int nRows)
{
        for(int m=1;m<nRows-1;++m)
                for(int n=1;n<nCols-1;++n)
                {
                        int k=0;
                        element window[9];
                        for(int j=m-1;j<m+2;++j)
                                for(int i=n-1;i<n+2;++i)
                                        window[k++]=image[j*nCols+i];
                        for(int j=0;j<5;++j)
                        {
                                int min=j;
                                for(int l=j+1;l<9;++l)
                                        if(window[l]<window[min])
                                                min=l;
                                const element temp=window[j];
                                window[j]=window[min];
                                window[min]=temp;
                                result[(m-1)*(nCols)+n-1]=window[4];
                        }
                }
}
void laplacian_filtering(element *image1, element *image2, int x_size1, int y_size1)
        /* spatial filtering of image*/
        /*8-neighbor Laplacian filter*/
        /*input:image1[y][x]-Outout:image2[y][x]*/
{
        /*Definition of 8-neighbour Laplacian filter*/
        int weight[3][3]={
                {1,1,1},
                {1,-8,1},
                {1,1,1}};
        double pixel_value;
        double min,max;
        int x,y,i,j;
        /*Maximum values calculation after filtering*/
        printf("Now,filtering of input image is performed\n\n");
        min=DBL_MAX;
        max=DBL_MIN; // not DBL_MAX
        for(y=1;y<y_size1-1;y++){
                for(x=1;x<x_size1-1;x++){
                        pixel_value=0.0;
                        for(j=-1;j<2;j++){
                                for(i=-1;i<2;i++){
                                        pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j) + x+i];
                                }
                        }
                        if(pixel_value<min)min=pixel_value;
                        if(pixel_value>max)max=pixel_value;
                }
        }
        if((int)(max-min)==0){
                printf("Nothing exist!!!\n\n");
                exit(1);
        }
        //Generation of image 2 after linear transformation
        for(y=1;y<y_size1-1;y++){
                for(x=1;x<x_size1-1;x++){
                        pixel_value=0.0;
                        for(j=-1;j<2;j++){
                                for(i=-1;i<2;i++){
                                        pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j) + x+i];
                                }
                        }
                        pixel_value=MAX_BRIGHTNESS*(pixel_value-min)/(max-min);
                        image2[y*x_size1 + x]=(unsigned char)pixel_value;
                }
        }
}


int main(int argc,char *argv[])
{

        FILE *bmpInput, *bmpOutput;
        unsigned char *pixel, *result;
        char signature[2];
        long nRows,nCols,nbits;
        long xpixpeRm,ypixpeRm;
        long nColors;
        long fileSize;
        long vectorSize;
        long nBits;
        long rasterOffset;
        int i, j,k,l,m;
        unsigned char databuff[512][512][3];

        if(argc<2)
        {
                printf("Usage: %s <lena512.bmp>\n",argv[0]);
                exit(0);
        }

        //Open the specified input file for reading.
        printf("Reading %s ...\n",argv[1]);
        if((bmpInput = fopen(argv[1],"rb"))==NULL)
        {
                printf("Cannot read %s \n", argv[1]);
                exit(0);
        }

        //open output file.
        if((bmpOutput = fopen(argv[2],"w+"))==NULL)
        {
                if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
                {
                        printf("Cannot read %s \n", argv[1]);
                        exit(0);
                }
        }

        //position the pointer to the beginning of the file.
        fseek(bmpInput, 0L, SEEK_SET);

        //read First two characters of the input file.
        for(i=0; i<2; i++)
        {
                signature[i] = (char)getImageInfo(bmpInput,i,1);
        }

        //verify First two character of a BMP image file are BM
        if((signature[0]=='B') && (signature[1]=='M'))
        {
                printf("It is verified that the image is in Bitmap format\n");
        }
        else
        {
                printf("The image is not a BMP format,quitting....\n");
                exit(0);
        }

        //specifies number of bits per pixel in the image.
        nBits = getImageInfo(bmpInput, 28, 2);
        printf("The Image is \t%ld-bits per pixel. \n", nBits);

        //offset from the begining of the file where the pixel data starts.
        rasterOffset = getImageInfo(bmpInput,10,4);
        printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

        //size of the file in bytes.
        fileSize=getImageInfo(bmpInput,2,4);
        printf("File size is \t%ld byte\n",fileSize);

        //number of columns in image.
        nCols = getImageInfo(bmpInput,18,4);
        printf("Width:\t\t%ld\n",nCols);

        //number of rows in image.
        nRows = getImageInfo(bmpInput,22,4);
        printf("Height:\t%ld\n",nRows);


        xpixpeRm = getImageInfo(bmpInput,38,4);
        printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

        ypixpeRm = getImageInfo(bmpInput,42,4);
        printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

        nColors = 1L<<nBits;
        printf("There are \t%ld number of colors \n",nColors);

        //it is the size of the array required to store the image pixel data.
        vectorSize = nCols*nRows;
        printf("vector Size is \t%ld\n",vectorSize);

        //write the bmp header to the output file.
        i = 0;
        while(i < rasterOffset)
        {
                fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
                i++;
        }


        //now declare an 2D array to store & manipulate the image pixel data.
        // calloc() allocates and resets the memory to zero.
        pixel  = (char *) calloc(sizeof(char)*nRows*nCols, sizeof(char));
        result = (char *) calloc(sizeof(char)*nRows*nCols, sizeof(char));

        //Set all the array value to zero.
        // Not necessary if allocated with calloc.
        /*
        printf("\n\nResetting the pixel array: ");
        i = 0;
        while(i < vectorSize)
        {
                pixel[i] = 0x00;
                i++;
                // printf("%d ", i);
        }
        */

        //Read the bitmap data into array:
        printf("\n\nReading the pixel array: ");
        i = 0;
        while(i < vectorSize)
        {
                pixel[i] = (char)getImageInfo(bmpInput,rasterOffset+ i, 1);
                i++;
                // printf("%d ", i);
        }

        //Display or modify pixel values:
        printf("\n\n Diplaying pixel values: \n\n");
        i = 0;
        j = 0;
        while(i < nRows)
        {
                j = 0;
                while(j < nCols)
                {
                        printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
                        j++;
                }
                i++;
        }
        if((nRows!=512)||(nCols!=512)||(nBits!=8)){
                printf(" this works only for 512x512 8-color bitmaps\n");
                return 0;
        }

        // It is not completely correct to call with arguments (pixel, pixel, ...),
        // as the transformation is not local (i.e. not point-to-point).
        _medianfilter(pixel,result,nCols,nRows);
        laplacian_filtering(result, pixel, nCols, nRows);//laplacian filtering is applied to image1

        //save_image_data();//output of image2
        //return 0;


        //write the modified pixel array to the output file.
        i = 0;
        while(i < vectorSize)
        {
                fputc(pixel[i], bmpOutput);
                i++;
        }

        //write the End-Of-File character the output file.
        fputc(EOF, bmpOutput);

        printf("\n");
        fclose(bmpInput);
        fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
        unsigned char *ptrC;
        long value = 0L, temp;
        unsigned char dummy;
        int i;

        dummy = '0';
        ptrC = &dummy;

        //position the file pointer to the desired offset.
        fseek(inputFile, offset, SEEK_SET);

        //read the bytes into values (one byte at a time).
        for(i=1; i<=numberOfChars; i++)
        {
                fread(ptrC,sizeof(char),1,inputFile);
                temp = *ptrC;
                value = (long) (value + (temp<<(8*(i-1))));

        }

        return(value);
}


jayshri 02-28-2012 12:56 AM

image processing
 
Hello,
Thanx alot..:D.
I would like to say that since i am very new to this field nd also not that much expert about coding i would like to clear some doubts from u..
it wil b very helpful for me if you kindly clear my doubts.
1.last time when i got some problem with median filtering part then you have added the argument(pixel,pixel..)
then in case of laplacian what wil b the problem?? wil the argument(pixel,pixel...)wil work for median filter??
2.In declaring 2D array part:malloc function worked during median filter.bt during laplacian we are applying calloc???
so do we have to manupalted these things that i mentioned above during laplacian???
nd for median it won't need any change right???

Thanx will be very less for the help that u have done with my coding.:D.
actualy itz a project that i have to complete soon.
Regards..:)

firstfire 02-28-2012 02:12 AM

Hi.

Good questions.
Quote:

1.last time when i got some problem with median filtering part then you have added the argument(pixel,pixel..)
then in case of laplacian what wil b the problem?? wil the argument(pixel,pixel...)wil work for median filter??
Actually in both cases (median and laplacian filters) one should pass different arrays as input and output. That is because the transformation we apply to (i,j)-th input pixel depends also on the neighbourhood of that pixel and if we put the result into the same pixel (in the same array), then, when we proceed to (i+1,j)-th pixel, our result will be incorrect -- we already changed pixel (i,j) from neighbourhood if (i+1,j). That's why last time I used second array to store the result:
Code:

median: pixel -> result
laplacian: result -> pixel

Quote:

2.In declaring 2D array part:malloc function worked during median filter.bt during laplacian we are applying calloc???
malloc() and calloc() are the same, except that calloc() also sets allocated memory to zero. In fact, you may use malloc() and do not initialize arrays, because their elements are explicitly set when you load bitmap and perform transformations (so you never use uninitialized values). For more details read `man malloc'.

jayshri 02-28-2012 02:19 AM

image processing
 
now i gt it thanx alot... m done with preprocessing technique..
nw i wil start edge detection then..:)

jayshri 02-29-2012 02:04 AM

im
 
double gaussian (double x, double mu, double sigma) {
return exp( -(((x-mu)/(sigma))*((x-mu)/(sigma)))/2.0 );
}

vector< vector<double> > produce2dGaussianKernel (int kernelRadius) {
// get kernel matrix
vector< vector<double> > kernel2d ( 2*kernelRadius+1,
vector<double>(2*kernelRadius+1)
);

// determine sigma
double sigma = kernelRadius/2.;

// fill values
double sum = 0;
for (int row = 0; row < kernel2d.size(); row++)
for (int col = 0; col < kernel2d[row].size(); col++) {
kernel2d[row][col] = gaussian(row, kernelRadius, sigma) *
gaussian(col, kernelRadius, sigma);
sum += kernel2d[row][col];
}

// normalize
for (int row = 0; row < kernel2d.size(); row++)
for (int col = 0; col < kernel2d[row].size(); col++)
kernel2d[row][col] /= sum;

return kernel2d;
}

int main() {
vector< vector<double> > kernel2d = produce2dGaussianKernel (3);
for (int row = 0; row < kernel2d.size(); row++) {
for (int col = 0; col < kernel2d[row].size(); col++)
cout << setprecision(5) << fixed << kernel2d[row][col] << " ";
cout << endl;
}
}
itz a c++ code for aaplying gaussian blurr on a image..
i am unable to understand the 1 st part of the code nd hw to convert it into c..
what wil b the euivalent c code..
Regards

jayshri 02-29-2012 04:24 AM

i mean the middle and the main part wil b same i think.. bt 1st part i didn't get... what wil b the c code for that..
Regards..:)

jayshri 02-29-2012 05:23 AM

i
 
double sigma = 1;
int W = 5;
double kernel[W][W];
double mean = W/2;
for (int x = 0; x < W; ++x) for (int y = 0; y < W; ++y)
{
kernel[x][y] = exp( -0.5 * (pow((x-mean)/sigma, 2.0) + pow((y-mean)/sigma,2.0)) )
/ (2 * M_PI * sigma * sigma);
}



wil this code work with my code above???..
regards

firstfire 02-29-2012 05:35 AM

Hi.

Yes, in principle this will work after some tiny modifications to the laplacian filter (the size of convolution kernel in 5x5 instead of 3x3). BTW, take a look at http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm. I'd probably introduce some convolution(in, out, sizes, kernel, kern_size) function which can be used to perform different types of filtering.

jayshri 02-29-2012 05:39 AM

with the theory part i am all clear.. but again stuck with programming..:(((
regargds....

jayshri 03-01-2012 01:55 AM

im
 
hello firstfire,
I tried out this program.. i have changed the kernel into 5X5.

#include<stdio.h>
#include<stdlib.h>
//#include"medianfilter.h"
#include<memory.h>
#include<math.h>
#include<float.h>
#define MAX_BRIGHTNESS 80
#define OUTPUT_FILE "out.bmp"
typedef char element;


long getImageInfo(FILE*,long,int);
void _medianfilter(element* image,element* result,int nCols,int nRows)
{
for(int m=1;m<nRows-1;++m)
for(int n=1;n<nCols-1;++n)
{
int k=0;
element window[9];
for(int j=m-1;j<m+2;++j)
for(int i=n-1;i<n+2;++i)
window[k++]=image[j*nCols+i];
for(int j=0;j<5;++j)
{
int min=j;
for(int l=j+1;l<9;++l)
if(window[l]<window[min])
min=l;
const element temp=window[j];
window[j]=window[min];
window[min]=temp;
result[(m-1)*(nCols)+n-1]=window[4];
}
}
}
void laplacian_filtering(element *image1,element *image2,int x_size1,int y_size1)
/* spatial filtering of image*/
/*8-neighbor Laplacian filter*/
/*input:image1[y][x]-Outout:image2[y][x]*/

/*Definition of 8-neighbour Laplacian filter*/
{
int weight[5][5]={{2,4,5,4,2},
{4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}};
double pixel_value;
double min,max;
int x,y,i,j;
/*Maximum values calculation after filtering*/
printf("Now,filtering of input image is performed\n\n");
min=DBL_MAX;
max=DBL_MIN;
for(y=1;y<y_size1-1;y++){
for(x=1;x<x_size1-1;x++){
pixel_value=0.0;
for(j=-1;j<2;j++){
for(i=-1;i<2;i++){
pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j)+x+i];
}
}
if(pixel_value<min)min=pixel_value;
if(pixel_value>max)max=pixel_value;
}
}
if((int)(max-min)==0){
printf("Nothing exist!!!\n\n");
exit(1);
}
//initialization of image2[y][x]
//x_size2=x_size1;
//y_size2=y_size1;
//for(y=0;y<y_size2;y++){
//for(x=0;x<x_size2;x++){
//image2[y][x]=0;
//}
//}
//Generation of image 2 after linear transformation
for(y=1;y<y_size1-1;y++){
for(x=1;x<x_size1-1;x++){
pixel_value=0.0;
for(j=-1;j<2;j++){
for(i=-1;i<2;i++){
pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j)+x+i];
}
}
pixel_value=MAX_BRIGHTNESS*(pixel_value-min)/(max-min);
image2[y*x_size1+x]=(unsigned char)pixel_value;
}
}
}
double sigma=1;
int W=5;
double kernel[W][W];
double mean=W/2;
for(int x=0;x<W;++x)
{
for(int y=0;y<W;++y)
{
kernel[x][y]=exp(-0.5*(pow((x-mean)/sigma,2.0)+pow((y-mean)/sigma,2.0)))/(2*M_PI*sigma*sigma);
}
}




int main(int argc,char *argv[])
{

FILE *bmpInput, *bmpOutput;
unsigned char *pixel,*result;
char signature[2];
long nRows,nCols,nbits;
long xpixpeRm,ypixpeRm;
long nColors;
long fileSize;
long vectorSize;
long nBits;
long rasterOffset;
int i, j,k,l,m;
unsigned char databuff[512][512][3];

if(argc<2)
{
printf("Usage: %s <median.bmp>\n",argv[0]);
exit(0);
}

//Open the specified input file for reading.
printf("Reading %s ...\n",argv[1]);
if((bmpInput = fopen(argv[1],"rb"))==NULL)
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}

//open output file.
if((bmpOutput = fopen(argv[2],"w+"))==NULL)
{
if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}
}

//position the pointer to the beginning of the file.
fseek(bmpInput, 0L, SEEK_SET);

//read First two characters of the input file.
for(i=0; i<2; i++)
{
signature[i] = (char)getImageInfo(bmpInput,i,1);
}

//verify First two character of a BMP image file are BM
if((signature[0]=='B') && (signature[1]=='M'))
{
printf("It is verified that the image is in Bitmap format\n");
}
else
{
printf("The image is not a BMP format,quitting....\n");
exit(0);
}

//specifies number of bits per pixel in the image.
nBits = getImageInfo(bmpInput, 28, 2);
printf("The Image is \t%ld-bits per pixel. \n", nBits);

//offset from the begining of the file where the pixel data starts.
rasterOffset = getImageInfo(bmpInput,10,4);
printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

//size of the file in bytes.
fileSize=getImageInfo(bmpInput,2,4);
printf("File size is \t%ld byte\n",fileSize);

//number of columns in image.
nCols = getImageInfo(bmpInput,18,4);
printf("Width:\t\t%ld\n",nCols);

//number of rows in image.
nRows = getImageInfo(bmpInput,22,4);
printf("Height:\t%ld\n",nRows);


xpixpeRm = getImageInfo(bmpInput,38,4);
printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

ypixpeRm = getImageInfo(bmpInput,42,4);
printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

nColors = 1L<<nBits;
printf("There are \t%ld number of colors \n",nColors);

//it is the size of the array required to store the image pixel data.
vectorSize = nCols*nRows;
printf("vector Size is \t%ld\n",vectorSize);

//write the bmp header to the output file.
i = 0;
while(i < rasterOffset)
{
fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
i++;
}


//now declare an 2D array to store & manipulate the image pixel data.
pixel = (char *) calloc(sizeof(char)*nRows*nCols,sizeof(char));
result= (char *) calloc(sizeof(char)*nRows*nCols,sizeof(char));

//Set all the array value to zero.
printf("\n\nResetting the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = 0x00;
i++;
// printf("%d ", i);
}

//Read the bitmap data into array:
printf("\n\nReading the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = (char)getImageInfo(bmpInput,rasterOffset+ i, 1);
i++;
// printf("%d ", i);
}

//Display or modify pixel values:
printf("\n\n Diplaying pixel values: \n\n");
i = 0;
j = 0;
while(i < nRows)
{
j = 0;
while(j < nCols)
{
printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
j++;
}
i++;
}
if((nRows!=512)||(nCols!=512)||(nBits!=8)){
printf(" this works only for 512x512 8-color bitmaps\n");
return 0;
}

//int main(void)
//{
// enum {nCols=512,nRows=512};
// const float in[nCols*nRows];
// float out[nCols*nRows];
// median(out,in,nCols,nRows);
// printf("the filterd image is:\n");
// for (int i=0;i<nRows;i++)
//{
// for (int j=0;j<nCols;j++)
//{
// printf("%0.f",out[i*nCols+j]);
// printf("\n");
//}
//
//return 0;
_medianfilter(pixel,result,nCols,nRows);
//load_image_data();//input of image1
laplacian_filtering(result,pixel,nCols,nRows);//laplacian filtering is applied to image1
//save_image_data();//output of image2
//return 0;


//write the modified pixel array to the output file.
i = 0;
while(i < vectorSize)
{
fputc(pixel[i], bmpOutput);
i++;
}

//write the End-Of-File character the output file.
fputc(EOF, bmpOutput);

printf("\n");
fclose(bmpInput);
fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L, temp;
unsigned char dummy;
int i;

dummy = '0';
ptrC = &dummy;

//position the file pointer to the desired offset.
fseek(inputFile, offset, SEEK_SET);

//read the bytes into values (one byte at a time).
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC,sizeof(char),1,inputFile);
temp = *ptrC;
value = (long) (value + (temp<<(8*(i-1))));

}

return(value);
}



here is the previous program with some change in kernel part..and also gaussian blurr part included..
is this the way u were telling me to do it????
some error are also coming after introducing gaussian blur part
errors are:
1. Variably modified 'kernel'at first scope
2.initializer element is not constant.
3. expecting identifier befor ++ token.
Didn't able to sort it out..
Regard..:(

firstfire 03-01-2012 12:52 PM

Hi.

Here is a new version. Try to figure out how it works and ask questions. load/save BMP should work with 8bpp images, not sure about other types.
Code:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <string.h>

#define MAX_BRIGHTNESS 255

/*
 * Loading part taken from
 * http://www.vbforums.com/showthread.php?t=261522
 * BMP info:
 * http://en.wikipedia.org/wiki/BMP_file_format
 *
 */
 
/* Note: the magic number has been removed from the bmpfile_header structure
  since it causes alignment problems
    struct bmpfile_magic should be written/read first
  followed by the
    struct bmpfile_header
  [this avoids compiler-specific alignment pragmas etc.]
*/
 
struct bmpfile_magic {
  unsigned char magic[2];
};
 
struct bmpfile_header {
  uint32_t filesz;
  uint16_t creator1;
  uint16_t creator2;
  uint32_t bmp_offset;
};

typedef struct {
  uint32_t header_sz;
  int32_t width;
  int32_t height;
  uint16_t nplanes;
  uint16_t bitspp;
  uint32_t compress_type;
  uint32_t bmp_bytesz;
  int32_t hres;
  int32_t vres;
  uint32_t ncolors;
  uint32_t nimpcolors;
} BITMAPINFOHEADER;

typedef struct {
        uint8_t r;
        uint8_t g;
        uint8_t b;
        uint8_t null;
} rgb_t;

typedef unsigned char pixel_t;

unsigned char *load_bmp(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
        FILE *filePtr; //our file pointer
        struct bmpfile_magic  mag;
        struct bmpfile_header bitmapFileHeader; //our bitmap file header
        unsigned char *bitmapImage;  //store image data

        filePtr = fopen(filename,"r");
        if (filePtr == NULL)
                return NULL;

        fread(&mag, sizeof(struct bmpfile_magic),1,filePtr);
        //verify that this is a bmp file by check bitmap id
        if ( *((uint16_t*) mag.magic) != 0x4D42 )
        {
                fprintf(stderr, "Not a BMP file: magic=%c%c\n", mag.magic[0], mag.magic[1]);
                fclose(filePtr);
                return NULL;
        }
        //read the bitmap file header
        fread(&bitmapFileHeader, sizeof(struct bmpfile_header), 1, filePtr);

        //read the bitmap info header
        fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

        if( bitmapInfoHeader->compress_type != 0)
                fprintf(stderr, "Warning, compression is not supported.\n");

        //move file point to the beginning of bitmap data
        fseek(filePtr, bitmapFileHeader.bmp_offset, SEEK_SET);

        //allocate enough memory for the bitmap image data
        bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->bmp_bytesz);

        //verify memory allocation
        if (!bitmapImage)
        {
                free(bitmapImage);
                fclose(filePtr);
                return NULL;
        }

        //read in the bitmap image data
        fread(bitmapImage, 1, bitmapInfoHeader->bmp_bytesz, filePtr);

        //close file and return bitmap image data
        fclose(filePtr);
        return bitmapImage;
}

// Return: nonzero on error.
int save_bmp(char *filename, BITMAPINFOHEADER *bmp_ih, unsigned char *data)
{
        unsigned int offset =
                sizeof(struct bmpfile_magic)
                + sizeof(struct bmpfile_header)
                + sizeof(BITMAPINFOHEADER)
                + (1<<bmp_ih->bitspp)*4;

        struct bmpfile_header bmp_fh = {
                .filesz = offset + bmp_ih->bmp_bytesz,
                .creator1 = 0,
                .creator2 = 0,
                .bmp_offset = offset
        };

        FILE* fp = fopen(filename,"w");
        if (fp == NULL) return 1;
        struct bmpfile_magic mag = {{0x42, 0x4d}};

        fwrite(&mag, 1, sizeof(struct bmpfile_magic), fp);
        fwrite(&bmp_fh, 1, sizeof(struct bmpfile_header), fp);
        fwrite(bmp_ih, 1, sizeof(BITMAPINFOHEADER), fp);

        // Palette
        rgb_t color = {0, 0, 0, 0};
        int i;
        for(i=0; i < (1<<bmp_ih->bitspp); i++)
        {
                color.r = i;
                color.g = i;
                color.b = i;
                fwrite(&color, 1, sizeof(rgb_t), fp);
        }
        fwrite(data, 1, bmp_ih->bmp_bytesz, fp);

        fclose(fp);
        return 0;
}

void median_filter( pixel_t* image, pixel_t* result, int nCols, int nRows)
{
        int m, n, i, j, l, k, min;
        for(m=1; m<nRows-1; m++)
                for(n=1; n<nCols-1; n++)
                {
                        k = 0;
                        pixel_t window[9];
                        for(j=m-1; j<m+2; j++)
                                for(i=n-1; i<n+2; i++)
                                        window[k++] = image[j*nCols+i];
                        for(j=0; j<5; j++)
                        {
                                min = j;
                                for(l=j+1; l<9; l++)
                                        if(window[l]<window[min]) min=l;
                                pixel_t temp = window[j];
                                window[j] = window[min];
                                window[min] = temp;
                                result[m*(nCols)+n] = window[4];
                        }
                }
}

void convolution(pixel_t *in, pixel_t *out, double *kernel, int nx, int ny, int kn)
{
        int i, j, m, n, c;
        int khalf = floor(kn/2.);
        double pixel, min=DBL_MAX, max=DBL_MIN;

        for(m=khalf; m<nx-khalf; m++)
                for(n=khalf; n<ny-khalf; n++)
                {
                        pixel = 0;
                        for(c=0, i=-khalf; i<=khalf; i++)
                                for(j=-khalf; j<=khalf; j++)
                                        pixel += in[(n-j)*nx + m-i]*kernel[c++];
                        if(pixel < min) min = pixel;
                        if(pixel > max) max = pixel;
                }

        for(m=khalf; m<nx-khalf; m++)
                for(n=khalf; n<ny-khalf; n++)
                {
                        pixel = 0;
                        for(c=0, i=-khalf; i<=khalf; i++)
                                for(j=-khalf; j<=khalf; j++)
                                        pixel += in[(n-j)*nx + m-i]*kernel[c++];

                        pixel = MAX_BRIGHTNESS*(pixel-min)/(max-min);
                        out[n*nx + m] = (unsigned char) pixel;
                }
}

void laplacian_filter(pixel_t *in, pixel_t *out, int nx, int ny)
{
        double kernel[]={
                1,1,1,
                1,-8,1,
                1,1,1};
        convolution(in, out, kernel, nx, ny, 3);
}

void gaussian_filter(pixel_t *in, pixel_t *out, int nx, int ny)
{
        const int n = 7;
        int i, j, c=0;
        double        mean = floor(n/2.), sigma = 1;
        double kernel[n*n];
        for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                        kernel[c++]=exp(-0.5*(
                                                pow((i-mean)/sigma,2.0) +pow((j-mean)/sigma,2.0))
                                        ) /(2*M_PI*sigma*sigma);
        convolution(in, out, kernel, nx, ny, n);
}

int main(int argc, char **argv)
{
        if(argc < 2){
                printf("Usage: %s image.bmp\n", argv[0]);
                exit(1);
        }
        BITMAPINFOHEADER ih;
        pixel_t *bitmap_data, *temp_image;

        bitmap_data = load_bmp(argv[1], &ih);
        temp_image = (unsigned char*) malloc(ih.bmp_bytesz);

        printf("Info: %d x %d x %d\n", ih.width, ih.height, ih.bitspp);

        median_filter(bitmap_data, temp_image, ih.width, ih.height);
        //laplacian_filter(bitmap_data, temp_image, ih.width, ih.height);
        //gaussian_filter(bitmap_data, temp_image, ih.width, ih.height);

        save_bmp("out.bmp", &ih, temp_image);
        return 0;
}


jayshri 03-01-2012 01:58 PM

image processing
 
hi.
the program code u have given is 4 colour image.. but i am working with gray image..
i hav to do the whole process in the same program... i hav already done the loading of bmp image now what i want to do is canny edge detection..
as u hav sugested i hav changed the kernel size... but hw it works i cant figure out.. what is going worng in that code???
nw i hav to manipulate the previous code only nd av to perform canny edge detection..
Regards

jayshri 03-02-2012 01:03 AM

image processing
 
hi firstfire,

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<memory.h>
#include<math.h>
#include<float.h>
#include<string.h>
#define MAX_BRIGHTNESS 80
#define OUTPUT_FILE "out.bmp"
typedef char element;


long getImageInfo(FILE*,long,int);
void _medianfilter(element* image,element* result,int nCols,int nRows)
{
for(int m=1;m<nRows-1;++m)
for(int n=1;n<nCols-1;++n)
{
int k=0;
element window[9];
for(int j=m-1;j<m+2;++j)
for(int i=n-1;i<n+2;++i)
window[k++]=image[j*nCols+i];
for(int j=0;j<5;++j)
{
int min=j;
for(int l=j+1;l<9;++l)
if(window[l]<window[min])
min=l;
const element temp=window[j];
window[j]=window[min];
window[min]=temp;
result[(m-1)*(nCols)+n-1]=window[4];
}
}
}
void convolution(element *in,element *out,double *kernel,int nx,int ny,int kn)
{
int i,j,m,n,c;
int khalf=floor(kn/2.);
double pixel,min=DBL_MAX,max=DBL_MIN;
for(m=khalf;m<nx-khalf;n++)
{
pixel=0;
for(c=0,i=-khalf;i<=khalf;i++)
for(j=-khalf;j<=khalf;j++)
pixel+=in[(n-j)*nx+m-i]*kernel[c++];
if(pixel<min)min=pixel;
if(pixel>max)max=pixel;
}
for(m=khalf;m<nx-khalf;m++)
for(n=khalf;n<ny-khalf;n++)
{
pixel=0;
for(c=0,i=-khalf;i<=khalf;i++)
for(j=-khalf;j<=khalf;j++)
pixel+=in[(n-j)*nx+m-i]*kernel[c++];
pixel=MAX_BRIGHTNESS*(pixel-min)/(max-min);
out[n*nx+m]=(unsigned char)pixel;
}
}
void laplacian_filtering(element *in,element *out,int nx,int ny)
/* spatial filtering of image*/
/*8-neighbor Laplacian filter*/
/*input:image1[y][x]-Outout:image2[y][x]*/

/*Definition of 8-neighbour Laplacian filter*/
{
double kernel[]={1,1,1,
1,-8,1,
1,1,1};
convolution(in,out,kernel,nx,ny,3);
}
//double pixel_value;
//double min,max;
//int x,y,i,j;
/*Maximum values calculation after filtering*/
//printf("Now,filtering of input image is performed\n\n");
//min=DBL_MAX;
//max=DBL_MIN;
void gaussian_filter(element *in,element *out,int nx,int ny)
{
const int n=7;
int i,j, c=0;
double mean=floor(n/2.);
double sigma=1;
double kernel[n*n];
for(i=0;i<n;i++)
for(j=0;j<n;j++)

//for(y=1;y<y_size1-1;y++){
//for(x=1;x<x_size1-1;x++){
//pixel_value=0.0;
//for(j=-1;j<2;j++){
//for(i=-1;i<2;i++){
//pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j)+x+i];
//}
//}
//if(pixel_value<min)min=pixel_value;
//if(pixel_value>max)max=pixel_value;
//}
//}
//if((int)(max-min)==0){
//printf("Nothing exist!!!\n\n");
//exit(1);
//}
//initialization of image2[y][x]
//x_size2=x_size1;
//y_size2=y_size1;
//for(y=0;y<y_size2;y++){
//for(x=0;x<x_size2;x++){
//image2[y][x]=0;
//}
//}
//Generation of image 2 after linear transformation
//for(y=1;y<y_size1-1;y++){
//for(x=1;x<x_size1-1;x++){
//pixel_value=0.0;
//for(j=-1;j<2;j++){
//for(i=-1;i<2;i++){
//pixel_value+=weight[j+1][i+1]*image1[x_size1*(y+j)+x+i];
//}
//}
//pixel_value=MAX_BRIGHTNESS*(pixel_value-min)/(max-min);
//image2[y*x_size1+x]=(unsigned char)pixel_value;
//}
//}
//}
//double sigma=1;
//int W=5;
//double kernel[W][W];
//double mean=W/2;
//for(int x=0;x<W;++x)
//{
//for(int y=0;y<W;++y)
//{
kernel[c++]=exp(-0.5*(pow((i-mean)/sigma,2.0)+pow((j-mean)/sigma,2.0)))
/(2*M_PI*sigma*sigma); //error in this line
convolution(in,out,kernel,nx,ny,n);
}





int main(int argc,char *argv[])
{

FILE *bmpInput, *bmpOutput;
unsigned char *pixel,*result;
char signature[2];
long nRows,nCols,nbits;
long xpixpeRm,ypixpeRm;
long nColors;
long fileSize;
long vectorSize;
long nBits;
long rasterOffset;
int i, j,k,l,m;
unsigned char databuff[512][512][3];

if(argc<2)
{
printf("Usage: %s <median.bmp>\n",argv[0]);
exit(0);
}

//Open the specified input file for reading.
printf("Reading %s ...\n",argv[1]);
if((bmpInput = fopen(argv[1],"rb"))==NULL)
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}

//open output file.
if((bmpOutput = fopen(argv[2],"w+"))==NULL)
{
if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
{
printf("Cannot read %s \n", argv[1]);
exit(0);
}
}

//position the pointer to the beginning of the file.
fseek(bmpInput, 0L, SEEK_SET);

//read First two characters of the input file.
for(i=0; i<2; i++)
{
signature[i] = (char)getImageInfo(bmpInput,i,1);
}

//verify First two character of a BMP image file are BM
if((signature[0]=='B') && (signature[1]=='M'))
{
printf("It is verified that the image is in Bitmap format\n");
}
else
{
printf("The image is not a BMP format,quitting....\n");
exit(0);
}

//specifies number of bits per pixel in the image.
nBits = getImageInfo(bmpInput, 28, 2);
printf("The Image is \t%ld-bits per pixel. \n", nBits);

//offset from the begining of the file where the pixel data starts.
rasterOffset = getImageInfo(bmpInput,10,4);
printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

//size of the file in bytes.
fileSize=getImageInfo(bmpInput,2,4);
printf("File size is \t%ld byte\n",fileSize);

//number of columns in image.
nCols = getImageInfo(bmpInput,18,4);
printf("Width:\t\t%ld\n",nCols);

//number of rows in image.
nRows = getImageInfo(bmpInput,22,4);
printf("Height:\t%ld\n",nRows);


xpixpeRm = getImageInfo(bmpInput,38,4);
printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

ypixpeRm = getImageInfo(bmpInput,42,4);
printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

nColors = 1L<<nBits;
printf("There are \t%ld number of colors \n",nColors);

//it is the size of the array required to store the image pixel data.
vectorSize = nCols*nRows;
printf("vector Size is \t%ld\n",vectorSize);

//write the bmp header to the output file.
i = 0;
while(i < rasterOffset)
{
fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
i++;
}


//now declare an 2D array to store & manipulate the image pixel data.
pixel = (char *) calloc(sizeof(char)*nRows*nCols,sizeof(char));
result= (char *) calloc(sizeof(char)*nRows*nCols,sizeof(char));

//Set all the array value to zero.
printf("\n\nResetting the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = 0x00;
i++;
// printf("%d ", i);
}

//Read the bitmap data into array:
printf("\n\nReading the pixel array: ");
i = 0;
while(i < vectorSize)
{
pixel[i] = (char)getImageInfo(bmpInput,rasterOffset+ i, 1);
i++;
// printf("%d ", i);
}

//Display or modify pixel values:
printf("\n\n Diplaying pixel values: \n\n");
i = 0;
j = 0;
while(i < nRows)
{
j = 0;
while(j < nCols)
{
printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
j++;
}
i++;
}
if((nRows!=512)||(nCols!=512)||(nBits!=8)){
printf(" this works only for 512x512 8-color bitmaps\n");
return 0;
}

//int main(void)
//{
// enum {nCols=512,nRows=512};
// const float in[nCols*nRows];
// float out[nCols*nRows];
// median(out,in,nCols,nRows);
// printf("the filterd image is:\n");
// for (int i=0;i<nRows;i++)
//{
// for (int j=0;j<nCols;j++)
//{
// printf("%0.f",out[i*nCols+j]);
// printf("\n");
//}
//
//return 0;
_medianfilter(pixel,result,nCols,nRows);
//load_image_data();//input of image1
laplacian_filtering(result,pixel,nCols,nRows);//laplacian filtering is applied to image1
//save_image_data();//output of image2
//return 0;


//write the modified pixel array to the output file.
i = 0;
while(i < vectorSize)
{
fputc(pixel[i], bmpOutput);
i++;
}

//write the End-Of-File character the output file.
fputc(EOF, bmpOutput);

printf("\n");
fclose(bmpInput);
fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L, temp;
unsigned char dummy;
int i;

dummy = '0';
ptrC = &dummy;

//position the file pointer to the desired offset.
fseek(inputFile, offset, SEEK_SET);

//read the bytes into values (one byte at a time).
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC,sizeof(char),1,inputFile);
temp = *ptrC;
value = (long) (value + (temp<<(8*(i-1))));

}

return(value);
}



here is the code.. i have changed this code a bit according to the previous code u have posted.
every thing worked wel.
bt in the last part itz showing an error..
i haved marked the line with bold letters.
the error is undeclared M_PI.
Regards..:(

firstfire 03-02-2012 02:55 AM

Hi.

Constant M_PI defined in math.h header.

jayshri 03-02-2012 03:03 AM

image processing
 
hey i have included that header...
still itz showing same error

firstfire 03-02-2012 03:17 AM

Then add
Code:

#define M_PI 3.14159265358979323846
after includes.

jayshri 03-02-2012 03:32 AM

im
 
hi,
is there anything wrong in my code,,,because it is showing segmentation fault.......:(

jayshri 03-02-2012 03:40 AM

im
 
hi,,,it worked.thanks a lot....:)....will the output of laplacian and gaussian blur b the same??..we r getting the same output.....
reguards

firstfire 03-02-2012 04:34 AM

I don't get the question.

jayshri 03-02-2012 08:03 AM

im
 
hi,
the code worked. we got the output by modifyng the program with the codes that u hav posted..
In the codes that u have posted above the gaussian part was so easily represented that it didn't take me much time to understand..
is the code for other parts of canny edge detection avaiable any where..? actualy i need to do canny edge detection..
1st part i.e gaussian blur is done.
now i have left with gradient finding,non maximal suppresion and edge tracking hyteresis.
since i am very new in this field itz a bit difficult for me and the project submission day is also coming nearby..
Thanx 1nce again.. u hav helped me alot with ma project..
Regards.:)

jayshri 03-05-2012 01:23 AM

image processing
 
hi,
can any 1 suggest me the c code to find the gradient of an image????
i am nt getting any specific code to understand that...
Regards..


All times are GMT -5. The time now is 05:09 AM.