Previous portal:

“Python Image Processing OpenCV (1) : Getting Started”

“Python Image Processing OpenCV (2) : Pixel Processing with Numpy manipulation and Matplotlib Display images”

“Python Image Processing OpenCV (3) : Image Properties, ROI Regions of Interest and Channel Processing”

“Python Image Processing OpenCV (4) : Image Arithmetic and Color Space Modification”

“Python Image Processing OpenCV (5) : Geometric Transformations of Images”

“Python Image Processing OpenCV (6) : Image Threshold Processing”

1. The introduction

So the first thing is, again, what is image smoothing?

It literally looks like image smoothing as if it’s talking about image sliding.

Emmmmmmmmmmmmmmmmm…

In fact, there is no relationship between half a cent, image smoothing technology is usually also known as image filtering technology (this name may see you will have a feeling).

Every image contains noise to a certain extent, which can be understood as the random change of gray value caused by one or more reasons, such as the noise caused by the randomness of photon flux, etc.

And the image smoothing technology or image filtering technology is used to deal with the noise on the image, which can have the effect of edge smoothing, has become the focus of attention.

This is no nonsense, processing a picture noise reduction, the result of the entire image with glass paste on a layer of water mist, what is the meaning of this noise reduction.

This article introduces four algorithms for image smoothing provided in OpenCV:

  • Average filtering
  • Box filtering
  • Gaussian filter
  • Median filtering

Here we go one by one 🙂

Gives a add noise to Mario program, program comes from the teacher’s blog: Yang blog.csdn.net/Eastmount/a… , the complete code is as follows:

import cv2 as cv
import numpy as np

# fetch image
img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED)
rows, cols, chn = img.shape

# plus noise
for i in range(5000):
    x = np.random.randint(0, rows)
    y = np.random.randint(0, cols)
    img[x, y, :] = 255

cv.imshow("noise", img)

# Save images
cv.imwrite("maliao_noise.jpg", img)

# wait for display
cv.waitKey()
cv.destroyAllWindows()
Copy the code

The above program is actually adding 5,000 random white dots to the image, which is really loud enough.

2. 2D image convolution

Before introducing filtering, let’s briefly introduce 2D image convolution, which is actually image filtering.

Image filtering can use a variety of low pass filter (LPF), high pass filter (HPF), etc.

Low pass filter (LPF) helps to eliminate noise, but can blur the image.

A high-pass filter (HPF) helps find edges in an image.

OpenCV provides a function called filter2D() to convolve the kernel with the image.

We try to average the image, and the kernel of the 5 x 5 average filter is as follows:


Specific operations are as follows:

We keep the kernel at one pixel, add up all 25 pixels below the kernel, take their average, and replace the center pixel with the new average. It continues this for all pixels in the image, complete with the following example code:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

# fetch image
img = cv.imread("maliao_noise.jpg", cv.IMREAD_UNCHANGED)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

kernel = np.ones((5.5),np.float32)/25

dst = cv.filter2D(rgb_img, - 1, kernel)

titles = ['Source Image'.'filter2D Image']
images = [rgb_img, dst]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
Copy the code

As you can see, the noise does go away, but the image becomes blurred.

3. Mean filtering

Mean filtering refers to the pixel value at any point, which is the mean value of N * M surrounding pixel values.

In fact, the mean filtering and the image convolution example above do the same thing, I just manually do the mean filtering using filter2D(). In fact, OpenCV provides a special mean filtering method for us. If you didn’t understand the convolution in the previous image, you can do the mean filtering again. I’ll try to make this whole thing clear.

So let’s draw a picture:

The value in the red box in the middle is the sum of the pixels in the surrounding 25 grids divided by 25, and the formula looks like this:


I’m going to write all the pixels in the grid as 1 just to be lazy, because n over n is always equal to 1.

The above 5 * 5 matrix is called kernel, which is used to process the pixels in the original image to obtain the resulting image.

We can customize the size of the core, such as 5 * 5, 3 * 3, 10 * 10, etc., depending on the therapeutic effect.

OpenCV provides me with the blur() method to achieve mean filtering. The original function is as follows:

def blur(src, ksize, dst=None, anchor=None, borderType=None)
Copy the code
  • KSize: the kernel parameter is actually the matrix multiplied when the image is convolved. How to calculate the convolved matrix is very many online, I will not describe it here, the resulting image is blurred, and the image is actually missing (original image – kernel parameter +1)^2 cells according to the original ratio.
  • Anchor: Point type, namely anchor Point, has the default value Point(-1, -1), when the coordinate is negative, it represents the core center.
  • BorderType: Type Int, used to infer some boundary mode for the external pixels of the image, with a default value of BORDER_DEFAULT.

Here is the sample code for mean filtering:

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread("maliao_noise.jpg", cv.IMREAD_UNCHANGED)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Mean filtering
blur_img = cv.blur(rgb_img, (3.3))
# blur_img = cv.blur(img, (5, 5))
# blur_img = cv.blur(img, (10, 10))
# blur_img = cv.blur(img, (20, 20))

titles = ['Source Image'.'Blur Image']
images = [rgb_img, blur_img]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
Copy the code

This noise reduction is not as good as the previous 2D convolution noise reduction, but the image is clearer, because I used a smaller core in this example, a 3 by 3 core. By the way, I also tried a larger core, such as a 10 by 10 core commented out in the code or a 20 by 20 core. Real-time proof, The larger the core, the better the noise reduction, but on the contrary, the more blurred the image.

4. Box filtering

Box filter and mean filter kernel are basically the same, the difference is whether normalization is needed.

We’ll talk about normalization in a minute, but let’s look at the box filter function:

def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None)
Copy the code
  • SRC: original image.
  • Ddepth: Int. The depth of the target image, usually -1, is consistent with the original image.
  • KSize: kernel parameter.
  • DST: Outputs an image of the same size and type as SRC.
  • Anchor: Point type, i.e. anchor Point, with default value Point(-1, -1).
  • Normalize: Int: indicates whether the target image is normalized.

When normalize is true, averaging is required.

When normalize is false, no mean processing is performed, but the sum of surrounding pixels is actually calculated. Overflow is easy to occur. When overflow occurs, all pixels are white and the corresponding pixel value is 255.

The complete sample code is as follows:

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread('maliao_noise.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# box filtering
result = cv.boxFilter(source, - 1, (5.5), normalize = 1)

# Display graphics
titles = ['Source Image'.'BoxFilter Image']
images = [source, result]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
Copy the code

When we set normalize to 0, without normalizing, the result looks like this:

5. Gaussian filtering

In order to overcome the disadvantage of simple local average method (image blur), many local smoothing algorithms have been proposed to preserve edges and details. Their starting point is how to choose the size, shape and direction of neighborhood, parameter plus average and weight coefficient of neighborhood.

In the Gaussian filtering method, you actually replace the convolution kernel with a Gaussian kernel, so what is a Gaussian kernel?

Simply is the box, box or the original every right of the inside of the box are equal, you finally take the average, now turned into a gaussian distribution, the weights of the center of the square is the largest, diminishing the distance form the centre of the box by distance element, constitute a gaussian hillock, so take the value becomes a weighted average.

The figure below shows the Gaussian kernel in the fields of 3 * 3 and 5 * 5.

Gaussian filtering is implemented in OpenCV by GaussianBlur(). Its original function is as follows:

def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
Copy the code
  • SigmaX: indicates the x-direction variance.

In the Gaussian kernel, the kernel (N, N) must be odd, and the x-direction variance mainly controls the weight.

The complete sample code is as follows:

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread('maliao_noise.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# box filtering
result = cv.GaussianBlur(source, (3.3), 0)

# Display graphics
titles = ['Source Image'.'GaussianBlur Image']
images = [source, result]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
Copy the code

6. Median filtering

The denoising by neighborhood average method also makes the boundary blurred.

Median filtering is a nonlinear image processing method which can preserve boundary information while denoising.

The specific method of median filtering is to select a window W with odd points, scan the window on the image, arrange the pixels contained in the window in ascending or descending order of gray level, and take the gray value in the middle to replace the gray value of the point.

The following figure shows the filtering process of a one-dimensional window:

In OpenCV, medianBlur() is called to achieve median filtering. Its original function is as follows:

def medianBlur(src, ksize, dst=None)
Copy the code

The cores of the median filter, like those of the Gaussian filter, must be an odd number greater than 1.

Example code is as follows:

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread('maliao_noise.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# box filtering
result = cv.medianBlur(source, 3)

# Display graphics
titles = ['Source Image'.'medianBlur Image']
images = [source, result]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
Copy the code

It can be clearly seen that the current median filtering is the highest degree of reduction of the original image after denoising. The commonly used median filtering graphics can use square boxes, as well as cross, circle and ring, and different shapes of Windows produce different filtering effects.

Square and round Windows are suitable for object images with long contour lines, while cross Windows are good for images with pointed corners.

For some complex images with more details, different median filtering can be used many times.

7. sample code

If you need to get the source code, you can reply “OpenCV” on the public account to get it.

Reference 8.

Blog.csdn.net/Eastmount/a…

www.woshicver.com/