Noise Reduction and Edge Definition?

Hello, all!

I've dealt with these types of imaging terms before, yet I have no clue with how to implement them in a C++ program. In short, my supervisor assigned me a project where I would create a C++ program that reads an image file (.txt format), enhances it, and displays the image.

I'm supposed to enhance it with the two methods in the title, noise definition and edge reduction. My supervisor gave me very limited instructions for the program, so I'm feeling lost with creating the function.

If it helps, this is straight from my assignment sheet:

(image file)

7 5
1 2 3 4 5
2 3 9 4 5
3 2 9 2 1
4 9 9 9 1
5 1 9 2 1
6 7 9 3 3
1 1 1 1 1

(Instructions)
For this project you are asked to design, implement, debug and test a C++ program which will read in an image file (in text format), enhance it, and display the enhanced image on the screen. There will be two types of enhancements:

1. Noise Reduction – Reducing noise in a picture requires two steps. The first step is to determine whether the value in a particular location or pixel is noise. The second is to replace the noise with something more meaningful. In this problem, each pixel will contain a value from 0 to 9. A value will be considered noise if it differs from all eight of its neighbors by more than a cutoff value. To replace the noisy value, you should take the average (rounded to the nearest integer) of all the neighbors and use the result to replace the original value. The cutoff value should be an argument to the noise reduction function.
2. Edge Definition – To increase contrast requires lumping values which are close in intensity and replacing all these values with a single value. For example, you will replace {0, 1, 2} with 1, {3, 4, 5} with 4 and {6, 7, 8, 9} with 8.



This program will prompt the user to enter the name of the file. It will then open the file for input and read the data into a two-dimensional array. Display the raw data. Then perform noise reduction followed by edge definition. Display the enhanced image.
Other Notes:
1. For the noise reduction process:
a. the edges must be ignored because you don’t know what lies on at least one side.
b. the noise reduction should be carried out on the “raw” image
2. Maximum dimension of an image is 50 pixels by 80 pixels.
3. Modular design is important. Your program must have at least these programmer-defined functions:
a. reduceNoise - has four arguments: array, #rows, #columns, cutoff
b. defineEdge - has three arguments: array, #rows, #columns

This is what I've started with. As you can see, I'm held up on the different functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 #include "stdafx.h"
#include <iostream>
#include <fstream>

using namespace std;
const int MAXROWS = 50;
const int MAXCOLS = 80;
void display(int[][MAXCOLS], int, int);
int reduceNoise(int[][MAXCOLS], int, int, int);


int main()
{
	char fname[30];							// name of file is stored in a char array
		int image[MAXROWS][MAXCOLS];        // two-dimensional array of image data
		ifstream infile;                    // input file stream
	int n, m;								// actual dimensions of image array
		
	// What file does user want to see?
	cout << "Enter image file name: ";
	cin >> fname;

	// Check if file actually exists...
	infile.open(fname);
	if (!infile)
	{
		cerr << "File not found! Terminating program..." <<
			endl;
		exit(1);
	}
	// Extract image data from file
	infile >> n >> m;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			infile >> image[i][j];
		}
	}
	// Display the image array
	display(image, n, m);
	cout << endl;
	return 0;
}

void display(int a[][MAXCOLS], int r, int c)
{
	int i, j;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
			cout << a[i][j] << "\t";
		cout << endl;
	}
}

int reduceNoise(int a[][MAXCOLS], int x, int y, int cutoff)
{

}

int defineEdge(int a[][MAXCOLS], int b, int d)
{

}
Last edited on
Both terms are explained online with some searching.
noise reduction is usually some sort of 'if a pixel is surrounded by a solid color, make it that solid color' with maybe tolerances (might be, if the offending pixel is close in color or if surrounding are within tolerances, and so on)

edge enhancement is usually making edges a stronger color or making them wider so they stand out. There are a variety of edge detection algorithms, just pick one. Its looking for the pixel between 2 areas with distinct colors on opposite sides (could be left / right or top/bottom or even diagonal).

you are going to have to, in both cases, do a 3x3 (9 total pixels) check on each pixel in the image and handle the image boarders so you don't go out of bounds.



Last edited on
Well, here's a possible outline for one of those functions. You can take it or leave it and fill in the gaps.

Note that, with your given image file and definition of 'noisy', only one point is likely to be regarded as noisy (the 1 in the third row from the bottom), and then only if cutoff=1.

For your second function you need to query this with your teacher. I (personally) think that
replace ... {6, 7, 8, 9} with 8
is ambiguous (why 8, not 7? why 4 points?).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void reduceNoise( int a[MAXROWS][MAXCOLS], int rows, int cols, int cutoff )
{
   // Create a work array
   int working[MAXROWS][MAXCOLS];                // Set up a work array

   // Set the INTERNAL points only of the work array by checking if noise and averaging points in a[][]
   for ( int i = 1; i < rows - 1; i++ )
   {                                   
      for ( int j = 1; j < cols - 1; j++ )
      {
         // You will need to consider, for point a[i][j]:
         // (i) Is it noise? This depends on cutoff and all EIGHT surrounding points
         // (ii) If it is noise then 
         //          working[i][j] = (rounded) average of all eight surrounding nodes
         //      Otherwise
         //          working[i][j] = a[i][j];
         //
         // e.g.
         //    mindiffer = ... (involving looping through all neighbours)
         //    if ( mindiffer > cutoff ) 
         //    {
         //       average = ... 
         //       working[i][j] = ...
         //    }
         //    else
         //    {
         //       working[i][j] = ...
         //    }
      }
   }


   // Now copy back the work array (INTERNAL points only) into a[][]; boundaries aren't changed
   for ( int i = 1; i < rows - 1; i++ )   
   {                                      
      for ( int j = 1; j < cols - 1; j++ ) a[i][j] = working[i][j];
   }
}
Last edited on
Topic archived. No new replies allowed.