opencv-python learning (10): using convolution to blur images

First, call the function to achieve fuzzy

Image blurring is one of the more commonly used and simple processing methods in image processing. Then the reason for using this method is to denoise the image for later processing.

According to my image convolution operation above, I can imagine that image blurring is the calculation of convolution. Take a 3*3 convolution kernel to do a sliding operation on the image, and then get a new image.

Different types of blurs actually correspond to
different convolution kernels. According to different principles, there are many ways to blur, such as: mean blur function blur(), median blur function medianBlur(), Gaussian smoothing function GaussianBlur(), Bilateral filter function bilateralFilter()

  • Mean blur function blur()

Mean blur literally means to remove the average value, that is, the coefficients in the convolution kernel are all 1, multiplied by the pixel value of the original image covered by the convolution kernel, and then divided by 9 (the size of the convolution kernel is 3*3 ), get the average value and assign it to the center pixel

Its disadvantage is that it cannot preserve image details well while denoising, because it is all replaced by the mean value.

blur(src,ksize,dst=None, anchor=None, borderType=None)
src: Input image
ksize: The size of the convolution kernel, the larger the blurrier, generally speaking, it is an odd number, the convolution kernel is generally 3x3, 5x5 or 7x7 and
other parameters can be ignored

  • Gaussian smoothing function GaussianBlur()

Compared with mean blur, Gaussian blur can better preserve the details of the image. Because of the characteristics of the Gaussian function, there will be a certain weight ratio

GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
src: input image
ksize: blur kernel size, but they must be positive and odd
sigmaX: Gaussian kernel standard deviation in X direction

  • Median blur function medianBlur()

Literally, it takes the middle value to replace the center pixel. Similar to the mean, except that the mean is the average value, and the median is the value in the middle. The median can effectively remove salt and pepper noise (for example, if you sprinkle some salt in clear water, these are salt and pepper noise. Corresponding to the image, on a black image, there are many small white spots, these are salt and pepper noise)

So why can it remove salt and pepper noise? Because the salt and pepper noise pixel value is either very small to 0, or very large to 255, and if the intermediate value is taken, these will be replaced by these, thereby denoising the image.

medianBlur(src, ksize, dst=None)
src: input image
ksize: aperture linear size; it must be odd and greater than 1

  • Bilateral filter function bilateralFilter()

Gaussian filtering retains some details of the image relative to the mean blur, but it is based on the empty threshold, which is based on the spatial distribution. But it still has no way to completely avoid the loss of edge information. The bilateral filter has a Gaussian variance sigma-d more than the Gaussian filter, so near the edge, the pixels farther away will not affect the pixel value on the edge too much, thus ensuring the preservation of the pixel value near the edge . That is to say, their pixel values ​​are outside the set drop, and they are not blurred, which is easier to preserve the edges.

bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
src: the input image
d: the diameter of each pixel neighborhood used for filtering, all pixels within the diameter will be included in the calculation. If it is non-positive, calculate
sigmaColor from sigmaSpace: determines how many pixels within the difference will be calculated, color standard deviation
sigmaSpace: invalid if the value of d is greater than 0, otherwise it will be used to calculate the value of d, space standard deviation

code show as below:

# 引入包
import cv2 as cv

def mo_image(src1):
    src2 = cv.blur(src1, (5, 5))
    cv.namedWindow("blur", cv.WINDOW_NORMAL)
    cv.imshow("blur", src2)

    src2 = cv.medianBlur(src1, 5)
    cv.namedWindow("mdBlur", cv.WINDOW_NORMAL)
    cv.imshow("mdBlur", src2)

    src2 = cv.GaussianBlur(src1, (5, 5), 2)
    cv.namedWindow("GaussBlur", cv.WINDOW_NORMAL)
    cv.imshow("GaussBlur", src2)

    src2 = cv.bilateralFilter(src1, 5, 5, 2)
    cv.namedWindow("bilFilter", cv.WINDOW_NORMAL)
    cv.imshow("bilFilter", src2)

src = cv.imread("./static/image/blur.jpg")
cv.namedWindow("image", cv.WINDOW_NORMAL)
cv.imshow("image", src)
mo_image(src)
cv.waitKey(0)
cv.destroyAllWindows()



2. Custom blur

filter2D(): defined as filter2D(src,ddepth,kernel)

  • src: input image
  • ddepth: Depth, when the input value is -1, the depth of the target image is consistent with the original image, generally set to -1.
  • Kernel: Convolution kernel (or related kernel), a single-channel floating-point matrix (modifying the kernel matrix can achieve different blurs, there are many interesting kernels):

1. Blur
The blur kernel eliminates the difference between adjacent pixel values. The kernel is as follows:
kernel = np.ones((5, 5), np.float)/25

# 自定义模糊
    kernel1 = np.ones((5, 5), np.float)/25 # 自定义矩阵,并防止数值溢出
    src2 = cv.filter2D(src1, -1, kernel1) # 自定义模糊
    cv.namedWindow("define", cv.WINDOW_NORMAL)
    cv.imshow("define", src2)

running result:
insert image description here

2. Sobel (sobel)
The sobel kernel is used to display only the difference in adjacent pixel values ​​in a specific direction, divided into left sobel, right sobel (detecting the horizontal change of the gradient), top sobel, buttom sobel (detecting the vertical change of the gradient) . The kernel is as follows:

-1 -2 -1
0 0 0
1 2 1

The code is similar to the above, just modify the value of krenel :
insert image description here

3. Emboss (emboss)
Gives the illusion of depth in a given direction by emphasizing the difference in pixels. In this case, along the direction of a straight line from top left to bottom right. The kernel is as follows:

-2 -1 0
-1 1 1
0 1 2

running result:
insert image description here

4. Outline
An outline kernel (also known as an "edge" kernel) is used to highlight large differences in pixel values. Pixels next to neighbors with nearly the same intensity will appear black in the new image, while pixels adjacent to strongly different neighbors will appear white. The kernel is as follows:

-1 -1 -1
-1 8 -1
-1 -1 -1

running result:
insert image description here

5. Sharpen
a contour kernel (also known as an "edge" kernel) to highlight large differences in pixel values. Pixels next to neighbors with nearly the same intensity will appear black in the new image, while pixels adjacent to strongly different neighbors will appear white. The kernel is as follows:

0 -1 0
-1 5 -1
0 -1 0

Running effect:
insert image description here
6. Laplacian operator (laplacian operator)
The Laplacian operator can be used for edge detection, and is also very useful for detecting blur in images. The kernel is as follows:

0 1 0
1 -4 1
0 1 0

running result:
insert image description here

7. Identity
is very simple, it is the original image (when the boundary is not considered). The kernel is as follows:

0 0 0
0 1 0
0 0 0

Full code:

# 引入包
import cv2 as cv
import numpy as np

def define_image(src1):
    # 自定义模糊
    kernel1 = np.ones((9, 9), np.float)/80 # 自定义矩阵,并防止数值溢出
    src2 = cv.filter2D(src1, -1, kernel1) # 自定义模糊
    cv.namedWindow("define", cv.WINDOW_NORMAL)
    cv.imshow("define", src2)

    # 自定义锐化
    kernel2 = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel2) # 自定义锐化
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

    # 索贝尔(sobel)
    kernel3 = np.array([[-1, -2, -1],
        [0, 0, 0],
        [1, 2, 1]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel3)
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

    # 浮雕
    kernel4 = np.array([[-2, -1, 0],
                        [-1, 1, 1],
                        [0, 1, 2]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel4)
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

    # 大纲(outline)
    kernel5 = np.array([[-1, -1, -1],
                        [-1, 8, -1],
                        [-1, -1, -1]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel5)
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

    # 拉普拉斯算子(laplacian operator)
    kernel6 = np.array([[0, 1, 0],
                        [1, -4, 1],
                        [0, 1, 0]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel6)
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

    # 分身(identity)
    kernel7 = np.array([[0, 0, 0],
                        [0, 1, 0],
                        [0, 0, 0]], np.float32)
    src2 = cv.filter2D(src1, -1, kernel7)
    cv.namedWindow("define2", cv.WINDOW_NORMAL)
    cv.imshow("define2", src2)

src = cv.imread("./static/image/windows.jpg")
cv.namedWindow("image", cv.WINDOW_NORMAL)
cv.imshow("image", src)
define_image(src)
cv.waitKey(0)
cv.destroyAllWindows()

Example reference:

https://blog.csdn.net/qq_42059060/article/details/107660265?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162520738216780271574301%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162520738216780271574301&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-2-107660265.pc_search_result_cache&utm_term=cv.filter2d&spm=1018.2226.3001.4187

Guess you like

Origin blog.csdn.net/weixin_33538887/article/details/118390924