Digital Image Processing in C (Chapter 1): Mean and Median Filter
0. Complete Code
The complete code for this chapter: Chapter 1: Average Filter and Median Filter.
For more chapters on digital image processing and all the original images, see: Introduction to Digital Image Processing.
Please give my repository a star ⭐️ if you like it.
1. Mean Filter
Algorithm:
Input: An unsigned char array storing the source image data.
Output: An unsigned char array storing the output image data.
Every pixel in the image, except for those on the edges, is surrounded by eight pixels. The mean filter recalculates each pixel’s value by taking the average of these nine pixels (including the center one).
Image and Result Comparison (lena.pgm, noise.pgm):
Result Analysis:
Except for the image edges, the value of each pixel is replaced by the average of itself and the surrounding eight pixels. Therefore, the difference between all pixels is reduced, making the image look smoother. Clearly, this method reduces noise but also loses image details, resulting in a blurred image. It is suitable for eliminating Gaussian noise but not as effective for salt-and-pepper noise.
Code Implementation:
Image *AverageImage(Image *image) {
unsigned char *tempin, *tempout;
Image *outimage;
int size;
outimage = CreateNewImage(image, (char*)"#testing Average Filter");
tempin = image->data;
tempout = outimage->data;
if(image->Type == GRAY) size = image->Width * image->Height;
else if(image->Type == COLOR) size = image->Width * image->Height * 3;
for(int i = 1; i < image->Height-1; i++) {
for(int j = 1; j < image->Width-1; j++){
int sum = 0;
for(int x = -1; x <= 1; x++) {
for(int y = -1; y <= 1; y++) {
sum += tempin[(image->Width)*(i+x) + (j+y)];
}
}
tempout[(image->Width)*i + j] = sum/9;
}
}
return (outimage);
}
2. Median Filter
Algorithm:
Input: An unsigned char array storing the source image data.
Output: An unsigned char array storing the output image data.
Similar to the above, but each pixel’s value is replaced with the median of the nine-grid pixels, rather than the average. The values of the nine surrounding pixels are stored in an array, and sorting methods are used to find the median, which is then assigned to the pixel (i, j).
Image and Result Comparison (lena.pgm, noise.pgm):
Result Analysis:
Each pixel’s value is replaced by the median of itself and the eight surrounding pixels, reducing the difference between all pixels and smoothing the image. Compared to mean filtering, median filtering retains clearer object edges after noise reduction. It is suitable for eliminating salt-and-pepper noise but less effective for Gaussian noise.
Code Implementation:
Image *MedianImage(Image *image) {
unsigned char *tempin, *tempout, Sudoku[9];
Image *outimage;
int size;
outimage = CreateNewImage(image, (char*)"#testing Median Filter");
tempin = image->data;
tempout = outimage->data;
if(image->Type == GRAY) size = image->Width * image->Height;
else if(image->Type == COLOR) size = image->Width * image->Height * 3;
for(int i = 1; i < image->Height-1; i++) {
for(int j = 1; j < image->Width-1; j++){
int num = 0;
for(int x = -1; x <= 1; x++) {
for(int y = -1; y <= 1; y++) {
Sudoku[num++] = tempin[(image->Width)*(i+x) + (j+y)];
}
}
// Use Insertion Sort:
for(int m = 1; m < 9; m++) {
int currNum = Sudoku[m];
int n = m;
while(n >= 1 && Sudoku[n-1] > currNum) {
Sudoku[n] = Sudoku[n-1];
n--;
}
Sudoku[n] = currNum;
}
tempout[(image->Width)*i + j] = Sudoku[4];
}
}
return (outimage);
}
-END-