The first method: Gaussian template
The following text copy of the << Digital Image processing Programming primer >>,code for their own implementation, is the Win32 console program.
Let me give you an example of what smoothing is (smoothing), as shown in the following two images: As you can see, Figure 3.2 is softer (and more obscure) than figure 3.1. Does it feel magical. In fact, the implementation is very simple. We add the grayscale of each point in the original image and the gray level of the eight dots around it, then divide by 9, as the grayscale of the corresponding point in the new graph, to achieve the above effect.
This is not blind, but there is a reason for it. Think about it and it's easy to understand. For example, like face and face, first add water in the middle, and then keep the surrounding surface and come in, stirring several times, the surface evenly.
It is explained by the theory of signal processing that this approach achieves a simple low pass filter. Wow, that's so abstruse. It doesn't matter, these theories are not much content, and it is good to know some theories. In gray-scale continuous changes in the image, if there is a large difference between the gray level of neighboring pixels, such as a dark area suddenly appeared a bright spot, the human eye can be easily detected. It is like watching old movies, because the film is too old, there are often some bright spots on the screen. This is considered to be a kind of noise. The gray-scale mutation represents a high-frequency component in the frequency domain, and the function of the low-pass filter is to filter out the high-frequency component so as to reduce the image noise.
In order to conveniently describe what is said above, "add the grayscale of each point in the original image and the grayscale of the eight points around it, then divide by 9, as the grayscale of the corresponding point in the new graph", we use the following notation:
(3.1)
This representation is a bit like a matrix, which we call a template. The middle black point represents the central element, that is, which element is used as the treated element. For example [2.1] means twice times the value of itself plus the element on the right as the new values, and [2 1.] Represents a new value that adds itself to twice times the left element.
In general, the template does not allow the move out of the boundary, so the resulting image will be smaller than the original, for example, the template is, the image is after the template operation, where the number represents a grayscale, x represents a point on the boundary where the template operation is not possible, the usual practice is to copy the original image of the grayscale, no processing.
The template operation realizes a neighborhood operation (Neighborhoodoperation), that is, the gray scale of a pixel point is not only related to the pixel grayscale, but also to the value of its neighborhood point. In the refinement algorithm introduced later, we will also be exposed to neighborhood operations. The mathematical implication of a template operation is a convolution (or cross-correlation) operation, and you don't need to know the exact meaning of the convolution, as long as you have a concept like that.
Template operations are often used in image processing, which can be seen as a very time-consuming operation. Take (3.2)
For example, the template operation is done with 9 multiplication, 8 addition, and one division per pixel. For an image of NxN (width x height), it is 9n2 multiplication, 8n2 addition and N2 division, the algorithm complexity is O (N2), which is very scary for large images. Therefore, the commonly used templates are not big, such as 3x3,4x4. There are a lot of special image processing system, using hardware to complete the template operation, greatly improve the speed. In addition, we can try to transform the two-dimensional template operation into one-dimensional template operation, and the speed improvement is also very considerable. For example, the (3.2) formula can be decomposed into a horizontal template and a vertical template, i.e.,
(3.3)
Let's check it out.
The image is arranged after (3.2) processing, and after (3.3) processing becomes, the two are exactly the same. If the calculation does not take into account the surrounding circle of pixels, the former made 4x (9 multiplication, 8 additions, 1 divisions), a total of 36 multiplication, 32 additions, 4 divisions, the latter made 4x (3 multiplication, 2 addition) +4x (3 multiplication, 2 addition) + 4 division, a total of 24 multiplication, 16 addition, 4 Division, the operation is simplified a lot, if it is a large map, the efficiency of the increase will be very objective.
The idea of smoothing the template is that by averaging a point and the surrounding 8 points, the point of abrupt change is removed, and the noise is filtered out, and the cost is that the image has a certain degree of ambiguity. The above mentioned template (3.1), is a smooth template, called box template. The box template takes into account the neighborhood point, but does not take into account the impact of each point location, for all 9 points are treated equally, so the smooth effect is not ideal. In fact, we can imagine that the closer the point to the point of the impact should be greater, for this reason, we introduced the weighting coefficient, the original template is transformed into, it can be seen that the closer the point, the greater the weighting coefficient.
The new template is also a common smoothing template, called the Gaussian (Gauss) template. Why this name is called because this template is obtained by sampling the 2 Gaussian function.
The image is set up with two smoothing templates (a circle of pixels is copied directly from the original). The result of using the box template is that the result of using the Gaussian template is.
You can see that the noise in the original image area is the 2nd row 2nd column and 3rd row 2nd column, gray level from 21 to jump to 6, with the box template processing, grayscale from 3.11 to 4.33; after processing with Gaussian template, gray level from 3. Jump to 4.56, all easing the jump amplitude, from this point of view, Both have reached the goal of smoothing. However, in the original image of the 3rd, 4th line in general, the gray value is relatively high, after the template 1 processing, The 2nd column of the 3rd row of the gray level into 4.33, and 3rd, 4th line of the overall grayscale compared to a small, in addition, the original 3rd row 2nd column elements of the gray level of 6, 3rd row 3rd column element of the gray level of 4, after the transformation, the latter 4.56 is greater than the former 4.33. And the use of Gaussian template does not appear these problems, the reason is because it considers the position of the impact.
To give a practical example: the image below, from left to right respectively is the original, with the Gaussian template processing diagram, with the box template processing diagram, you can see that the use of Gaussian template, in order to achieve a smooth effect at the same time, more clearly than the box template.
function Implementation function Code:
Double Tem[9] = {1.0,2.0,1.0,2.0,4.0,2.0,1.0,2.0,1.0};
void Smooth () {int height = bmpinfoheader.biheight;
int width = bmpinfoheader.biwidth;
int imgsize = Bmpinfoheader.bisizeimage; int linebyte = (Width * 8 +31)/32 * 4; The number of bytes per row of pixels//processing is based on the original image, so the original data can not be changed, with Pnewbmpdata storage changes after the data memcpy (pnewbmpdata,pbmpdata,imgsize);
Copy the original data to Pnewbmpdata double sum; for (int i = 1, i < height-1; i++) {for (int j = 1; j < Width-1; J + +) {sum = 0; Clear 0 sum + = (double) (* (Pbmpdata + (i-1) * linebyte + j-1)) * tem[0]; The point in the lower left corner is sum + = (double) (* (Pbmpdata + (i-1) * linebyte + j)) * tem[1]; Under Sum + = (double) (* (Pbmpdata + (i-1) * Linebyte + j + 1)) * tem[2]; lower right sum + = (double) (* (Pbmpdata + i * linebyte + j-1)) * tem[3]; Left sum + = (double) (* (Pbmpdata + i * linebyte + j)) * tem[4]; The point position sum + = (double) (* (Pbmpdata + i * linebyte + j + 1)) * tem[5]; Right sum + = (double) (* (Pbmpdata + (i+1) * linebyte + j-1)) * tem[6]; upper Left sum + = (douBLE) (* (Pbmpdata + (i+1) * linebyte + j)) * tem[7]; On sum + = (double) (* (Pbmpdata + (i+1) * Linebyte + j + 1)) * Tem[8];
Upper Right * (Pnewbmpdata + i * linebyte + j) = (unsigned char) (sum/16.0); }
}
}
Second method: Median filter
Median filtering is also a typical low-pass filter, which is designed to protect image edges while eliminating noise. The so-called median filter, refers to a certain point (X, y) of the small window in the center of all the pixels in the gray scale in order from large to small, the median as (x, y) at the gray value (if the window has an even number of pixels, the average of two intermediate values). How does median filtering remove noise? It's easy to see, for example.
The figures in the figure represent the grayscale of the place. Can be seen in the middle of the original image 6 and the surrounding gray scale is very large, is a noise point. Through the 3x1 window (that is, the horizontal 3 pixels to take the median) of the median filter, to get to the right of the picture, you can see that the noise point was removed.
Below is a comparison between the median filter and the two smoothing templates described above to see what the median filter has. We take a one-dimensional template as an example, only the horizontal direction, the size of 3x1 (width × height). The box template is, the Gaussian template is.
First look at the picture:
It is not difficult to see from the original image of the left area gray value is low, the right area gray value is high, the middle has a clear boundary, this class of images called "step" (like grayscale on a step). When the smoothing template is applied, the image is smoothed, but the boundary is blurred. By applying median filtering, the original boundary can be maintained well. Therefore, the characteristic of median filter is to protect image edge while removing noise.
Then look at the second picture:
It is not difficult to see that there are many noise points in the original image (Gray is the point that the gray value is high, gray is negative for the low gray value point), and is disorganized, randomly distributed. This is also a kind of typical diagram, called Gaussian noise. After box smoothing, the degree of noise decreases. Gauss templates are very effective against Gaussian noise. The median filter is powerless for Gaussian noise.
Last look at the third picture:
It is not difficult to see from the original image that the middle gray level is much higher than the two sides. This is also a kind of typical diagram, called pulse (Impulse). It can be seen that median filtering is very effective for impulse noise.
Combined with the above three class diagram, it is not difficult to draw the following conclusions: Median filtering is easy to remove outliers, line noise while maintaining the edge of the image, it can be very good to remove the binary noise, but the Gaussian noise is powerless. It is important to note that when the number of noise points in the window is greater than half the window width, the median filter is not effective. This is very obvious. CODE:
/**
* Function Name: Medianfilter
* Power : Horizontal median filter processing for image *
/void Medianfilter ()
{
int height = Bmpinfoheader.biheight;
int width = bmpinfoheader.biwidth;
int imgsize = bmpinfoheader.bisizeimage;
int linebyte = (Width * 8 +31)/* 4; The number of bytes per row of pixels
//processing is based on the original image, so the original data can not be changed, with Pnewbmpdata storage changes after the data
memcpy (pnewbmpdata,pbmpdata,imgsize); Copy the original data to Pnewbmpdata
unsigned char g[3]; To take three points
//Note that the boundary point is not processed, so I from 1 to height -2,j similar for
(int i = 1; i < height-1; i++)
{for
(int j = 1; J < wid Th-1; J + +)
{
G[0] = * (Pbmpdata + i * linebyte + j-1);
G[1] = * (Pbmpdata + i * linebyte + j);
G[2] = * (Pbmpdata + i * linebyte + j + 1);
Sort (g,g+3); Sort
* (Pnewbmpdata + i * linebyte + j) = G[1];}}