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/)

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

jayshri 03-05-2012 03:05 AM

image processing
 
hi firstfire,
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<memory.h>
#include<float.h>
#include<math.h>
//#include<alloc.h>
#define M_PI 3.14159265358979323846
#define MAX_BRIGHTNESS 80
#define OUTPUT_FILE "out.bmp"
typedef char element;
//typedef struct{int nRows;int nCols;unsigned char* data;}sImage;


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;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_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.), 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);
}

typedef struct{int nRows;int nCols;unsigned char* data;}sImage;



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

FILE *bmpInput, *bmpOutput;
unsigned char *pixel,*result;
sImage originalImage;
sImage edgeImage;
char signature[2];
long nRows,nCols,nbits;
long xpixpeRm,ypixpeRm;
long nColors;
long fileSize;
long vectorSize;
int GX[3][3];
int GY[3][3];
long nBits;
long rasterOffset;
int i, j,k,l,m,x,y,SUM;
long sumx,sumy;
unsigned char databuff[512][512][3];
//3X3 GX Sobel mask.
GX[0][0]=-1; GX[0][1]=0; GX[0][2]=1;
GX[1][0]=-2; GX[1][1]=0; GX[1][2]=2;
GX[2][0]=-1; GX[2][1]=0; GX[2][2]=1;
//3X3 GY Sobel mask
GY[0][0]=1; GY[0][1]=2; GY[0][2]=1;
GY[1][0]=0; GY[1][1]=0; GY[1][2]=0;
GY[2][0]=-1;GY[2][1]=-2;GY[2][2]=-1;

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;
}

_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;

//sobel algorithm starts here
for(y=0;y<=(originalImage.nRows-1);y++){
for(x=0;x<=(originalImage.nCols-1);x++){
sumx=0;
sumy=0;
//image boudaries
if(y==0||y==originalImage.nRows-1)
SUM=0;
else if(x==0||x==originalImage.nCols-1)
SUM=0;
//Convolution starts here
else {
//X Gradient approximation
for(i=1;i<=1;i++){
for(j=-1;j<=1;j++){
sumx=sumx+(int)((*(originalImage.data+x+i+(y+j)*originalImage.nCols))*GX [i+1][j+1]);
}
}
//Y Gradient approximation
for(i=-1;i<=1;i++){
for(j=-1;j<=1;j++){
sumy=sumy+(int)((*(originalImage.data+x+i+(y+j)*originalImage.nCols))*GY[i+1][j+1]);
}
}
//gradient magnitude approximation
SUM=abs(sumx)+abs(sumy);
}
if(SUM>255) SUM=255;
if(SUM<0) SUM=0;
*(edgeImage.data+x+y*originalImage.nCols)=255-(unsigned char)(SUM);
fwrite((edgeImage.data+x+y*originalImage.nCols),sizeof(char),1,bmpOutput);
}
}
//write the modified pixel array to the output file
i=0;
while(i<vectorSize)
{fputc(pixel[i],bmpOutput);
i++;
}
printf("see median.bmp for result\n");
//write the End-Of-File character the output file.
fputc(EOF, bmpOutput);

printf("\n");
fclose(bmpInput);
fclose(bmpOutput);
farfree(edgeImage.data);//finished with edgeImage.data//error
farfree(originalImage.data);//finished with original image.data//error
return 0;
}

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 have writtn the code merged with the previous code..
itz for gradient finding..
however itz givng a error undefined refrence to "farfree".
is there any other command that can be used instead of "farfree"
is der any more modification neede.
Regards..:(

jayshri 03-05-2012 03:07 AM

i have marked the error with bold front..

firstfire 03-05-2012 05:04 AM

Hi.

I think you can use `free()' instead of `farfree()'.

jayshri 03-05-2012 05:11 AM

im
 
hi,
that error gt removed..
bt when i run the program itz showing segmentation fault..
can u plz tell me where is the fault..
regards..:(

firstfire 03-05-2012 11:32 AM

Hi.

None field of originalImage and edgeImage are initialized, hence the segfault. I just finished this page. You can use the code for reference. Here is the program for Canny edge detection from that page.
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;

BITMAPINFOHEADER ih;

// Use int instead `unsigned char' so that
// we can store negative values.
typedef int pixel_t;

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

        filePtr = fopen(filename,"r");
        if (filePtr == NULL)
        {
                perror("fopen()");
                exit(1);
        }

        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 = (pixel_t *)malloc(bitmapInfoHeader->bmp_bytesz*(sizeof(pixel_t)));

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

        //read in the bitmap image data
        int i;
        unsigned char c;
        for(i=0; i<bitmapInfoHeader->bmp_bytesz; i++){
                fread(&c, sizeof(unsigned char), 1, filePtr);
                bitmapImage[i] = (int) c;
        }

        // If we were using unsigned char as pixel_t, then:
        //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, pixel_t *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);
        }

        // We use int instead of uchar, so we can't write img in 1 call any more.
        //fwrite(data, 1, bmp_ih->bmp_bytesz, fp);
        unsigned char c;
        for(i=0; i<bmp_ih->bmp_bytesz; i++){
                c = (unsigned char) data[i];
                fwrite(&c, sizeof(unsigned char), 1, fp);
        }

        fclose(fp);
        return 0;
}

// if norm==1, map pixels to range 0..MAX_BRIGHTNESS
void convolution(pixel_t *in, pixel_t *out, float *kernel, int nx, int ny, int kn, int norm)
{
        int i, j, m, n, c;
        int khalf = floor(kn/2.);
        float pixel, min=DBL_MAX, max=DBL_MIN;

        if(norm)
        for(m=khalf; m<nx-khalf; m++)
                for(n=khalf; n<ny-khalf; n++)
                {
                        pixel = 0;
                        c = 0;
                        for(j=-khalf; j<=khalf; j++)
                                for(i=-khalf; i<=khalf; i++)
                                        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;
                        c = 0;
                        for(j=-khalf; j<=khalf; j++)
                                for(i=-khalf; i<=khalf; i++)
                                        pixel += in[(n-j)*nx + m-i]*kernel[c++];

                        if(norm) pixel = MAX_BRIGHTNESS*(pixel-min)/(max-min);
                        out[n*nx + m] = (pixel_t) pixel;
                }
}

// http://www.songho.ca/dsp/cannyedge/cannyedge.html
// determine size of kernel (odd #)
// 0.0 <= sigma < 0.5 : 3
// 0.5 <= sigma < 1.0 : 5
// 1.0 <= sigma < 1.5 : 7
// 1.5 <= sigma < 2.0 : 9
// 2.0 <= sigma < 2.5 : 11
// 2.5 <= sigma < 3.0 : 13 ...
//kernelSize = 2 * int(2*sigma) + 3;

void gaussian_filter(pixel_t *in, pixel_t *out, int nx, int ny, float sigma)
{
        int i, j, c=0;
        const int n = 2*(int)(2*sigma) + 3;
        float        mean = floor(n/2.);
        float        kernel[n*n];
        fprintf(stderr, "gaussian_filter: kernel size %d, sigma=%g\n", n, sigma);
        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, 1);
}

/*
 * Links:
 * http://en.wikipedia.org/wiki/Canny_edge_detector
 * http://www.tomgibara.com/computer-vision/CannyEdgeDetector.java
 * http://fourier.eng.hmc.edu/e161/lectures/canny/node1.html
 * http://www.songho.ca/dsp/cannyedge/cannyedge.html
 *
 * Note: T1 and T2 are lower and upper thresholds.
 */
void canny_edge_detection(pixel_t *in, pixel_t *out, int nx, int ny, int tmin, int tmax, float sigma)
{
        int i, j, c, Gmax;
        int counter = 0;
        float dir;
        float Gx[]={
                -1,0,1,
                -2,0,2,
                -1,0,1};
        float Gy[]={
                1,2,1,
                0,0,0,
                -1,-2,-1};

        pixel_t        *G        = calloc(nx*ny*sizeof(pixel_t), 1),
                *after_Gx = calloc(nx*ny*sizeof(pixel_t), 1),
                *after_Gy = calloc(nx*ny*sizeof(pixel_t), 1),
                *nms          = calloc(nx*ny*sizeof(pixel_t), 1);

        gaussian_filter(in, out, nx, ny, sigma);

        convolution(out, after_Gx, Gx, nx, ny, 3, 0);
        convolution(out, after_Gy, Gy, nx, ny, 3, 0);

        for(i=1; i<nx-1; i++)
                for(j=1; j<ny-1; j++)
                {
                        c = i + nx*j;
                        //G[c] = abs(after_Gx[c]) + abs(after_Gy[c]);
                        G[c] = hypot(after_Gx[c], after_Gy[c]);
                        if (G[c]>Gmax ) Gmax = G[c];
                }

        int nn,ss,ww,ee,nw,ne,sw,se;
        // Non-maximum suppression, straightforward implementation.
        for(i=1; i<nx-1; i++)
                for(j=1; j<ny-1; j++)
                {
                        c = i + nx*j;
                        nn = c - nx;
                        ss = c + nx;
                        ww = c + 1;
                        ee = c - 1;
                        nw = nn + 1;
                        ne = nn - 1;
                        sw = ss + 1;
                        se = ss - 1;

                        dir = atan2(after_Gy[c], after_Gx[c]) * 8.0/M_PI;

                        if( (( fabs(dir)<=1 || fabs(fabs(dir)-8)<=1 ) && G[c] > G[ee] && G[c] > G[ww])        /* 0 deg */
                                ||
                                (( fabs(dir-2)<=1 || fabs(dir+6)<=1 )  && G[c] > G[nw] && G[c] > G[se])                /* 45 deg */
                                ||
                                (( fabs(fabs(fabs(dir)-4))<=1 )  && G[c] > G[nn] && G[c] > G[ss])                /* 90 deg */
                                ||
                                (( fabs(dir-6)<=1 || fabs(dir+2)<=1 )  && G[c] > G[ne] && G[c] > G[sw])                /* 135 deg */
                            )
                                nms[c] = G[c];
                        else
                                nms[c] = 0;
                }
        // Reuse array
        pixel_t *edges        = after_Gy;        // used as a stack
        memset(out, 0, sizeof(pixel_t)*nx*ny);
        memset(edges, 0, sizeof(pixel_t)*nx*ny);
        int nedges, k, t;
        int nbs[8];        // neighbours

        counter = 0;
        // Tracing edges with hysteresis . Non-recursive implementation.
        for(c=1, j=1; j<ny-1; j++)
                for(i=1; i<nx-1; i++)
                {
                        if( nms[c] >= tmax && out[c] == 0 )        // trace edges
                        {
                                out[c] = MAX_BRIGHTNESS;
                                nedges = 1;
                                edges[0] = c;

                                do{
                                        nedges--;
                                        t = edges[ nedges ];

                                        nbs[0] = t - nx;        // nn
                                        nbs[1] = t + nx;        // ss
                                        nbs[2] = t + 1;                // ww
                                        nbs[3] = t - 1;                // ee
                                        nbs[4] = nbs[0] + 1;        // nw
                                        nbs[5] = nbs[0] - 1;        // ne
                                        nbs[6] = nbs[1] + 1;        // sw
                                        nbs[7] = nbs[1] - 1;        // se

                                        for(k=0; k<8; k++)
                                                if( nms[ nbs[k] ] >= tmin && out[ nbs[k] ] == 0 )
                                                {
                                                        out[ nbs[k] ] = MAX_BRIGHTNESS;
                                                        edges[nedges++] = nbs[k];
                                                }
                                } while( nedges > 0 );
                        }
                        c++;
                }
        free(after_Gx);
        free(after_Gy);
        free(G);
        free(nms);
}

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

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

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

        canny_edge_detection(bitmap_data, temp_image, ih.width, ih.height, 45, 50, 1);

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

Note that it is my first programs on image processing, so there may be bugs etc.

Hope that helps.

jayshri 03-06-2012 02:49 AM

image processing
 
hi...
first fire
thanx 4 d code..:)
i hav used the code u have posted wid my program...
bt i am facing some problem in calling the canny edge function in the main() part.
I am marking that part with bold letters.
can u help me out wid dat???
Code:

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<memory.h>
#include<float.h>
#include<math.h>
//#include<alloc.h>
#define M_PI 3.14159265358979323846
#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 norm)
{
int i,j,m,n,c;
int khalf=floor(kn/2.);
double pixel,min=DBL_MAX,max=DBL_MIN;
if(norm)
        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++];
        if(norm)        pixel=MAX_BRIGHTNESS*(pixel-min)/(max-min);
                out[n*nx+m]=(element)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,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;
void gaussian_filter(element *in,element *out,int nx,int ny,double sigma)
{
const int n=2*(int)(2*sigma)+3;
int i,j, c=0;
double mean=floor(n/2.);
double kernel[n*n];
fprintf(stderr,"gaussian_filter:kernel size %d,sigma=%g\n",n,sigma);
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,1);
}

//canny edge detection starts here
void canny_egde_detection(element *in,element *out,int nx,int ny,int tmin,int tmax,double sigma)
{
int i,j,c,Gmax;
int counter=0;
double dir;
double Gx[]={
        -1,0,1,
        -2,0,2,
        -1,0,1};
double Gy[]={
        1,2,1,
        0,0,0,
        -1,-2,-1};
element *G=calloc(nx*ny*sizeof(element),1),
        *after_Gx=calloc(nx*ny*sizeof(element),1),
        *after_Gy=calloc(nx*ny*sizeof(element),1),
        *nms=calloc(nx*ny*sizeof(element),1);
        gaussian_filter(in,out,nx,ny,sigma);
        convolution(out,after_Gx,Gx,nx,ny,3,0);
        convolution(out,after_Gy,Gy,nx,ny,3,0);
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
G[c]=hypot(after_Gx[c],after_Gy[c]);
if(G[c]>Gmax)Gmax=G[c];
}
int nn,ss,ww,ee,nw,ne,sw,se;
//Non-maximum suppresion,straightforward implemention.
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
nn=c-nx;
ss=c+nx;
ww=c+1;
ee=c-1;
nw=nn+1;
ne=nn-1;
sw=ss+1;
se=ss-1;
dir=atan2(after_Gy[c],after_Gx[c])*8.0/M_PI;
if(((fabs(dir)<=1||fabs(fabs(dir)-8)<=1)&& G[c]>G[c]>G[ww])//0 degree
||
((fabs(dir-2)<=1||fabs(dir+6)<=1)&& G[c]>G[nw]&& G[c]>G[se])//45 degree
||
((fabs(fabs(fabs(dir)-4))<=1) &&G[c]>G[nn] &&G[c]>G[ss]) //90 degree
||
((fabs(dir-6)<=1||fabs(dir+2)<=1)&&G[c]>G[ne]&& G[c]>G[sw])//135 degree
)
nms[c]=G[c];
else
nms[c]=0;
}

//Reuse array
element *edges=after_Gy;
memset(out,0,sizeof(element)*nx*ny);
memset(edges,0,sizeof(element)*nx*ny);
int nedges,k,t;
int nbs[8];
counter=0;
//Tracking edge with hyteresis.Non-recursive implementation
for(c=1,j=1;j<ny-1;j++)
        for(i=1;i<nx-1;i++)
{
if(nms[c]>=tmax && out[c]==0)
{
out[c]=MAX_BRIGHTNESS;
nedges=1;
edges[0]=c;
do{
nedges--;
t=edges[nedges];
nbs[0]=t-nx; //nn
nbs[1]=t+nx;//ss
nbs[2]=t+1;//ww
nbs[3]=t-1;//ee       
nbs[4]=nbs[0]+1;//nw
nbs[5]=nbs[1]-1;//ne
nbs[6]=nbs[1]+1;//sw
nbs[7]=nbs[1]-1;//se
for(k=0;k<8;k++)
if(nms[nbs[k]]>=tmin && out[nbs[k]]==0)
{
out[nbs[k]]=MAX_BRIGHTNESS;
edges[nedges++]=nbs[k];
}
}while(nedges>0);
}
c++;
}
free(after_Gx);
free(after_Gy);
free(G);
free(nms);
}
       

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,x,y;
        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;
}

_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;
//element *in,*out;
//in=load_bmp(argv[1],&ih);
//out=(element*)malloc(ih.bmp_bytesz*sizeof(element));
//printf("Info:%d x %d x \n",ih.nCols,ih.nRows,ih.nBits);
canny_edge_detection(in,out,nRows,nCols,45,50,1);[having problem here
free(in);
free(out);
return 0;

       

//write the modified pixel array to the output file
i=0;
while(i<vectorSize)
{fputc(pixel[i],bmpOutput);
i++;
}
printf("see median.bmp for result\n");
        //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);
}

thank u
regards..

jayshri 03-11-2012 03:05 AM

im
 
hi firstfire,
i have tried the code ..
itz working wel... but i am nt able to call the canny edge function in the main() part.
that why while showing the output itz only doing gaussin blur.
can u plz tel me where m getting worng???
here is the code
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<memory.h>
#include<float.h>
#include<math.h>
//#include<alloc.h>
#define M_PI 3.14159265358979323846
#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 norm)
{
int i,j,m,n,c;
int khalf=floor(kn/2.);
double pixel,min=DBL_MAX,max=DBL_MIN;
if(norm)
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++];
if(norm) pixel=MAX_BRIGHTNESS*(pixel-min)/(max-min);
out[n*nx+m]=(element)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,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;
void gaussian_filter(element *in,element *out,int nx,int ny,double sigma)
{
const int n=2*(int)(2*sigma)+3;
int i,j, c=0;
double mean=floor(n/2.);
double kernel[n*n];
fprintf(stderr,"gaussian_filter:kernel size %d,sigma=%g\n",n,sigma);
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,1);
}

//canny edge detection starts here
void canny_egde_detection(element *in,element *out,int nx,int ny,int tmin,int tmax,double sigma)
{
int i,j,c,Gmax;
int counter=0;
double dir;
double Gx[]={
-1,0,1,
-2,0,2,
-1,0,1};
double Gy[]={
1,2,1,
0,0,0,
-1,-2,-1};
element *G=calloc(nx*ny*sizeof(element),1),
*after_Gx=calloc(nx*ny*sizeof(element),1),
*after_Gy=calloc(nx*ny*sizeof(element),1),
*nms=calloc(nx*ny*sizeof(element),1);
gaussian_filter(in,out,nx,ny,sigma);
convolution(out,after_Gx,Gx,nx,ny,3,0);
convolution(out,after_Gy,Gy,nx,ny,3,0);
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
G[c]=hypot(after_Gx[c],after_Gy[c]);
if(G[c]>Gmax)Gmax=G[c];
}
int nn,ss,ww,ee,nw,ne,sw,se;
//Non-maximum suppresion,straightforward implemention.
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
nn=c-nx;
ss=c+nx;
ww=c+1;
ee=c-1;
nw=nn+1;
ne=nn-1;
sw=ss+1;
se=ss-1;
dir=atan2(after_Gy[c],after_Gx[c])*8.0/M_PI;
if(((fabs(dir)<=1||fabs(fabs(dir)-8)<=1)&& G[c]>G[c]>G[ww])//0 degree
||
((fabs(dir-2)<=1||fabs(dir+6)<=1)&& G[c]>G[nw]&& G[c]>G[se])//45 degree
||
((fabs(fabs(fabs(dir)-4))<=1) &&G[c]>G[nn] &&G[c]>G[ss]) //90 degree
||
((fabs(dir-6)<=1||fabs(dir+2)<=1)&&G[c]>G[ne]&& G[c]>G[sw])//135 degree
)
nms[c]=G[c];
else
nms[c]=0;
}

//Reuse array
element *edges=after_Gy;
memset(out,0,sizeof(element)*nx*ny);
memset(edges,0,sizeof(element)*nx*ny);
int nedges,k,t;
int nbs[8];
counter=0;
//Tracking edge with hyteresis.Non-recursive implementation
for(c=1,j=1;j<ny-1;j++)
for(i=1;i<nx-1;i++)
{
if(nms[c]>=tmax && out[c]==0)
{
out[c]=MAX_BRIGHTNESS;
nedges=1;
edges[0]=c;
do{
nedges--;
t=edges[nedges];
nbs[0]=t-nx; //nn
nbs[1]=t+nx;//ss
nbs[2]=t+1;//ww
nbs[3]=t-1;//ee
nbs[4]=nbs[0]+1;//nw
nbs[5]=nbs[1]-1;//ne
nbs[6]=nbs[1]+1;//sw
nbs[7]=nbs[1]-1;//se
for(k=0;k<8;k++)
if(nms[nbs[k]]>=tmin && out[nbs[k]]==0)
{
out[nbs[k]]=MAX_BRIGHTNESS;
edges[nedges++]=nbs[k];
}
}while(nedges>0);
}
c++;
}
free(after_Gx);
free(after_Gy);
free(G);
free(nms);
}


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,x,y;
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;
}

_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;
//element *in,*out;
//in=load_bmp(argv[1],&ih);
//out=(element*)malloc(ih.bmp_bytesz*sizeof(element));
//printf("Info:%d x %d x \n",ih.nCols,ih.nRows,ih.nBits);
canny_edge_detection(in,out,nRows,nCols,45,50,1);[having problem here
free(in);
free(out);
return 0;



//write the modified pixel array to the output file
i=0;
while(i<vectorSize)
{fputc(pixel[i],bmpOutput);
i++;
}
printf("see median.bmp for result\n");
//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))));
kindly help me wid dis..
Regards..;(

firstfire 03-11-2012 07:46 AM

Hi.

What errors do you have?

jayshri 03-11-2012 08:18 AM

hi,
actualy i am not able to call d function in the main part... like u have told me before about (median -pixel,result) nd (laplacian-result,pixel)..likewise wat wil b for canny edge..i have post the program before.. since i am unable to call d canny function itz nt priting the resulting image after applying canny edge.. itz only showing d picture after applying gaussian blur

jayshri 03-11-2012 08:23 AM

Code:

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<memory.h>
#include<float.h>
#include<math.h>
//#include<alloc.h>
#define M_PI 3.14159265358979323846
#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 norm)
{
int i,j,m,n,c;
int khalf=floor(kn/2.);
double pixel,min=DBL_MAX,max=DBL_MIN;
if(norm)
        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++];
        if(norm)        pixel=MAX_BRIGHTNESS*(pixel-min)/(max-min);
                out[n*nx+m]=(element)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,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;
void gaussian_filter(element *in,element *out,int nx,int ny,double sigma)
{
const int n=2*(int)(2*sigma)+3;
int i,j, c=0;
double mean=floor(n/2.);
double kernel[n*n];
fprintf(stderr,"gaussian_filter:kernel size %d,sigma=%g\n",n,sigma);
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,1);
}

//canny edge detection starts here
void canny_egde_detection(element *in,element *out,int nx,int ny,int tmin,int tmax,double sigma)
{
int i,j,c,Gmax;
int counter=0;
double dir;
double Gx[]={
        -1,0,1,
        -2,0,2,
        -1,0,1};
double Gy[]={
        1,2,1,
        0,0,0,
        -1,-2,-1};
element *G=calloc(nx*ny*sizeof(element),1),
        *after_Gx=calloc(nx*ny*sizeof(element),1),
        *after_Gy=calloc(nx*ny*sizeof(element),1),
        *nms=calloc(nx*ny*sizeof(element),1);
        gaussian_filter(in,out,nx,ny,sigma);
        convolution(out,after_Gx,Gx,nx,ny,3,0);
        convolution(out,after_Gy,Gy,nx,ny,3,0);
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
G[c]=hypot(after_Gx[c],after_Gy[c]);
if(G[c]>Gmax)Gmax=G[c];
}
int nn,ss,ww,ee,nw,ne,sw,se;
//Non-maximum suppresion,straightforward implemention.
for(i=1;i<nx-1;i++)
for(j=1;j<ny-1;j++)
{
c=i+nx*j;
nn=c-nx;
ss=c+nx;
ww=c+1;
ee=c-1;
nw=nn+1;
ne=nn-1;
sw=ss+1;
se=ss-1;
dir=atan2(after_Gy[c],after_Gx[c])*8.0/M_PI;
if(((fabs(dir)<=1||fabs(fabs(dir)-8)<=1)&& G[c]>G[c]>G[ww])//0 degree
||
((fabs(dir-2)<=1||fabs(dir+6)<=1)&& G[c]>G[nw]&& G[c]>G[se])//45 degree
||
((fabs(fabs(fabs(dir)-4))<=1) &&G[c]>G[nn] &&G[c]>G[ss]) //90 degree
||
((fabs(dir-6)<=1||fabs(dir+2)<=1)&&G[c]>G[ne]&& G[c]>G[sw])//135 degree
)
nms[c]=G[c];
else
nms[c]=0;
}

//Reuse array
element *edges=after_Gy;
memset(out,0,sizeof(element)*nx*ny);
memset(edges,0,sizeof(element)*nx*ny);
int nedges,k,t;
int nbs[8];
counter=0;
//Tracking edge with hyteresis.Non-recursive implementation
for(c=1,j=1;j<ny-1;j++)
        for(i=1;i<nx-1;i++)
{
if(nms[c]>=tmax && out[c]==0)
{
out[c]=MAX_BRIGHTNESS;
nedges=1;
edges[0]=c;
do{
nedges--;
t=edges[nedges];
nbs[0]=t-nx; //nn
nbs[1]=t+nx;//ss
nbs[2]=t+1;//ww
nbs[3]=t-1;//ee       
nbs[4]=nbs[0]+1;//nw
nbs[5]=nbs[1]-1;//ne
nbs[6]=nbs[1]+1;//sw
nbs[7]=nbs[1]-1;//se
for(k=0;k<8;k++)
if(nms[nbs[k]]>=tmin && out[nbs[k]]==0)
{
out[nbs[k]]=MAX_BRIGHTNESS;
edges[nedges++]=nbs[k];
}
}while(nedges>0);
}
c++;
}
free(after_Gx);
free(after_Gy);
free(G);
free(nms);
}
       

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,x,y;
        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;
}

_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;
//element *in,*out;
//in=load_bmp(argv[1],&ih);
//out=(element*)malloc(ih.bmp_bytesz*sizeof(element));
//printf("Info:%d x %d x \n",ih.nCols,ih.nRows,ih.nBits);
canny_edge_detection(in,out,nRows,nCols,45,50,1);//HERE HAVING PROBLEM IN DECLARING D CANNY EDGE PART
free(in);
free(out);
return 0;

       

//write the modified pixel array to the output file
i=0;
while(i<vectorSize)
{fputc(pixel[i],bmpOutput);
i++;
}
printf("see median.bmp for result\n");
        //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 have attached d program and marked d place i am having prblem wid bold letters.
regard..


All times are GMT -5. The time now is 07:09 PM.