[OpenCV-Python] 16 image smoothing

OpenCV-Python: IV Image Processing in OpenCV

16 Image smoothing

Goals
  • Learn to use different low-pass filters to blur images
  • Use custom filters to convolve images (2D convolution)

2D Convolution
  Like one-dimensional signals, we can also implement low-pass filtering (LPF), high-pass filtering (HPF), etc. on 2D images. LPF helps us remove noise and blur images. HPF helps us find the edge of the image.
The function cv.filter2D() provided by OpenCV allows us to perform convolution operations on an image. Below we will use an averaging filter on an image. The following is a 5x5 average filter kernel: the
      K =  \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1  \ 1 & 1 & 1 & 1 & 1 \ 1 & 1 & 1 & 1 & 1 \ 1 & 1 & 1 & 1 & 1 \ 1 & 1 & 1 & 1 & 1 \end{bmatrix}
operation is as follows: put the kernel on a pixel A of the image, find the sum of 25 (5x5) pixels on the image corresponding to the kernel, and then take the average and replace it with this average The value of pixel A. Repeat the above operation until each pixel value of the image is updated. The code is as follows, let's run it.

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

img = cv2.imread('opencv_logo.png')

kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()

result:

Image blur (image smoothing)
Use a low-pass filter to achieve the purpose of image blur. This is very helpful for noise removal. In fact, it is to remove the high-frequency components (such as: noise, border) in the image. So the border will be blurred a bit. (Of course, there are some blurring techniques that will not blur the boundaries). OpenCV provides four blurring techniques.

16.1 Average

This is done by a normalized convolution box. He just uses the average value of all pixels in the area covered by the convolution box to replace the central element. You can use the functions cv2.blur() and cv2.boxFilter() to accomplish this task. You can also see the documentation for more details of the convolution box. We need to set the width and height of the convolution box. The following is a 3x3 normalized convolution box:
      K =  \frac{1}{9} \begin{bmatrix} 1 & 1 & 1  \ 1 & 1 & 1 \ 1 & 1 & 1 \end{bmatrix}
Note: If you don't want to use a normalized convolution box, you should use cv2.boxFilter(), and then pass in the parameter normalize=False.
The following is the same example as the first part:

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

img = cv2.imread('opencv_logo.png')

blur = cv2.blur(img,(5,5))

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

result:

blur

16.2 Gaussian Blur

Now replace the convolution kernel with a Gaussian kernel (in simple terms, the box remains unchanged, the original value of each box is equal, and the value inside is now in accordance with the Gaussian distribution, the center of the box has the largest value, and the rest The box decreases according to the distance from the center element to form a Gaussian hill bag. The original average is now a weighted average, which is all the value in the box). The implemented function is cv2.GaussianBlur(). We need to specify the width and height of the Gaussian kernel (must be an odd number). And the standard deviation of the Gaussian function along the X and Y directions. If we only specify the standard deviation in the X direction, the Y direction will also take the same value. If both standard deviations are 0, then the function will calculate itself according to the size of the kernel function. Gaussian filtering can effectively remove Gaussian noise from the image.
If you want, you can also use the function cv2.getGaussianKernel() to build a Gaussian kernel yourself.
If you want to use Gaussian blur, the above code should be written as:

#0 是指根据窗口大小( 5,5 )来计算高斯函数标准差
blur = cv2.GaussianBlur(img,(5,5),0)

result:

GaussianBlur

16.3 Median Blur

As the name implies, the median value of the pixel corresponding to the convolution box is used to replace the value of the center pixel. This filter is often used to remove salt and pepper noise. The previous filters use a new value calculated to replace the value of the center pixel, while the median filter replaces it with the value around the center pixel (or itself). He can effectively remove noise. The size of the convolution kernel should also be an odd number.
In this example, we add 50% noise to the original image and then use the median blur.
Code:

median = cv2.medianBlur(img,5)
# 运行有问题,出不了如下结果,下图为照搬的

result:

Median Blurring

16.4 Bilateral filtering

The function cv2.bilateralFilter() can effectively remove noise while keeping the boundary clear. However, this operation is slower than other filters. We already know that the Gaussian filter is to find the Gaussian weighted average of the pixels in the vicinity of the center point. This Gaussian filter only considers the spatial relationship between pixels, but does not consider the relationship between pixel values ​​(pixel similarity). So this method does not consider whether a pixel is located on the boundary. Therefore, the boundary will not be blurred, and this is not what we want. Bilateral filtering uses both spatial Gaussian weights and gray value similarity Gaussian weights. The spatial Gaussian function ensures that only the pixels in the neighboring area have an influence on the center point, and the gray value similarity Gaussian function ensures that only the gray value of the center pixel is similar to that will be used for the blur operation. So this method will ensure that the border will not be blurred, because the gray value changes at the border are relatively large.
The code for bilateral filtering is as follows:

#cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
#d – Diameter of each pixel neighborhood that is used during filtering.
# If it is non-positive, it is computed from sigmaSpace
#9 邻域直径,两个 75 分别是空间高斯函数标准差,灰度值相似性高斯函数标准差
blur = cv2.bilateralFilter(img,9,75,75)
# 运行有问题,出不了如下结果,下图为照搬的  

Result:
See it, the texture in the image above is blurred, but the border is still there.

Bilateral Filtering

For more information, please pay attention to the official account:
img

Guess you like

Origin blog.csdn.net/yegeli/article/details/113418884