Image Thresholding – Image Smoothing – Mean Filtering – Box Filtering – Gaussian Filtering – Median Filtering

Article directory

      • image thresholding
        • standard paradigm
        • Parameter Description
        • the code
        • visualize the results
      • image smoothing
        • image noise
      • Image Noise Results
        • mean filtering
        • box filtering
        • Gaussian filter
        • median filter
      • Comparison of different filtering results

Image thresholding

Standard paradigm

Standard paradigm: res,dst = cv2.threshold(src, thresh, maxval, type)

Parameter Description

cv2.threshold() is an image thresholding function in the OpenCV library, which is used to binarize the input image (separate the image into two gray levels). The function takes the following parameters:

  • src: input image, grayscale image (single channel image).
  • thresh: Threshold, the pixel value used to divide the image into two gray levels.
  • maxval: The maximum pixel value, if a pixel is greater than the threshold, it is set to this value, which can be 0 or 255.

type: Thresholding type, specifies the thresholding method to apply. Here are some common types:

  • cv2.THRESH_BINARY: Binarization threshold type, pixels exceeding the threshold are set to maxval, and pixels below the threshold are set to 0.
  • cv2.THRESH_BINARY_INV: Inverse binary threshold type, pixels exceeding the threshold are set to 0, and pixels below the threshold are set to maxval.
  • cv2.THRESH_TRUNC: Truncation threshold type, pixels exceeding the threshold are set to the threshold, and pixels below the threshold remain unchanged.
  • cv2.THRESH_TOZERO: Thresholding is a zero threshold type, pixels above the threshold remain unchanged, and pixels below the threshold are set to 0
  • cv2.THRESH_TOZERO_INV: Inverse zero threshold type, pixels exceeding the threshold are set to 0, and pixels below the threshold remain unchanged.

Two values are returned: the thresholded result (dst) and the threshold used (ret).

Code

def BGR2RGB(img):
    """

    :param img:
    :return:
    """
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1, mode=cv2.IMREAD_GRAYSCALE)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Return threshold and thresholded image
    ret, thresh1 = cv2.threshold(img_1, 127, 255, cv2.THRESH_BINARY)
    ret, thresh2 = cv2.threshold(img_1, 127, 255, cv2.THRESH_BINARY_INV)
    ret, thresh3 = cv2.threshold(img_1, 127, 255, cv2.THRESH_TRUNC)
    ret, thresh4 = cv2.threshold(img_1, 127, 255, cv2.THRESH_TOZERO)
    ret, thresh5 = cv2.threshold(img_1, 127, 255, cv2.THRESH_TOZERO)
    titles = ['Rti_imh',
              'THRESH_BINARY',
              'THRESH_BINARY_INV',
              'THRESH_TRUNC',
              'THRESH_TOZERO',
              'THRESH_TOZERO']
    images = [img_1, thresh1, thresh2, thresh3, thresh4, thresh5]
    plt.figure(figsize=(18, 12))
    for i in range(6):
        plt.subplot(f'23{<!-- -->i + 1}')
        plt. title(titles[i])
        plt.imshow(BGR2RGB(images[i]))
    plt. show()

Visualize the results

Image smoothing

Image Noise

if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1, mode=cv2.IMREAD_GRAYSCALE)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    img_show('==', reslut)

Result of image noise addition

Mean filter

Paradigm: blur = cv2.blur(reslut, (3, 3))

def BGR2RGB(img):
    """

    :param img:
    :return:
    """
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    blur = cv2. blur(reslut, (3, 3))
    plt.figure(figsize=(18, 12))
    plt.subplot(131), plt.imshow(BGR2RGB(img_1)), plt.title('Ori')
    plt.subplot(132), plt.imshow(BGR2RGB(reslut)), plt.title('noise')
    plt.subplot(133), plt.imshow(BGR2RGB(blur)), plt.title('blur')
    plt. show()

In the above example code, we use the cv2.blur() function to perform mean filtering on the image. The first parameter is the input image and the second parameter is the size of the filter. In this example, (3, 3) is used as the size of the filter, which means that the average value of pixels is taken in a 3×3 neighborhood, and the average value is used as the value of the corresponding pixel in the output image. Finally, the original image and the filtered image are displayed using the cv2.imshow() function.

After mean filtering, most of the noise points disappear

Box filtering

Paradigm: blur = cv2.boxFilter(reslut, -1, (3, 3), normalize=True)

  • src: input image
  • ddepth: the depth of the output image, if set to -1, the output image has the same depth as the input image
  • ksize: The size of the filter window, specified as (width, height)
  • normalize: Whether to normalize the filtering results, the default is True, when it is True, it is the same as the mean filter
def BGR2RGB(img):
    """

    :param img:
    :return:
    """
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    blur = cv2.boxFilter(reslut, -1, (3, 3), normalize=False)
    plt.figure(figsize=(18, 12))
    plt.subplot(131), plt.imshow(BGR2RGB(img_1)), plt.title('Ori')
    plt.subplot(132), plt.imshow(BGR2RGB(reslut)), plt.title('noise')
    plt.subplot(133), plt.imshow(BGR2RGB(blur)), plt.title('blur')
    plt. show()

Gaussian filter

Standard paradigm: blur = cv2.GaussianBlur(reslut, (5, 5), 1)

Use the cv2.GaussianBlur() function to Gaussian filter the image. The first parameter is the input image, and the second parameter is the size of the filtering window, specified as (5, 5). The third parameter is the standard deviation of the Gaussian kernel, which is set to 1 here. A larger standard deviation produces a larger blurring effect.

def BGR2RGB(img):
    """

    :param img:
    :return:
    """
    return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    blur = cv2.GaussianBlur(reslut, (5, 5), 1)
    plt.figure(figsize=(18, 12))
    plt.subplot(131), plt.imshow(BGR2RGB(img_1)), plt.title('Ori')
    plt.subplot(132), plt.imshow(BGR2RGB(reslut)), plt.title('noise')
    plt.subplot(133), plt.imshow(BGR2RGB(blur)), plt.title('GaussianBlur')
    plt. show()

Median filter

The cv2.medianBlur(img, size) function performs median filtering on an image instead of adding noise or other filtering operations. Median filtering is a commonly used image denoising method, which uses the median value of all pixels in the filter window to replace the value of the center pixel, and size is the window size.

if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    blur = cv2.medianBlur(reslut, 5)
    plt.figure(figsize=(18, 12))
    plt.subplot(131), plt.imshow(BGR2RGB(img_1)), plt.title('Ori')
    plt.subplot(132), plt.imshow(BGR2RGB(reslut)), plt.title('noise')
    plt.subplot(133), plt.imshow(BGR2RGB(blur)), plt.title('medianBlur')
    plt. show()

For this picture, the effect of mean filtering is the best, all noise points disappear, but the image becomes too smooth

Comparison of different filtering results

if __name__ == '__main__':
    img_path_1 = 'sister.jpg'
    img_path_2 = 'baixue.png'
    ## Read BGR by default
    image_1 = read_img(img_path_1)
    image_2 = read_img(img_path_2, mode=cv2.IMREAD_GRAYSCALE)
    img_1 = cv2.resize(image_1, (512, 512))
    img_2 = cv2.resize(image_2, (512, 512))
    ## Randomly generate noise data
    noise = np.random.normal(0, 1, img_1.shape).astype(np.uint8)
    ## Add noise to the image
    reslut = noise + img_1
    blur = cv2. blur(reslut, (3, 3))
    boxFilter = cv2.boxFilter(reslut, -1, (3, 3), normalize=False)
    GaussianBlur = cv2.GaussianBlur(reslut, (5, 5), 1)
    medianBlur = cv2.medianBlur(reslut, 5)
    res = np.hstack((blur, boxFilter, GaussianBlur, medianBlur))
    img_show('All', res)

The pictures used are generated by the model. After replacing the picture path with your local path, you can run it directly. Welcome everyone to learn and communicate