我有一个如下所示的图像(该图像是我对原始图像进行预处理的结果):
我想做的是检测 黑色区域 以 2 为界的轮廓白色区域(请注意,白色区域并不总是实心的,顶部可能有 2、3... 不连续的白色区域 - 对于大多数图片,白色区域是连续的;但是,有一些示例,顶部白色区域是不连续 - 请参阅我的问题的更新部分以查看非连续区域的示例)
您对如何检测黑色区域的边界并分离黑色区域有什么建议吗?
当然,以下是使用 OpenCV 在 Python 中检测图像中黑色轮廓的步骤,即使白色区域不连续也是如此:
import cv2
import numpy as np
# 加载图像
image = cv2.imread("your_image.jpg")
# 将图像转换为灰度(如果它还不是)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用自适应阈值对图像进行阈值处理
# 这将有助于处理照明条件的变化
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# 使用形态学运算来清理阈值图像
# 可以尝试不同的内核大小和形状以获得最佳结果
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)
# 查找轮廓
contours, hierarchy = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 循环遍历轮廓
for contour in contours:
# 计算轮廓的面积
area = cv2.contourArea(contour)
# 设置最小面积阈值以过滤掉小的、不想要的轮廓
if area > 100: # 调整此阈值
# 绘制轮廓(可选)
cv2.drawContours(image, [contour], -1, (0, 255, 0), 2)
# 显示结果
cv2.imshow("Image", image)
cv2.waitKey(0)
解释:
-
加载图像:
使用
cv2.imread()
加载图像。 -
转换为灰度:
如果图像不是灰度图像,则使用
cv2.cvtColor()
将其转换为灰度。 -
阈值处理:
使用
cv2.adaptiveThreshold()
对图像进行阈值处理。自适应阈值在处理照明条件变化时比简单阈值更好。 -
形态学运算:
使用
cv2.morphologyEx()
对阈值图像执行形态学运算。在本示例中,我们使用带有cv2.MORPH_OPEN
的opening
来去除噪点并分离白色区域。 -
查找轮廓:
使用
cv2.findContours()
查找阈值图像中的轮廓。我们使用cv2.RETR_EXTERNAL
仅检索外部轮廓,并使用cv2.CHAIN_APPROX_SIMPLE
简化轮廓。 - 循环遍历轮廓: 循环遍历找到的轮廓,并仅绘制面积大于特定阈值的轮廓。这有助于过滤掉小的、不想要的轮廓。
-
绘制轮廓:
使用
cv2.drawContours()
在原始图像或空白图像上绘制选定的轮廓,以可视化结果。
调整和改进:
-
阈值处理和内核:
可以尝试使用不同的阈值方法(例如,
cv2.THRESH_OTSU
) 和内核大小/形状进行形态学运算,以获得最佳结果。 - 面积阈值: 调整面积阈值以根据图像中的对象大小过滤轮廓。
-
轮廓逼近:
可以使用不同的轮廓逼近方法(例如,
cv2.CHAIN_APPROX_NONE
)以获得更精确或更简单的轮廓表示。
通过实验不同的参数和技术,可以针对的特定图像和要求微调此过程。
标签:python,opencv,image-processing From: 74047007