使用 OpenCV 的“findContours()”进行基于 4 连通性的轮廓检测

Contour detection based on 4-connectivity using `findContours()` from OpenCV

提问人:Walrus 提问时间:10/18/2023 更新时间:10/18/2023 访问量:71

问:

OpenCV 库中的函数不允许您根据 4 连接自定义轮廓的选择。我检查了一张测试图像:test image我们可以调整此功能的所有模式,它们似乎都使用 8 连接进行轮廓检测,因为它们将图像中的物体选择为 1 个完整的轮廓。 如果我们使用 4 连通性,则不会考虑对角线上白色像素的相邻点,该函数将在图像中选择两个轮廓,这正是我想要达到的。findContours()

我尝试将不同的参数发送到 ,我阅读了文档和论坛,但当我意识到 OpenCV 无法实现 4 连接时。然后我在 python 中编写了基于 4 连通性选择轮廓的幼稚算法,但我在计算所选轮廓和嵌套轮廓的数量时遇到了困难。findContours()

请告诉我我可以用什么来解决我的问题?如果 OpenCV 库中有任何其他函数可以帮助我根据 4 连接选择轮廓,或者我是否必须自己编写算法?在我的项目中,我需要选择 1 和 2 层次结构的轮廓并计算它们的数量。

我的代码:

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

def is_4_connected(pixel, neighbor):
    return np.abs(pixel - neighbor) == 1

# uploading file with data
with open('text_data.txt', 'r') as file:
    lines = file.readlines()
    data = [[float(value) for value in line.strip().split()] for line in lines]

# Converting data to NumPy array
image = np.array(data)
max_value = np.amax(image)
threshold = max_value / 2
# Image binarization (threshold value can be adjusted)
binary_image = np.where(image < threshold, 0, 1)
contour_count = np.zeros((255, 255))
c = []
# Creating an image with contours based on 4-connectivity
contour_image = np.zeros_like(binary_image)
binary_image = binary_image.astype(np.uint8)
for y in range(1, binary_image.shape[0] - 1):
        c.append(len(contour_count[y]))
        for x in range(1, binary_image.shape[1] - 1):
                if binary_image[y, x] == 0:
                        if binary_image[y - 1, x] == 1 or binary_image[y + 1, x] == 1 or binary_image[y, x - 1] == 1 or binary_image[y, x + 1] == 1:
                                contour_image[y, x] = 1
                elif binary_image[y, x] == 1:
                # Checking 4-connectivity with neighboring pixels
                        if not is_4_connected(binary_image[y, x], binary_image[y - 1, x]) and \
                        not is_4_connected(binary_image[y, x], binary_image[y + 1, x]) and \
                        not is_4_connected(binary_image[y, x], binary_image[y, x - 1]) and \
                        not is_4_connected(binary_image[y, x], binary_image[y, x + 1]):
                     # If there is no 4-connectivity with any neighboring pixel, it is a new contour
                                        contour_count[y][x] = 1
        
        
        
        
contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
level1_count = 0
level2_count = 0
for i, cnt in enumerate(contours):
        if hierarchy[0][i][3] == -1:
# First level contour
                level1_count += 1
        else:
# 2nd level contour
                level2_count += 1

# Print result
print("number of 1st level contours:", len(c))
print("number of 2nd level contours:", level2_count)
 
# Displaying an image with outlines
plt.imshow(contour_image, cmap='gray')
plt.show()
Python OpenCV 轮廓 检测 数据处理

评论

2赞 fana 10/18/2023
功能可以选择连接8或4。那么,先使用它,然后提取每个区域的轮廓是可以理解的吗?(但我不知道如何识别层次结构)connectedComponents()

答: 暂无答案