首页 > 编程问答 >如何使用 open-cv 检测图像中的黑色轮廓

如何使用 open-cv 检测图像中的黑色轮廓

时间:2024-07-31 08:04:15浏览次数:13  
标签:python opencv image-processing

我有一个如下所示的图像(该图像是我对原始图像进行预处理的结果):

enter image description here

我想做的是检测 黑色区域 以 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)

解释:

  1. 加载图像: 使用 cv2.imread() 加载图像。
  2. 转换为灰度: 如果图像不是灰度图像,则使用 cv2.cvtColor() 将其转换为灰度。
  3. 阈值处理: 使用 cv2.adaptiveThreshold() 对图像进行阈值处理。自适应阈值在处理照明条件变化时比简单阈值更好。
  4. 形态学运算: 使用 cv2.morphologyEx() 对阈值图像执行形态学运算。在本示例中,我们使用带有 cv2.MORPH_OPEN opening 来去除噪点并分离白色区域。
  5. 查找轮廓: 使用 cv2.findContours() 查找阈值图像中的轮廓。我们使用 cv2.RETR_EXTERNAL 仅检索外部轮廓,并使用 cv2.CHAIN_APPROX_SIMPLE 简化轮廓。
  6. 循环遍历轮廓: 循环遍历找到的轮廓,并仅绘制面积大于特定阈值的轮廓。这有助于过滤掉小的、不想要的轮廓。
  7. 绘制轮廓: 使用 cv2.drawContours() 在原始图像或空白图像上绘制选定的轮廓,以可视化结果。

调整和改进:

  • 阈值处理和内核: 可以尝试使用不同的阈值方法(例如, cv2.THRESH_OTSU ) 和内核大小/形状进行形态学运算,以获得最佳结果。
  • 面积阈值: 调整面积阈值以根据图像中的对象大小过滤轮廓。
  • 轮廓逼近: 可以使用不同的轮廓逼近方法(例如, cv2.CHAIN_APPROX_NONE )以获得更精确或更简单的轮廓表示。

通过实验不同的参数和技术,可以针对的特定图像和要求微调此过程。

标签:python,opencv,image-processing
From: 74047007

相关文章

  • 如何在for循环中使用curve_fit函数在python中一次性创建多个回归?
    简而言之,我有两个矩阵,一个称为t,另一个称为y。每个都有7列。假设它们被称为a、b、c、d、e、f和g。我想要的是从a对a、b对b、...、g对g这两个矩阵进行回归。我已经设法使我的算法使用curve_fit对一列进行回归一次。但我真正希望的是它能够一次性完成7个回归......
  • 激活虚拟环境会让python消失?
    VisualStudioCode终端的屏幕截图如屏幕截图所示,python在Powershell中运行得很好。然后我在E:\DrewFTCAPI\ftcapivenv激活虚拟环境,然后python就消失了。不仅没有消失,它不运行任何东西,也不产生任何输出。我至少预计会出现某种类型的"python"i......
  • Python 3.6 中的相互递归类型,使用命名元组语法
    我正在尝试实现图的节点和边。这是我的代码:fromtypingimportNamedTuple,ListclassNode(NamedTuple):name:stredges:List[Edge]classEdge(NamedTuple):src:Nodedest:Node这会引发错误,因为创建Edge时未定义Node类型。......
  • 使用 keras 模型对函数进行 Python 类型提示
    如果我创建这样的函数:defmdl(input_shape):model=Sequential()model.add(Conv2D(depth=64,kernel_size=(3,3),input_shape=input_shape,activation='relu'))model.add(Dense(32),activation='relu')model.add(Dropout(0.3))m......
  • Python:自动完成可以用于列表中的元素吗?
    Python在函数参数和函数返回类型中具有类型提示。类的元素是否有类似的东西?我希望能够在如下示例中使用自动完成功能:classMyClass:defhello(self):print("Hello")mylist=[]mylist.append(MyClass())foriinmylist:i.hello()#Noautocomplete......
  • python 中 COM 对象的正确类型提示是什么?
    我在python中使用COM对象来向3rd方软件公开可编程接口。这是通过使用Dispatchfromwin32com.client来实现的。我的项目也一直在使用python.3.7中的类型提示,但是我不确定如何为了类型提示的目的定义这些COM对象的类型。这个问题涉及我拥有的所有COM......
  • 如何遍历Python字典同时避免KeyErrors?
    解析大型JSON时,某些键可能仅在某些情况下存在,例如出现错误时。从服务器的API获取200OK的情况并不少见,但是您得到的响应包含应检查的错误。处理此问题的最佳方法是什么?我知道使用类似||之类的东西。|是处理KeyError的一种方法。get()但是如果......
  • Python 中的递归数据类型
    Python中最接近Haskell中的递归数据类型的是什么?(即在定义自身时使用类型自己的定义。)编辑:为了给出递归类型的更具体定义,下面是Haskell中的二叉树:dataTreea=Leafa|Branch(Treea)(Treea)我的阅读方式如下:二叉树可以是叶子,也可以包含两......
  • 如何在Python中平滑相邻的多边形?
    我正在寻找一种平滑多边形的方法,以便相邻/接触的多边形保持接触。单个多边形可以轻松平滑,例如使用PAEK或Bezier插值(https://pro.arcgis.com/en/pro-app/latest/tool-reference/cartography/smooth-polygon.htm),这自然会改变它们的边界边缘。但是如何平滑所有多边形......
  • Python多处理池不启动多个进程
    我正在尝试使用多处理池来创建多个进程。我有一个工作函数dummy_proc定义如下:importrefrommultiprocessingimportPooldefregex_check(input_string):#Patterntomatchboth"pm_lat"and"pm_lon_coslat"followedbytwofloatspattern=r"(c......