This is a follow-up question for Image Processing Median Filter in C. Under the same tiny bmp image read / write framework, a sobel edge detection function has been performed.
The experimental implementation
The basic structures:
typedef struct RGB { unsigned char R, G, B; } RGB; typedef struct BMPIMAGE { char FILENAME[MAX_PATH]; unsigned int XSIZE; unsigned int YSIZE; unsigned char FILLINGBYTE; unsigned char *IMAGE_DATA; } BMPIMAGE; typedef struct RGBIMAGE { unsigned int XSIZE; unsigned int YSIZE; RGB *IMAGE_DATA; } RGBIMAGE;
SobelEdge
function implementation:RGB *SobelEdge(const int xsize, const int ysize, const RGB * const image) { RGB *output; output = malloc(xsize * ysize * sizeof(RGB)); if (output == NULL) { printf("Memory allocation error!"); return NULL; } for(long long int i = 0; i < (xsize * ysize); i++) { if( (i < xsize) || ( (i % xsize) == 0) || ( ((i + 1) % xsize) == 0) || (i >= (xsize*(ysize-1)))) { output[i].R = image[i].R; output[i].G = image[i].G; output[i].B = image[i].B; } else { int Gx = 0, Gy = 0; Gx = ( image[i+xsize-1].R * (-1) + image[i+xsize].R * 0 + image[i+xsize+1].R * 1 + image[i-1].R * (-2) + image[i].R * 0 + image[i+1].R * 2 + image[i-xsize-1].R * (-1) + image[i-xsize].R * 0 + image[i-xsize+1].R * 1 ); Gy = ( image[i+xsize-1].R * (-1) + image[i+xsize].R * (-2) + image[i+xsize+1].R * (-1) + image[i-1].R * 0 + image[i].R * 0 + image[i+1].R * 0 + image[i-xsize-1].R * 1 + image[i-xsize].R * 2 + image[i-xsize+1].R * 1 ); long double magnitude, direction; magnitude = sqrt(pow(Gx, 2) + pow(Gy, 2)); if(Gx > 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)90; } else if(Gx < 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)270; } else if( (Gx == 0) && (Gy > 0) ) { direction = 90; } else if( (Gx == 0) && (Gy < 0) ) { direction = -90; } else if( (Gx == 0) && (Gy == 0) ) { direction = 0; } output[i].R = (magnitude > 255)?255:(magnitude < 0)?0:(unsigned char)magnitude; Gx = ( image[i+xsize-1].G * (-1) + image[i+xsize].G * 0 + image[i+xsize+1].G * 1 + image[i-1].G * (-2) + image[i].G * 0 + image[i+1].G * 2 + image[i-xsize-1].G * (-1) + image[i-xsize].G * 0 + image[i-xsize+1].G * 1 ); Gy = ( image[i+xsize-1].G * (-1) + image[i+xsize].G * (-2) + image[i+xsize+1].G * (-1) + image[i-1].G * 0 + image[i].G * 0 + image[i+1].G * 0 + image[i-xsize-1].G * 1 + image[i-xsize].G * 2 + image[i-xsize+1].G * 1 ); magnitude = sqrt(pow(Gx, 2) + pow(Gy, 2)); if(Gx > 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)90; } else if(Gx < 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)270; } else if( (Gx == 0) && (Gy > 0) ) { direction = 90; } else if( (Gx == 0) && (Gy < 0) ) { direction = -90; } else if( (Gx == 0) && (Gy == 0) ) { direction = 0; } output[i].G = (magnitude > 255)?255:(magnitude < 0)?0:(unsigned char)magnitude; Gx = ( image[i+xsize-1].B * (-1) + image[i+xsize].B * 0 + image[i+xsize+1].B * 1 + image[i-1].B * (-2) + image[i].B * 0 + image[i+1].B * 2 + image[i-xsize-1].B * (-1) + image[i-xsize].B * 0 + image[i-xsize+1].B * 1 ); Gy = ( image[i+xsize-1].B * (-1) + image[i+xsize].B * (-2) + image[i+xsize+1].B * (-1) + image[i-1].B * 0 + image[i].B * 0 + image[i+1].B * 0 + image[i-xsize-1].B * 1 + image[i-xsize].B * 2 + image[i-xsize+1].B * 1 ); magnitude = sqrt(pow(Gx, 2) + pow(Gy, 2)); if(Gx > 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)90; } else if(Gx < 0) { direction = atan((long double)Gy / (long double)Gx) * ( 180 / M_PI) + (long double)270; } else if( (Gx == 0) && (Gy > 0) ) { direction = 90; } else if( (Gx == 0) && (Gy < 0) ) { direction = -90; } else if( (Gx == 0) && (Gy == 0) ) { direction = 0; } output[i].B = (magnitude > 255)? 255: (magnitude < 0)?0:(unsigned char)magnitude; } } return output; }
Input Image:
Output Image:
All suggestions are welcome.
The summary information:
Which question it is a follow-up to?
What changes has been made in the code since last question?
Besides creating
MedianFilter33
function, the function for sobel edge detection is the main part here.Why a new review is being asked for?
If there is any possible improvement, please let me know.