[Opencv-Python] Digital image processing (3) – Spatial image processing (2)

?

>Article navigation

1 Experimental purposes and requirements

2 Experimental environment and configuration

3 Spatial filtering

3.1 Image smoothing (mean filter, median filter, Gaussian filter)

3.2 Image sharpening

(1) Laplacian template (linear)

4 Experimental experiences and thoughts

4.1 Summary of experimental experience

4.2 Experimental problems and solutions


1 Experiment purpose and requirements

(1) Master the basic principles of image processing and the role of filters, and understand the characteristics and application scope of different filters;

(2) Understand and master image sharpening and other processing methods based on Laplacian template;

(3) Understand and master the basic concepts and methods of image operations;

(4) Through experiments, improve the understanding of basic concepts of image processing and cultivate practical operation and problem-solving abilities.

2 Experimental environment and configuration

(1) Computer;

(2) Python and Anaconda software;

(3) Typical grayscale, color image and other files.

3 Spatial filtering

Spatial filtering is a neighborhood processing method that smoothes or sharpens the image by directly processing pixels in the neighborhood in the image space.

3.1 Image Smoothing (Mean Filter, Median Filter, Gaussian Filter)

(1) Mean filter–cv2.blur(original image, kernel size) (2) Median filter–cv2.medianBlur(src, ksize) (3) Gaussian filter–cv2.GaussianBlur(src, ksize, sigmaX)

ksize = 3 :

import cv2
img = cv2.imread('D:\images\lena_color_512_saltpepper.jpg ') # Read the picture
result_blur = cv2.blur(img, (3, 3)) #Mean filter
result_GaussianBlur = cv2.GaussianBlur(img, (3, 3), 0) # Gaussian filter (i.e. the "weighted average filter" in the textbook)
result_medianBlur = cv2.medianBlur(img, 3) # Median filtering
cv2.imshow('original', img)
cv2.imshow('result_blur', result_blur)
cv2.imshow('result_GaussianBlur', result_GaussianBlur)
cv2.imshow('result_medianBlur', result_medianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102110201130

image-20231102110236671

1. Compare which filter has better denoising effect.

Median filtering works best.

The mean filter is a simple smoothing filter that takes the average value of the pixel neighborhood as the new pixel value. This filter has a good effect on eliminating random noise (especially Gaussian noise) in the image, but it has a poor suppression effect on salt and pepper noise.

Gaussian filtering is actually also a weighted average filtering, except that it gives greater weight to pixels closer to the center. Compared with mean filtering, Gaussian filtering is better at eliminating noise, especially for eliminating salt and pepper noise.

Median filtering is a nonlinear operation filter that sorts the gray values of the pixel neighborhood and then takes the middle value as the new pixel value. Median filtering is particularly effective in eliminating salt and pepper noise, but its suppression effect on Gaussian noise is not as good as the first two.

Which filter is better at denoising depends on what kind of noise is present in your image. If you are dealing with Gaussian noise, then mean filtering and Gaussian filtering will perform better. If you are dealing with salt and pepper noise, then the median filter will work better.

2. For each filter function, try different kernel sizes ksize (such as 3, 5, 7), and compare the smoothing effects of the output.

For Mean filter, changing the kernel size will affect the smoothness of the image by the filter. A larger kernel size will make the filter have a stronger smoothing effect on the image, which will make the image look blurry. Asmaller kernel size will make the filter less smooth and the image will retain more detail.

For Gaussian filter, changing the kernel size will also affect the smoothness of the image by the filter. Similar to mean filtering, a larger kernel size will make the image look blurrier, and asmaller kernel size will make the image retain more detail.

For median filtering, changing the kernel size mainly affects how smoothly the filter smoothes the image. Since median filtering is a nonlinear operation that is particularly effective in eliminating salt-and-pepper noise, changing the kernel size has little effect on the effectiveness of median filtering.

ksize = 5 :

import cv2
img = cv2.imread('D:\images\lena_color_512_saltpepper.jpg ') # Read the picture
result_blur = cv2.blur(img, (5, 5)) #Mean filter
result_GaussianBlur = cv2.GaussianBlur(img, (5, 5), 0) # Gaussian filter (i.e. the "weighted average filter" in the textbook)
result_medianBlur = cv2.medianBlur(img, 5) # Median filtering
cv2.imshow('original', img)
cv2.imshow('result_blur', result_blur)
cv2.imshow('result_GaussianBlur', result_GaussianBlur)
cv2.imshow('result_medianBlur', result_medianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102111129445

image-20231102111206824

ksize = 7 :

import cv2
img = cv2.imread('D:\images\lena_color_512_saltpepper.jpg ') # Read the picture
result_blur = cv2.blur(img, (7, 7)) #Mean filter
result_GaussianBlur = cv2.GaussianBlur(img, (7, 7), 0) # Gaussian filter (i.e. the "weighted average filter" in the textbook)
result_medianBlur = cv2.medianBlur(img, 7) # Median filtering
cv2.imshow('original', img)
cv2.imshow('result_blur', result_blur)
cv2.imshow('result_GaussianBlur', result_GaussianBlur)
cv2.imshow('result_medianBlur', result_medianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102111310714

image-202311021111337763

3. Select a picture without noise, filter it with the above three filter functions, and observe the characteristics of the smoothing effect without noise.

In the absence of noise, these three filter functions can smooth the image, but their characteristics are different. Both mean filtering and median filtering will slightly blur the image, but median filtering is better at preserving edges. Gaussian filtering can remove some small noise while maintaining image clarity.

The effectiveness of these three filter functions is also affected by the filter size. Larger filters remove noise better, but make the image blurrier. Smaller filters preserve image detail better, but are less effective at removing noise.

import cv2
img = cv2.imread('D:\myimages\lake.jpg ') # Read the image
result_blur = cv2.blur(img, (7, 7)) #Mean filter
result_GaussianBlur = cv2.GaussianBlur(img, (7, 7), 0) # Gaussian filter (i.e. the "weighted average filter" in the textbook)
result_medianBlur = cv2.medianBlur(img, 7) # Median filtering
cv2.imshow('original', img)
cv2.imshow('result_blur', result_blur)
cv2.imshow('result_GaussianBlur', result_GaussianBlur)
cv2.imshow('result_medianBlur', result_medianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102111838077

image-20231102111936772

4. Without calling the above-mentioned cv2 built-in filter function, you can manually program to implement median filtering and Gaussian filtering (textbook p62 weighted average filtering) respectively. You must provide the code and filtering effect you implemented yourself. The filter size is set to 3 × 3.

Median filter:

import cv2
import numpy as np
def median_filter(image):
    height, width = image.shape
    result = np.zeros((height, width), dtype=np.uint8)
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            neighborhood = image[i - 1:i + 2, j - 1:j + 2]
            result[i, j] = np.median(neighborhood)
    return result
# read image
image = cv2.imread('D:\myimages\cat.jfif', cv2.IMREAD_GRAYSCALE)
#Apply median filter
filtered_image = median_filter(image)
# Display original image and filtered image
cv2.imshow('Original Image', image)
cv2.imshow('Median Filtered Image', filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231109104006962

Gaussian filter:

import cv2
import numpy as np
def gaussian_filter(image):
    height, width = image.shape
    result = np.zeros((height, width), dtype=np.uint8)
?
    kernel = np.array([[1, 2, 1],
                      [2, 4, 2],
                      [1, 2, 1]]) / 16
?
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            neighborhood = image[i - 1:i + 2, j - 1:j + 2]
            weighted_sum = np.sum(neighborhood * kernel)
            result[i, j] = weighted_sum
?
    return result
# read image
image = cv2.imread('D:\myimages\cat.jfif', cv2.IMREAD_GRAYSCALE)
#Apply Gaussian filter
filtered_image = gaussian_filter(image)
# Display original image and filtered image
cv2.imshow('Original Image', image)
cv2.imshow('Gaussian Filtered Image', filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231109103706779

3.2 Image Sharpening

dst = cv2.filter2D(src, -1, kernel) In the above formula, -1 means that the depth (number of data bits) of the target image and the original image are consistent, kernel For filter templates, different templates have filtering effects.

(1) Laplacian template (linear)

kernel = 8:

import cv2
import numpy as np
src = cv2.imread('D:\myimages\dog_single.png')
kernel = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
dst = cv2.filter2D(src, -1, kernel)
cv2.imshow('original', src)
cv2.imshow('dst', dst)
cv2.imshow('src + dst', src + dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102201338682

2. Question: If the value of the filter template center in the above example is changed from 8 to 9, what is the image filtered by filter2D(src, -1, kernel)? Briefly analyze why such a filtered image appears.

If you change the value of the filter template center from 8 to 9, the filter will become a sharpening filter. After filtering with filter2D(src, -1, kernel), the image will become clearer. Because the sharpening filter can highlight the edges and details of the image, making the image look clearer. At the same time, due to changes in the center value of the filter, the smoothness of the image by the filter will also be different, so the filtered image may change slightly.

kernel = 9:

import cv2
import numpy as np
src = cv2.imread('D:\myimages\dog_single.png')
kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]])
dst = cv2.filter2D(src, -1, kernel)
cv2.imshow('original', src)
cv2.imshow('dst', dst)
cv2.imshow('src + dst', src + dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102201532632

3. Change to another image (not limited to images in the folder images, you can find it yourself) to perform image sharpening based on the Laplacian template.

import cv2
import numpy as np
src = cv2.imread('D:\myimages\cat.jfif')
kernel = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
dst = cv2.filter2D(src, -1, kernel)
cv2.imshow('original', src)
cv2.imshow('dst', dst)
cv2.imshow('src + dst', src + dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231102201758002

4. Without calling the filter2D function, you can manually program the sharpening filter of the Laplacian template below. You must provide the code and filtering effect you implemented yourself. The filter size is set to 3 × 3.

image-20231102112659756

import cv2
import numpy as np
def laplacian_sharpening(image):
    height, width = image.shape
    result = np.zeros((height, width), dtype=np.uint8)
    # Define Laplacian sharpening filter
    laplacian_kernel = np.array([[0, -1, 0],
                                 [-1, 4, -1],
                                 [0, -1, 0]])
    for i in range(1, height - 1):
        for j in range(1, width - 1):
            neighborhood = image[i - 1:i + 2, j - 1:j + 2]
            weighted_sum = np.sum(neighborhood * laplacian_kernel)
            result[i, j] = np.clip(weighted_sum, 0, 255) # Make sure the pixel value is between 0 and 255
    return result
# read image
image = cv2.imread('D:\myimages\cat.jfif', cv2.IMREAD_GRAYSCALE)
# Apply Laplacian sharpening filter
sharpened_image = laplacian_sharpening(image)
# Display the original image and the sharpened image
cv2.imshow('Original Image', image)
cv2.imshow('Sharpened Image', sharpened_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20231109104434716

4 Experimental Experience and Thoughts

4.1 Summary of Experimental Experience

Through this experiment, I gained an in-depth understanding of the basic principles of image processing and the characteristics and application scope of different filters. Not only did I master how to denoise and smooth images using mean, Gaussian and median filters, I also learned how to sharpen images using Laplacian templates. At the same time, I also learned the basic concepts and methods of image operations.

During the experiment, I observed and compared the processed images and found that different filters have different performances in terms of denoising effect and image smoothing effect. Mean filtering has a good effect on eliminating random noise (especially Gaussian noise) in the image, but it will reduce the clarity of the image. Gaussian filtering can better eliminate Gaussian noise, but still retains some noise. Median filtering is particularly effective at removing salt and pepper noise, but it makes the image blurry. I also found that the Laplacian sharpening method enhanced the edge details of the image, making the image look sharper.

4.2 Experimental problems and solutions

If you encounter unexpected problems during the experiment (for example, the image processing effect obtained is different from expected), find the reason yourself and think of ways to solve it.

(1) A problem occurs when assigning values to array elements and sequences using Laplacian filtering. The result array is used to store the entire filtered image to solve the errors encountered:

image-20231102223337679

If you think the author’s writing is good, please Like / Collect / Comment/ Forward and support it. ~

The most important thing is to click a big Follow. Your support is the greatest motivation for the author’s creation!!!