[OpenCV implements images: image processing techniques, morphological filtering corrosion operation, RuntimeError: sequence argument must have length equal to input rank]]

Article directory

    • summary
    • Corrosion operating principle
    • Select structural elements
    • Corrosion operation effect
    • summary

Summary

Tip: You can add a technical summary here

For example:

The development history of openAI’s GPT large model.

Principle of corrosion operation

Erosion is an operation in morphological image processing that finely shrinks objects in an image by gradually removing pixels from the edges of the image. The principle of the erosion operation is to set the value of each pixel to the minimum value of all pixels in the surrounding area by considering the surrounding area of each pixel. In a binary image, if there is a pixel with a value of 0 in the surrounding area, the value of the pixel will be set to 0. Simply put, the erosion operation can make the objects in the image smaller and remove pixels on the boundaries of the objects, thereby achieving refined processing of the image.

First import our image for today

import numpy as np
import matplotlib.pyplot as plt
# Define the image
original_image = np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 1, 1, 1, 0, 0],
                           [0, 0, 1, 1, 1, 1, 0, 0],
                           [0, 1, 1, 1, 1, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0]])

plt.figure(figsize=(10,10))
plt.imshow(original_image, cmap='gray', extent=[0, 8, 0, 8])
plt.title('Original Image', fontsize=20);
plt.show()

Select structured elements

import numpy as np
import matplotlib.pyplot as plt
# Define the image

# Define the structuring element
selem_cross = np.array([[0,1,0],
                        [1,1,1],
                        [0,1,0]])
plt.figure(figsize=(9,9))
plt.imshow(selem_cross, cmap='gray')
plt.title('Structuring Element: Cross', fontsize=20);
plt.show()

Corrosion operation effect

After the above operations, we define the original image and the corresponding structured template element that need to be operated, and then we use the function apply_erosion to apply the above structured template element to the corresponding image. The code is as follows:

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import morphology

#define original image
original_image = np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 1, 1, 1, 0, 0],
                           [0, 0, 1, 1, 1, 1, 0, 0],
                           [0, 1, 1, 1, 1, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0]])

# Define structural elements (3x3 cross shape)
selem_cross = np.array([[0, 1, 0],
                        [1, 1, 1],
                        [0, 1, 0]])

# Function to perform corrosion operations
def apply_erosion(image, selem):
    eroded_image = morphology.grey_erosion(image, structure=selem) # Use the structure parameter to pass structured elements
    fig, axes = plt.subplots(1, 3, figsize=(15, 10))
    ax = axes.ravel()
    ax[0].imshow(selem, cmap='gray', extent=[0, selem.shape[1], 0, selem.shape[0]])
    ax[0].set_title('Structuring Element', fontsize=20)
    ax[1].imshow(image, cmap='gray', extent=[0, image.shape[1], 0, image.shape[0]])
    ax[1].set_title('Original Image', fontsize=20)
    ax[2].imshow(eroded_image, cmap='gray', extent=[0, image.shape[1], 0, image.shape[0]])
    ax[2].set_title('Eroded Image', fontsize=20)
    plt.tight_layout()
    plt.show()

#Apply erosion operation to original image
apply_erosion(original_image, selem_cross)


Error encountered:

D:\anaconda\envs\yolov5\python.exe E:\yolo project\Opencv-project-main\Opencv-project-main\CVZone\guangliu\four.py
E:\yolo project\Opencv-project-main\Opencv-project-main\CVZone\guangliu\four.py:22: DeprecationWarning: Please use `grey_erosion` from the `scipy.ndimage` namespace, the `scipy.ndimage. morphology` namespace is deprecated.
  eroded_image = morphology.grey_erosion(image, selem)
Traceback (most recent call last):
  File "E:\yolo project\Opencv-project-main\Opencv-project-main\CVZone\guangliu\four.py", line 35, in <module>
    apply_erosion(original_image, selem_cross)
  File "E:\yolo project\Opencv-project-main\Opencv-project-main\CVZone\guangliu\four.py", line 22, in apply_erosion
    eroded_image = morphology.grey_erosion(image, selem)
  File "D:\anaconda\envs\yolov5\lib\site-packages\scipy\
dimage\_morphology.py", line 1229, in gray_erosion
    return _filters._min_or_max_filter(input, size, footprint, structure,
  File "D:\anaconda\envs\yolov5\lib\site-packages\scipy\
dimage\_filters.py", line 1149, in _min_or_max_filter
    sizes = _ni_support._normalize_sequence(size, input.ndim)
  File "D:\anaconda\envs\yolov5\lib\site-packages\scipy\
dimage\_ni_support.py", line 67, in _normalize_sequence
    raise RuntimeError(err)
RuntimeError: sequence argument must have length equal to input rank

Process finished with exit code 1

Modified part:

This error is caused by the fact that the shape of the structural element selem passed to the morphology.grey_erosion function does not meet the requirements of the function.

According to the error message, the sequence argument must have length equal to input rank, which means that the dimensions of the structured element (i.e. the length of the shape) should be equal to the dimensions of the input image. The original image original_image is an 8×8 two-dimensional array, so the shape of the structured element should also be a 2×2 two-dimensional array.

eroded_image = morphology.grey_erosion(image, structure=selem) # Use the structure parameter to pass structured elements

use:

 eroded_image = morphology.grey_erosion(image, selem)

Summary

For example, if you choose to use a square as a structuring element, it will take into account all neighboring pixels around the pixel. This means that if the size of the structural elements is larger, the erosion operation will shrink the object in the image more significantly. Conversely, if you select a smaller structural element, the effect of the erosion operation will be more subtle and may only remove pixels from the object’s edges.

In addition, you can also choose circular structural elements, which will have a more even range of influence and are suitable for situations where the shape of the object needs to be maintained. At the same time, custom-shaped structural elements can also be created according to specific needs to meet the requirements of specific morphological operations.
Square structural elements:

# Define the structuring element
selem_square = np.array([[0,0,0,0],
                         [0,1,1,0],
                         [0,1,1,0],
                         [0,0,0,0]])

# Apply erosion on the original image with square structuring element
apply_erosion(original_image, selem_square)

Complete code:

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import morphology

#define original image
original_image = np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 1, 1, 1, 0, 0],
                           [0, 0, 1, 1, 1, 1, 0, 0],
                           [0, 1, 1, 1, 1, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 1, 1, 1, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0]])

# Define structural elements (3x3 cross shape)

# Define the structuring element
selem_square = np.array([[0,0,0,0],
                         [0,1,1,0],
                         [0,1,1,0],
                         [0,0,0,0]])

# Apply erosion on the original image with square structuring element

# Function to perform corrosion operations
def apply_erosion(image, selem):
    eroded_image = morphology.grey_erosion(image, structure=selem) # Use the structure parameter to pass structured elements
    fig, axes = plt.subplots(1, 3, figsize=(15, 10))
    ax = axes.ravel()
    ax[0].imshow(selem, cmap='gray', extent=[0, selem.shape[1], 0, selem.shape[0]])
    ax[0].set_title('Structuring Element', fontsize=20)
    ax[1].imshow(image, cmap='gray', extent=[0, image.shape[1], 0, image.shape[0]])
    ax[1].set_title('Original Image', fontsize=20)
    ax[2].imshow(eroded_image, cmap='gray', extent=[0, image.shape[1], 0, image.shape[0]])
    ax[2].set_title('Eroded Image', fontsize=20)
    plt.tight_layout()
    plt.show()

#Apply erosion operation to original image
apply_erosion(original_image, selem_square)