I am learning OpenCV image processing 1 in Vscode (threshold processing, morphological operations [connectivity, erosion and expansion, opening and closing operations, top hat and black hat, kernel])

1. Threshold processing

阈值:指的是某一个范围内,不可逾越,不能低于的值。

For example, set the threshold to 127, then:
 Set the value of all pixels in the image with a value greater than 127 to 255.
 Set the value of all pixels in the image with a pixel value less than or equal to 127 to 0.

Insert image description here

1.1 OpenCV provides functions cv2.threshold() and functions cv2.adaptiveThreshold(), for implementing threshold processing

cv2.threshold() and cv2.adaptiveThreshold() are two functions used to implement threshold processing in OpenCV. The differences between them are as follows:

1.1.1. cv2.threshold():

This function is a global thresholding method. It converts the input image to a binary image, compares the pixel values ​​to a user-supplied threshold, and sets the pixels to a given maximum or minimum value based on the comparison. The syntax is as follows:

retval, threshold_image = cv2.threshold(src, threshold_value, max_value, threshold_type)

in:

  • retval represents the returned threshold.
  • threshold_image represents the threshold segmentation result image, which has the same size and type as the original image.
  • src: Input image, single-channel grayscale image, 8-bit or 32-bit floating point value.
  • threshold_value: Threshold value to compare pixel values ​​to.
  • max_value: The pixel value set when the pixel value is greater than the threshold.
  • threshold_type: threshold type, used to specify the threshold processing method.

Insert image description here

(1) In the functioncv2.threshold(), the parametersthreshold_type are used to specify the threshold processing method. It has the following optional threshold types:
  • cv2.THRESH_BINARY: If the pixel value is greater than the threshold, set to the maximum value, otherwise set to 0.

In 8-bit images, the maximum value is 255. Therefore, when binarizing an 8-bit grayscale image, if the threshold is set to 127, then:  All pixels greater than 127 will be processed as 255.  The remaining values ​​will be treated as 0.


  • cv2.THRESH_BINARY_INV: Contrary to cv2.THRESH_BINARY, if the pixel value is greater than the threshold, it is set to 0, otherwise it is set to the maximum value.

The anti-binarization threshold processing method for pixels is:
 For pixels whose gray value is greater than the threshold, set their value to 0.
 For pixels whose gray value is less than or equal to the threshold, set its value to 255.

  • cv2.THRESH_TRUNC: If the pixel value is greater than the threshold, set to the threshold, otherwise leave unchanged.

Truncation thresholding processing:
For example, if the threshold is selected as 127, then during truncation thresholding processing:
 For pixels with pixel values ​​greater than 127 point, its pixel value will be set to 127.
 For pixels with a pixel value less than or equal to 127, their pixel values ​​will remain changed.

  • cv2.THRESH_TOZERO: If the pixel value is greater than the threshold, leave it unchanged, otherwise set to 0.

Low threshold zero processing
For example, if the threshold is selected as 127, then:
 For pixels with a pixel value greater than 127, the pixel value will be Keep changing.
 For pixels whose pixel value is less than or equal to 127, their pixel value will be set to 0.

  • cv2.THRESH_TOZERO_INV: Contrary to cv2.THRESH_TOZERO, if the pixel value is greater than the threshold, it is set to 0, otherwise it remains unchanged.

Super threshold zero processing
For example, if the threshold is selected as 127, then:
 For pixels with a pixel value greater than 127, their values ​​will be Set to 0.
 For pixels with a pixel value less than or equal to 127, their values ​​will remain changed.

These threshold types can be selected based on specific application requirements. For example, if you want to convert an image to a binary image (black and white image), you can use cv2.THRESH_BINARY or cv2.THRESH_BINARY_INV. If you only want to keep the lighter parts of the image and make the rest black, use cv2.THRESH_TRUNC.

(2)Code
# 二值化阈值处理会将原始图像处理为仅有两个值的二值图像,
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

x=np.random.randint(0,256,size=(4,4),dtype=np.uint8)
x

Insert image description here

ret,dst=cv.threshold(x,thresh=127,maxval=255,type=cv.THRESH_BINARY)
ret=127.0
dst

Insert image description here

(3)Image part

Insert image description here

Insert image description here
Insert image description here
inverse binary value
Insert image description here

1.1.2. cv2.adaptiveThreshold():

This function is an adaptive thresholding method. It adaptively selects thresholds for pixel segmentation based on the statistical characteristics of different areas of the image. The syntax is as follows:

This approach allows the use of different thresholds in different areas of the image, thereby improving adaptability to local changes.

threshold_image = cv2.adaptiveThreshold(src, max_value, adaptive_method, threshold_type, block_size, constant)

in:

  • src: input image, single-channel grayscale image.
  • max_value: The pixel value set when the pixel value is greater than the threshold.
  • adaptive_method: adaptive threshold algorithm, optional values ​​include cv2.ADAPTIVE_THRESH_MEAN_C and cv2.ADAPTIVE_THRESH_GAUSSIAN_C.
  • threshold_type: threshold type, used to specify the threshold processing method.
  • block_size: The pixel area size used when calculating the threshold.
  • constant: A constant subtracted from the calculated mean or weighted mean.

 cv2.ADAPTIVE_THRESH_MEAN_C: The weight values ​​of all pixels in the neighborhood are consistent.
 cv2.ADAPTIVE_THRESH_GAUSSIAN_C: It is related to the distance from each pixel point in the neighborhood to the center point. The weight value of each point is obtained through
Gaussian equation.
Summary:

  • cv2.threshold() is a global thresholding method that applies to most areas in the image. It applies the same threshold to the entire image.
  • cv2.adaptiveThreshold() is an adaptive thresholding method suitable for different areas in the image with different lighting conditions and contrast. It selects the threshold based on the local characteristics of the image.

1.2 Otsu 处り

In image processing, thresholding is the process of converting a grayscale image into a binary image, where pixels are classified into two categories: background and foreground based on a certain threshold. Normally, we can manually select a threshold for binarization. But choosing an appropriate threshold can be difficult for different images.

Otsu processing automatically determines the optimal threshold by minimizing within-class variance and maximizing between-class variance. It uses the histogram information of the image to find the threshold that best distinguishes the foreground from the background. This allows Otsu processing to better adapt to the characteristics of different images and produce more accurate results.

Using the cv2.THRESH_OTSU flag in OpenCV, Otsu processing can be easily applied to determine the optimal threshold for the image and binarize the image.

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

img = cv2.imread('Pic/cc.jpg', 0)

# 使用Otsu's方法进行阈值处理
ret, otsu_thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# 使用cv2.THRESH_BINARY进行阈值处理
_, binary_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# 使用cv2.THRESH_TRUNC进行阈值处理
_, trunc_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)

# 使用cv2.THRESH_TOZERO进行阈值处理
_, tozero_thresh = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)

# 绘制结果图像
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(binary_thresh, cmap='gray')
plt.title('cv2.THRESH_BINARY'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(otsu_thresh, cmap='gray')
plt.title('cv2.THRESH_BINARY + cv2.THRESH_OTSU'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(tozero_thresh, cmap='gray')
plt.title('cv2.THRESH_TOZERO'), plt.xticks([]), plt.yticks([])

plt.show()

Insert image description here

2. Morphological operations

The category of morphology (English morphology, German morphologie) comes from the Greek word morphe. Goethe was the first to advocate it in his biological research. Goethe came up with this idea because he was dissatisfied with the excessive rational analysis tendency in natural science. Planning and Envisioning.
[Means "shape" or "structure". In the fields of image processing and computer vision, morphology generally refers to a set of mathematical methods for analyzing and processing the shape and structure of objects in images. 】

The goal of morphological operations is to extract key information by changing the shape and structure of the image, such as removing noise, connecting objects, separating objects, etc. Morphological operations are based on set theoretical and topological concepts in images, where shape and structure are manipulated through templates called "structural elements". A structuring element is a small, predefined shape, similar to a filter, that is moved over the image and compared to corresponding parts of the image.

Morphological operations have wide applications in image processing, especially in tasks such as image segmentation, feature extraction, and object recognition. Erosion and dilation are the basic building blocks of morphological operations, while opening and closing operations are combinations of these basic operations and are used to solve more complex problems. There are also different forms of operations such as morphological gradient operation, top hat operation (top hat operation), and black hat operation. These operations are useful for processing images with objects of different shapes, sizes, and orientations.

Morphological processing has very important applications in the fields of visual detection, text recognition, medical image processing, image compression and coding, etc.

2.1 Connectivity

In image processing and computer vision, "connectivity" refers to the connectivity or interconnectedness between pixels. It involves the connection relationship between regions, objects or pixel collections in the image.

Conditions for judging whether two pixels are connected:
(1)Adjacent positions: two Pixels must be spatially adjacent, that is, their positions in the image are adjacent.
(2) The grayscale values ​​are the same or similar: For grayscale images, the grayscale values ​​​​of two pixels are usually Need to be the same or similar.

2.1.1 Neighbor species

Because in an image, the pixel we often say is its smallest indivisible unit. It represents the information of a certain area of ​​the image, and the information it contains is related to the color and gray value. It is the arrangement of these small squares that constitutes the "information" we see in computer vision.

  1. 4-adjacency:
    In 4-adjacency, the adjacent pixels of a pixel include its upper, lower, left, and right directions. of pixels. This means that a pixel is adjacent to its four adjacent pixels above, below, left, and right.

    像素p(x,y)的4邻域是: (x+1,y); (x-1,y); (x,y+1); (x,y-1),
    	用N4(p)表示像素p的4邻接
    
0  1  0
1  x  1   (x表示中心像素)
0  1  0
  1. 8-contact:

. In 8-adjacency, the adjacent pixels of a pixel include the pixels in the four directions above, below, left, and right, as well as the four pixels in the diagonal direction. This means that a pixel is adjacent to its eight neighboring pixels above, below, left, right, and diagonally.

像素p(x,y)的8邻域是: 4邻域的点 +D邻域的点,
	用Ng(p)表示像素p的8邻域连通性是描述区域和边界的重要概念
1  1  1
1  x  1   (x表示中心像素)
1  1  1
  1. "D-adjacency"

Usually refers to diagonal adjacency, that is, around a pixel, in addition to the four directions of up, down, left, and right, it also includes the four directions in the diagonal direction. This is different from 8-adjacency, which considers adjacent pixels in the up, down, left, right and diagonal directions at the same time, while D-adjacency refers specifically to the diagonal direction.

像素pix,y)的D邻域是:对角上的点(x+1,y+1); (x+1,y-1); (x-1,y+1); (x-1,y-1),
	用Np(p)表示像素p的D邻域

In D-adjacency, the adjacent pixels of a pixel include the following eight directions:

1  0  1
0  x  0   (x表示中心像素)
1  0  1

2.1.2 Types of connectivity (3 types)

  1. 4-connected: Two pixels p and q are said to be 4-connected, if q is in the 4-neighborhood (upper, lower, left, right) of p.

  2. 8-connected: Two pixels p and q are said to be 8-connected if q is in the 8-neighborhood of p (including the diagonal direction).

  3. m connectivity: m connectivity is a hybrid connectivity definition. Two pixels p and q are said to be m-connected if one of the following conditions is true:

    • q is in the 4-neighborhood of p (4-connectivity condition).
    • q is in the D neighborhood of p, and the 4-neighborhood of p does not intersect with the 4-neighborhood of q (that is, there are no common pixels, or there are no pixels with value V between the two).

This definition of hybrid connectivity allows judging whether two pixels are connected through the conditions of 4-connectivity and 8-connectivity, while introducing some other restrictions to ensure that the connection is valid. The definition of m-connectivity may be more flexible in some image processing tasks, allowing greater flexibility.

2.2 Corrosion and expansion

These two operations can be understood in the following way:

Erosion: Just like the sea water on the beach slowly erodes the sand pile, making it smaller.
Expansion: Like adding some sand to a pile of sand to make it larger. ’

Erosion and dilation are two basic operations in morphological operations. They are often used to adjust the foreground and background in image processing, as well as change the shape and structure of objects. Both operations are typically used with structuring elements.

2.2.1 Dilation:cv2.dilate

  • Principle of operation: By sliding structural elements, the highlighted area in the image is expanded, making the highlighted area in the rendering larger than the original image.
  • Effect: Connect adjacent highlighted areas, fill small gaps, and increase the white area in the image.
  • Essence: is an operation to find the local maximum.
(1) Function prototype and usage
cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

cv.dilateIs one of the functions in the OpenCV library used for image dilation. Dilation is a type of morphological operation that moves a structuring element (also called a kernel or kernel) over all pixels in an image to set the pixel value to the maximum value within its neighborhood. This helps to enlarge the object, connect disconnected parts of the object, and emphasize the edges of the object.

The following is the general form and parameter description of the cv.dilate function:

  • src: Input image, usually a grayscale image.
  • kernel: Structural element (kernel), which is a small matrix that moves over the image. It can be in the shape of rectangle, ellipse, cross etc. You can use cv.getStructuringElement() to create structural elements of different shapes and sizes.
  • dst: Output image, of the same type and size as the input image. If not provided, the function modifies the original image.
  • anchor: The anchor point of the structural element. It indicates the central position of a structural element, usually at the center of the structural element. The default value is (-1, -1), which means the anchor point is at the center of the structural element.
  • iterations: Number of iterations for expansion. Default is 1.
  • borderType: Image boundary processing type. The default is cv.BORDER_CONSTANT, which means filling the boundary with a constant. Other options are available, such as cv.BORDER_REPLICATE or cv.BORDER_REFLECT.
  • borderValue: Constant value to use when padding the boundary with constants, defaults to 0.

Here is a simple example:

import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行膨胀操作
dilated_image = cv.dilate(image, kernel, iterations=1)

# 显示原始图像和膨胀后的图像
cv.imshow('Original Image', image)
cv.imshow('Dilated Image', dilated_image)
cv.waitKey(0)
cv.destroyAllWindows()

In this example, thecv.dilate function performs a dilation operation on the input image using a 3x3 rectangular structuring element. You can adjust the size and shape of structural elements, as well as the number of iterations, to achieve different effects as needed.

(2) Three parameters commonly used in Py
import cv2 as cv
cv.dilate(img,kernel,iterations)

kernel - core structure
iterations - number of expansions, default is 1

(3) Understand the effect of expansion

The expansion operation is the opposite of corrosion. It can expand the boundary of the object outward by a certain distance and merge the background points in contact with the object into the object.
To increase the size of the object. target and fill the holes in the target.

	增大目标并添补孔洞:膨胀操作可以填充物体中的小孔洞或细小空洞。
当物体内部存在一些细小的空隙或孔洞时,膨胀操作会使物体的边界向外膨胀,将与这些孔洞相邻的背景像素合并到物体中,从而填补这些孔洞,使得目标变得更大且更完整
	将背景点合并到物体中:膨胀操作会扩张物体边界,使物体的边界向外延伸一定的距离。
在这个过程中,原本与物体接触的背景区域的像素会被合并到物体中。这意味着物体的边界会变得更加光滑,原本与背景接触的一些像素点会被认为是物体的一部分,从而扩大了物体的尺寸。

2.2.2 Corrosion:cv2.erode

  • Principle of operation: By sliding structural elements, the highlighted area in the image is reduced, making the highlighted area in the rendering smaller than the original image.
  • Effect: Eliminate small objects, fine structures and noise, reducing the white area in the image.
  • Essence: is an operation to find the local minimum.
(1) Function prototype and usage

cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

Erosion is a morphological operation that moves a structuring element (also called a core or kernel) over all pixels on an image, placing the pixel value at the minimum value within its neighborhood. This helps eliminate small objects in images, smooth object boundaries, and shrink or eliminate objects.

The following is the general form and parameter description of the cv.erode function:

cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
  • src: Input image, usually a grayscale image.
  • kernel: Structural element (kernel), which is a small matrix that moves over the image. It can be in the shape of rectangle, ellipse, cross etc. You can use cv.getStructuringElement() to create structural elements of different shapes and sizes.
  • dst: Output image, of the same type and size as the input image. If not provided, the function modifies the original image.
  • anchor: The anchor point of the structural element. It indicates the central position of a structural element, usually at the center of the structural element. The default value is (-1, -1), which means the anchor point is at the center of the structural element.
  • iterations: Number of iterations of corrosion. Default is 1.
  • borderType: Image boundary processing type. The default is cv.BORDER_CONSTANT, which means filling the boundary with a constant. Other options are available, such as cv.BORDER_REPLICATE or cv.BORDER_REFLECT.
  • borderValue: Constant value to use when padding the boundary with constants, defaults to 0.
import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行腐蚀操作
eroded_image = cv.erode(image, kernel, iterations=1)

# 显示原始图像和腐蚀后的图像
cv.imshow('Original Image', image)
cv.imshow('Eroded Image', eroded_image)
cv.waitKey(0)
cv.destroyAllWindows()

In this example, thecv.erode function performs an erosion operation on the input image using a 3x3 rectangular structuring element. You can adjust the size and shape of structural elements, as well as the number of iterations, to achieve different effects as needed.

(2) Three parameters commonly used in Py
import cv2 as cv
cv.erode(img,kernel,iterations)

kernel - core structure
iterations - number of corrosions, default is 1

(3) Understand the effects of corrosion
	消除边界点:腐蚀操作会将物体边界的像素“侵蚀”,也就是将物体边界向内部缩小一定的距离。
这会导致物体边界的像素被消除或减少,从而使物体整体变小。
	缩小目标:可以通过腐蚀来减小物体的大小以去除不必要的细节。
	消除小噪声点:小的噪声点会被消除掉,因为它们被看作是物体边界的一部分,随着边界的腐蚀而消失。

2.2.3 Corrosion and expansion code and picture demonstration

(1) Ordinary

Insert image description here


import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt

#1.读取图像

img = cv.imread("img/test_img.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("原图")

axes[1].imshow(erpsion[:, :, ::-1])
axes[1].set_title("腐蚀")

axes[2].imshow(dilate[:, :, ::-1])
axes[2].set_title("膨胀")

plt.show()

(2) Three photos

These are three different pictures for comparison. The ones circled are not OpenCV annotations, but marks I made myself for comparison.
Insert image description here
Insert image description here
Insert image description here


import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt

#1.读取图像

img = cv.imread("img/work1127.jpg")
## 腐蚀和膨胀针对于高亮区域进行的                                                                          
# img = cv.imread("img/useCvOpenxx.jpg")
# img = cv.imread("img/usecvClose.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("原图")

axes[1].imshow(erpsion[:, :, ::-1])
axes[1].set_title("腐蚀")

axes[2].imshow(dilate[:, :, ::-1])
axes[2].set_title("膨胀")

plt.show()

2.2.4 Morphological gradient: difference between expansion and corrosion

Insert image description here

import numpy as  np
import cv2 as cv
import matplotlib.pyplot as plt
#1.读取图像
## 腐蚀和膨胀针对于高亮区域进行的                                                                          
img = cv.imread("img/usecvClose.jpg")
#2.Kernel 核结构
kernel = np.ones((5, 5), np.uint8)
#3.图像的腐蚀和膨胀
erpsion = cv.erode(img, kernel)
dilate = cv.dilate(img, kernel)

plt.imshow(dilate-erpsion)
plt.show()

or function

Morphological gradient operations can be implemented by setting the operation type parameter op of the function cv2.morphologyEx() to "cv2.MORPH_GRADIENT". Its grammatical structure is as follows:

result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

Insert image description here

2.3 Opening and closing operations

Opening operations and closing operations process corrosion and expansion in a certain order. But the two are not reversible, that is, opening first and then closing cannot get the original image.

2.3.1 opening operation

The opening operation is to erode first and then expand. Its function is to separate objects and eliminate small areas. Features: Eliminate noise and remove small interference blocks without affecting the original image.

Open operation: Corrosion first, then expansion. It is able to eliminate small noises and interferences, separate objects,
without affecting the structure of the original image. This operation is particularly useful for removing small objects, smoothing borders and reducing fine details

2.3.2 Closing operation closing

The closing operation is the opposite of the opening operation. It expands first and then corrodes.
The function is to eliminate holes in the "closed" object
Features: Can Fill closed area.

Closed operation: dilation first, then corrosion. Closure operations are often used to fill holes inside objects or connect discontinuities between objects.
It can close small holes inside the object, fill the closed area, and maintain the overall shape of the object

2.3.3 General morphological functions

(1) Commonly used parameters:
import cv2 as cv
cv.morphologyEx(src, op, kernel)

src: image to be processed
op: processing method: if the opening operation is performed, set to cv.MORPH_OPEN,
if the closing operation is performed , then set to cv.MORPH_CLOSE
Kernel: core structure

(2) Complete

Morphological operation is a basic operation in image processing, which includes erosion, expansion, opening operation, closing operation, etc. In OpenCV, there is a general morphological operation function cv.morphologyEx, which can perform different forms of morphological operations, including corrosion, expansion, opening operations, closing operations, etc.

cv.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
  • src: Input image, usually a grayscale image.

  • op: Type of morphological operation, which can be one of the following:

    • cv.MORPH_ERODE: Corrosion
    • cv.MORPH_DILATE: expansion
    • cv.MORPH_OPEN: Open operation
    • cv.MORPH_CLOSE: closed operation
    • cv.MORPH_GRADIENT: Gradient operation
    • cv.MORPH_TOPHAT: top hat operation
    • cv.MORPH_BLACKHAT: black hat operation
  • kernel: Structural element (kernel), which is a small matrix that moves over the image. You can use cv.getStructuringElement() to create structural elements of different shapes and sizes.

  • dst: Output image, of the same type and size as the input image. If not provided, the function modifies the original image.

  • anchor: The anchor point of the structural element. It indicates the central position of a structural element, usually at the center of the structural element. The default value is (-1, -1), which means the anchor point is at the center of the structural element.

  • iterations: Number of iterations of the operation. Default is 1.

  • borderType: Image boundary processing type. The default is cv.BORDER_CONSTANT, which means filling the boundary with a constant. Other options are available, such as cv.BORDER_REPLICATE or cv.BORDER_REFLECT.

  • borderValue: Constant value to use when padding the boundary with constants, defaults to 0.

The following is a simple example demonstrating how to use the cv.morphologyEx function to perform the opening operation:

import cv2 as cv
import numpy as np

# 读取图像
image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)

# 创建一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)

# 进行开运算
opened_image = cv.morphologyEx(image, cv.MORPH_OPEN, kernel)

# 显示原始图像和开运算后的图像
cv.imshow('Original Image', image)
cv.imshow('Opened Image', opened_image)
cv.waitKey(0)
cv.destroyAllWindows()

By adjusting the operation type and structural elements, you can perform other morphological operations such as dilation, closing operations, etc.

(3) Precautions

Insert image description here

In the example, the open operation (#MORPH_OPEN) with two iterations is equivalent to apply in sequence:
Erosion->Erosion->Expansion->Expansion (while Not erosion->expansion->erosion->expansion).

2.3.4 Code and demonstration

Insert image description here

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 读取两张图像
imgCvOpen = cv.imread("img/useCvOpenxx.jpg")
imgCvClose = cv.imread("img/usecvClose.jpg")

# 创建核结构(这里创建了一个10x10的全为1的二维数组,作为形态学运算的核结构)
kernel = np.ones((10, 10), np.uint8)

# 执行开运算和闭运算
# 开运算:消除周围的噪点
cvOpen = cv.morphologyEx(imgCvOpen, cv.MORPH_OPEN, kernel)
# 闭运算:填充闭合区域的孔洞
cvClose = cv.morphologyEx(imgCvClose, cv.MORPH_CLOSE, kernel)

# 使用 Matplotlib 显示图像
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))

# 显示原始图像和处理后的图像
axes[0, 0].imshow(imgCvOpen[:, :, ::-1])
axes[0, 0].set_title("imgCvOpen原图Img")
axes[0, 1].imshow(cvOpen[:, :, ::-1])
axes[0, 1].set_title("cvOpenImg")

axes[1, 0].imshow(imgCvClose[:, :, ::-1])
axes[1, 0].set_title("imgCvClose原图Img")
axes[1, 1].imshow(cvClose[:, :, ::-1])
axes[1, 1].set_title("cvCloseImg")

plt.show()

2.4 Top hat and black hat

Top Hat and Black Hat operations are two special forms of morphological operations. They are usually used for image detail enhancement and object detection.

2.4.1 Top-Hat Transformation

The difference between the original image and the result image of the "open operation"

dst=tophat(src,element)=src-open(src,element)

Insert image description here

The top hat operation is the difference between the original image and the opening operation, which is usually used to remove noise in the image. The top hat operation highlights small bright areas in the image, helping to emphasize some details.

礼帽运算是原始图像与开运算结果之差的操作,

The mathematical expression of is dst = tophat(src, element) = src - open(src, element).
It highlights areas that are lighter than the surrounding areas of the original image.
It emphasizes edges or areas of small brightness changes in the image.
When the background is relatively bright and small items or specific areas are dark, using the top hat operation can help extract these small dark areas.
This operation Depends on the selected core size.

2.4.2 Black-Hat Transformation

It is the difference between the result image of "closed operation" and the original image.

dst=blackhat(src,element)=close(src,element)-src

Insert image description here
The black hat operation is the difference between the closed operation and the original image, where the closed operation is usually used to fill holes in the image. Black hat operations highlight small dark areas in an image, helping to emphasize some details.

黑帽运算是闭运算结果与原始图像之差的操作,

The mathematical expression is dst = blackhat(src, element) = close(src, element) - src.
It highlights areas that are darker than the surrounding areas of the original image, emphasizing the presence of edges or small dark areas in the image.
When the background is relatively dark, but there are small dark areas or noise, using black hat operations can help separate these dark areas.
Similarly, this operation is the same as Dependent on the selected core size.

2.4.3 Code and picture demonstration


import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

imgOpen=cv.imread("img/useCvOpenxx.jpg")
imgClose=cv.imread("img/usecvClose.jpg")

#核结构
kernel=np.ones((10,10),dtype=np.uint8)

#礼帽和黑帽
cvOpen1=cv.morphologyEx(imgOpen,cv.MORPH_TOPHAT,kernel)
cvClose1=cv.morphologyEx(imgClose,cv.MORPH_BLACKHAT,kernel)

# 显示
fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(10,8))
axes[0,0].imshow(imgOpen)
axes[0,0].set_title("imgOpen")
axes[0, 1].imshow(cvOpen[:, :, ::-1])
axes[0, 1].set_title("cvOpenImg")
axes[0,2].imshow(cvOpen1)
axes[0,2].set_title("cvOpen1")

axes[1,0].imshow(cvClose1)
axes[1,0].set_title("imgClose1")
axes[1, 1].imshow(cvClose[:, :, ::-1])
axes[1, 1].set_title("cvCloseImg")
axes[1,2].imshow(cvClose1)
axes[1,2].set_title("cvClose1")
plt.show()

Insert image description here

2.5 Kernel function

In morphological operations, the kernel function (also called a structuring element or kernel) is a small matrix that defines the shape and size of the morphological operation. Different kernel functions will produce different effects, so choosing an appropriate kernel function is very important to obtain the desired morphological effects.

In OpenCV, you can use the cv.getStructuringElement() function to create kernel functions of different shapes and sizes. This function returns a binary matrix of specified shape and size for use as a kernel function for morphological operations.

The following is the general form of the cv.getStructuringElement() function:

cv.getStructuringElement(shape, ksize[, anchor])
  • shape: The shape of the structural element, which can be one of the following:
    • cv.MORPH_RECT: Rectangular structural element
    • cv.MORPH_CROSS: Cross-shaped structural element
    • cv.MORPH_ELLIPSE: Oval structural element
  • ksize: The size of the structure element, usually a tuple (rows, cols), specifying the number of rows and columns.
  • anchor: The anchor point of the structural element. It indicates the central position of a structural element, usually at the center of the structural element. The default value is (-1, -1), which means the anchor point is at the center of the structural element.

Here are some examples of how to create kernels of different shapes and sizes:

import cv2 as cv
import numpy as np

# 创建一个 3x3 的矩形结构元素
rect_kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))

# 创建一个 5x5 的十字形结构元素
cross_kernel = cv.getStructuringElement(cv.MORPH_CROSS, (5, 5))

# 创建一个 7x7 的椭圆形结构元素
ellipse_kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (7, 7))

These kernel functions can be used for morphological operations, such as erosion, expansion, opening operations, closing operations, etc. For example, you can pass these kernel functions to cv.erode, cv.dilate, cv.morphologyEx etc. 4> Parameters. kernel

subtle changes

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 读取图像
image = cv.imread('img/useCvOpenxx.jpg', cv.IMREAD_GRAYSCALE)

# 创建不同形状和大小的核函数
rect_kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
cross_kernel = cv.getStructuringElement(cv.MORPH_CROSS, (5, 5))
ellipse_kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (7, 7))

# 进行腐蚀操作
eroded_rect = cv.erode(image, rect_kernel)
eroded_cross = cv.erode(image, cross_kernel)
eroded_ellipse = cv.erode(image, ellipse_kernel)

# 进行膨胀操作
dilated_rect = cv.dilate(image, rect_kernel)
dilated_cross = cv.dilate(image, cross_kernel)
dilated_ellipse = cv.dilate(image, ellipse_kernel)

# 设置中文字体
font = FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc", size=12)

# 显示原始图像和不同核函数下的腐蚀结果和膨胀结果
plt.figure(figsize=(12, 8))

plt.subplot(3, 3, 1), plt.imshow(image, cmap='gray'), plt.title('原始图像', fontproperties=font)

plt.subplot(3, 3, 2), plt.imshow(eroded_rect, cmap='gray'), plt.title('矩形核腐蚀', fontproperties=font)
plt.subplot(3, 3, 3), plt.imshow(dilated_rect, cmap='gray'), plt.title('矩形核膨胀', fontproperties=font)

plt.subplot(3, 3, 5), plt.imshow(eroded_cross, cmap='gray'), plt.title('十字核腐蚀', fontproperties=font)
plt.subplot(3, 3, 6), plt.imshow(dilated_cross, cmap='gray'), plt.title('十字核膨胀', fontproperties=font)

plt.subplot(3, 3, 8), plt.imshow(eroded_ellipse, cmap='gray'), plt.title('椭圆核腐蚀', fontproperties=font)
plt.subplot(3, 3, 9), plt.imshow(dilated_ellipse, cmap='gray'), plt.title('椭圆核膨胀', fontproperties=font)

plt.show()

Insert image description here

Guess you like

Origin blog.csdn.net/m0_74154295/article/details/134608609