Digital Image Processing in C (Chapter 1): Mean and Median Filter

Zhe LIN
4 min readNov 15, 2023

--

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.

A 9x9 Convolutional Kernel

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-

--

--

Zhe LIN

Zhe studied Computer Science in Hong Kong and is currently pursuing a Master degree in the United States. Really hope my article is helpful to you!