填充轮廓但保留包​​含的区域未填充

2024-01-25

我有这个 python 代码,据说可以填充图像的轮廓,但其中包含的孔未填充。这就是我要的:

但这就是我得到的:

我尝试指定轮廓层次结构来填充 cv2,但我无法得到我想要的结果。

这是我尝试过的:


import numpy as np
import cv2

# Load the PNG image
img = cv2.imread('slice.png')

# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)

# Find the contours in the binary image
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)

# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
    # Check if the contour has a parent
    if hierarchy[0][i][3] == -1:
        # If the contour doesn't have a parent, fill it with pixel value 255
        cv2.drawContours(filled_img, [contour], -1, 255, cv2.FILLED)

# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

我尝试修改 'if hierarchy[0][i][3] == -1:' 部分的 -1, 0, 1 值,但它要么填充较小的孔,要么填充整个较大的轮廓,例如我发布的第一张照片。

Update

我还想在较小的层次结构轮廓内部填充白色,如下所示:


问题是cv2.drawContours填充闭合轮廓的整个内部部分,无论是否存在内部轮廓。

我们可以从白色轮廓开始,然后用黑色填充没有父项的轮廓,而不是用白色填充没有父项的轮廓。


假设我们知道内部应该是黑色的,我们可以应用以下阶段:

  • 使用cv2.RETR_EXTERNAL查找轮廓,并用白色填充外部轮廓。
  • 使用 cv2.RETR_TREE 查找轮廓。
  • 迭代轮廓层次结构,并仅用黑色填充没有子轮廓的轮廓(用黑色填充最内部的轮廓)。

代码示例:

import numpy as np
import cv2

# Load the PNG image
img = cv2.imread('slice.png')

# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)

# Find the outer contours in the binary image (using cv2.RETR_EXTERNAL)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)

# Fill the outer contour with white color
cv2.drawContours(filled_img, contours, -1, 255, cv2.FILLED)

# Find contours with hierarchy, this time use cv2.RETR_TREE
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
    # Check if the contour has no child
    if hierarchy[0][i][2] < 0:
        # If contour has no child, fill the contour with black color
        cv2.drawContours(filled_img, [contour], -1, 0, cv2.FILLED)

# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result filled_img:
enter image description here

Note:
如果我们不知道最内部轮廓的颜色,我们可以在黑色背景上绘制白色轮廓,并将结果用作蒙版 - 使用蒙版复制输入图像的原始内容。


Update:

支持没有子项的轮廓:

为了支持有子轮廓和没有子轮廓的轮廓,我们可以填充黑色,仅填充符合这两个条件的轮廓:

  • 轮廓没有子轮廓。
  • 轮廓有一个祖父母轮廓(寻找祖父母而不是父轮廓,因为空轮廓有一个内轮廓,而其父轮廓是外轮廓)。

代码示例:

import numpy as np
import cv2

# Load the PNG image
img = cv2.imread('slice.png')

# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)

# Find the outer contours in the binary image (using cv2.RETR_EXTERNAL)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)

# Fill the outer contour with white color
cv2.drawContours(filled_img, contours, -1, 255, cv2.FILLED)

# Find contours with hierarchy, this time use cv2.RETR_TREE
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
    has_grandparent = False
    has_parent = hierarchy[0][i][3] >= 0
    if has_parent:
        # Check if contour has a grandparent
        parent_idx = hierarchy[0][i][3]
        has_grandparent = hierarchy[0][parent_idx][3] >= 0

    # Check if the contour has no child
    if hierarchy[0][i][2] < 0 and has_grandparent:
        # If contour has no child, fill the contour with black color
        cv2.drawContours(filled_img, [contour], -1, 0, cv2.FILLED)

# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Update:

在较小的层次结构轮廓内部填充白色:

在用黑色填充轮廓之前,我们可以检查指定轮廓内部是否有黑色像素。
仅当它没有孩子、有祖父母并且内部有黑色时才填充黑色。

为了测试内部是否有黑色像素,我们可以在临时图像上绘制轮廓(白色)。
然后检查最小值是否为 0(绘制轮廓为白色的值)。

tmp = np.zeros_like(thresh)
cv2.drawContours(tmp, [contour], -1, 255, cv2.FILLED)
has_innder_black_pixels = (thresh[tmp==255].min() == 0)

代码示例:

import numpy as np
import cv2

# Load the PNG image
img = cv2.imread('slice.png')

# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Threshold the image to create a binary image
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)

# Find the outer contours in the binary image (using cv2.RETR_EXTERNAL)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Create a blank image with the same dimensions as the original image
filled_img = np.zeros(img.shape[:2], dtype=np.uint8)

# Fill the outer contour with white color
cv2.drawContours(filled_img, contours, -1, 255, cv2.FILLED)

# Find contours with hierarchy, this time use cv2.RETR_TREE
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Iterate over the contours and their hierarchies
for i, contour in enumerate(contours):
    has_grandparent = False
    has_parent = hierarchy[0][i][3] >= 0
    if has_parent:
        # Check if contour has a grandparent
        parent_idx = hierarchy[0][i][3]
        has_grandparent = hierarchy[0][parent_idx][3] >= 0

    # Draw the contour over temporary image first (for testing if it has black pixels inside).
    tmp = np.zeros_like(thresh)
    cv2.drawContours(tmp, [contour], -1, 255, cv2.FILLED)
    has_innder_black_pixels = (thresh[tmp==255].min() == 0)  # If the minimum value is 0 (value where draw contour is white) then the contour has black pixels inside

    if hierarchy[0][i][2] < 0 and has_grandparent and has_innder_black_pixels:
        # If contour has no child and has a grandparent and it has black inside, fill the contour with black color
        cv2.drawContours(filled_img, [contour], -1, 0, cv2.FILLED)

# Display the result
cv2.imshow('Original Image', img)
cv2.imshow('Filled Regions', filled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

填充轮廓但保留包​​含的区域未填充 的相关文章

  • 通过 Scrapy 抓取 Google Analytics

    我一直在尝试使用 Scrapy 从 Google Analytics 获取一些数据 尽管我是一个完全的 Python 新手 但我已经取得了一些进展 我现在可以通过 Scrapy 登录 Google Analytics 但我需要发出 AJAX
  • 将 saxon 与 python 结合使用

    我需要使用 python 处理 XSLT 目前我正在使用仅支持 XSLT 1 的 lxml 现在我需要处理 XSLT 2 有没有办法将 saxon XSLT 处理器与 python 一起使用 有两种可能的方法 设置一个 HTTP 服务 接受
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • Python(Selenium):如何通过登录重定向/组织登录登录网站

    我不是专业程序员 所以请原谅任何愚蠢的错误 我正在做一些研究 我正在尝试使用 Selenium 登录数据库来搜索大约 1000 个术语 我有两个问题 1 重定向到组织登录页面后如何使用 Selenium 登录 2 如何检索数据库 在我解决
  • 使用带有关键字参数的 map() 函数

    这是我尝试使用的循环map功能于 volume ids 1 2 3 4 5 ip 172 12 13 122 for volume id in volume ids my function volume id ip ip 我有办法做到这一点
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • 如何在 Python 中检索 for 循环中的剩余项目?

    我有一个简单的 for 循环迭代项目列表 在某些时候 我知道它会破裂 我该如何退回剩余的物品 for i in a b c d e f g try some func i except return remaining items if s
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 向 Altair 图表添加背景实心填充

    I like Altair a lot for making graphs in Python As a tribute I wanted to regenerate the Economist graph s in Mistakes we
  • 有没有办法检测正在运行的代码是否正在上下文管理器内执行?

    正如标题所述 有没有办法做到这样的事情 def call back if called inside context print running in context else print called outside context 这将
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我

随机推荐

  • 查询对象 mongoose 的嵌套数组

    我想在嵌套对象中查找带有 Alexa 的名称 操场 https mongoplayground net p rqYQtf0liaX https mongoplayground net p rqYQtf0liaX item journal i
  • 类型“Object”上不存在属性“json”

    我正在尝试使用 Angular 2 HttpClient 通过 REST 获取数据 我正在关注这里的角度教程https angular io tutorial toh pt6 https angular io tutorial toh pt
  • Woocommerce REST API - 添加自定义路由

    我有一家 Woocommerce 商店 我正在使用 Woocommerce REST API 在另一个网站上列出产品等 它工作正常 不过 我缺少一些功能 我想知道是否可以通过自定义调用来扩展 API 通过阅读 Woocommerce 的源代
  • 如何自动增加詹金斯构建号?

    如何自动增加 jenkins 内部版本号或使用 shell 脚本 现在我正在使用配置选项执行相同的操作 并手动增加 我想自动完成 您所要求的 即在多个作业之间保持内部版本号相同 很简单不可能的在詹金斯 这是通过设计完成的 正如 Jenkin
  • 过滤多列 Pandas

    我有一个将 pandas 数据框作为输入的方法 def dfColumnFilter df columnFilter columnName Returns a filtered DataFrame Keyword arguments df
  • 如何从 python 程序发送信号?

    我有这段代码可以监听 USR1 信号 import signal import os import time def receive signal signum stack print Received signum signal sign
  • 用于同步数组访问的最快 x86 汇编代码? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 同步访问内存中数组的最快 x86 汇
  • PHP 中具有不透明度的径向渐变

    我需要创建一个具有不透明度的 PNG 径向渐变 我浏览过 GDLib 但看不到生成径向渐变的方法 有谁知道使用 GDlib 或任何其他 PHP 图形库的方法吗 我想最坏的情况我可以使用 GDLib 逐像素生成它 但是如何开始对此进行数学计算
  • SQLAlchemy 模型 Django 喜欢保存方法吗?

    我正在一个项目中使用 sqlalchemy 不过 我更习惯Django的ORM 我想知道在 sqlalchemy ORM 中是否有类似于 Django 模型的 save 方法 我可以重写该方法以在 提交 保存 时自动实施操作 您可以使用一些
  • 无法获取 SoftwareComponentInternal - Maven 发布插件项目 gradle 的未知属性“release”

    我有一个包含多个模块的 Android 项目 我想将它们发布到自托管 Maven 存储库 我之前将发布代码存在于各个模块中 并且一切正常 我现在正在尝试将发布代码移至项目中build gradle这样我就可以重用该代码 我的各个模块内的代码
  • 在 pandas 中组合两个时间序列

    如果这明显记录在某处 我深表歉意 但我很难发现它 我有两个带有一些重叠日期 索引的 TimeSeries 我想合并它们 我假设我必须指定从两个系列中的哪一个获取重叠日期的值 为了说明我有 s1 2008 09 15 100 2008 10
  • 数据 URI 的用途是什么?

    为什么资源有时会嵌入到数据 URI 中 而不是使用链接到服务器上作为文件存储的资源的常规 URI 1 减少服务器请求 数据 URI 可用于通过减少获取资源所需的 HTTP 请求数量来减少服务器负载并提高客户端性能 例如 这个 HTML im
  • 注册媒体维基需要管理员批准吗?

    我维护的一个 wiki 受到了垃圾邮件机器人的严重打击 我们没有很多用户 而且我不想让合法用户背负验证码 有没有一种简单的方法可以让管理员确认注册 我浏览了手册 但无法弄清楚如何操作 您可以创建一个新用户权限 例如 批准 允许管理员分配该权
  • 如何在流上重用过滤器和映射的应用程序?

    我有一组从共享类型继承的域对象 即GroupRecord extends Record RequestRecord extends Record 子类型具有特定的属性 即GroupRecord getCumulativeTime Reque
  • 如何在 Android 中的 Activity 上强制执行自定义权限?

    我在android中创建了一个自定义权限
  • Python wand:具有透明度的合成图像

    我正在尝试用 Wand 合成两个图像 计划是将图像 B 放在 A 的右侧 并使 B 的透明度为 60 使用 IM 可以这样完成 composite blend 60 geometry 1000 0 b jpg a jpg new jpg 但
  • json对象访问

    我知道这很简单 但我坚持不下去 我有 json 变量 数据如下 var jsonText user Gender M Minage 19 Maxage 30 MaritalStatusId 0 user maritialtype Does
  • Google 应用程序引擎网站的多个域 - 每个域的分析

    好的 基本上我正在为我工 作的公司测试一种新的营销理念 购买 10 个左右的域名 其中包含与业务相关的关键搜索词 例如 carservice com carmot com hondaservice com 并将它们全部链接到一个网站 托管在
  • 训练 tesseract 后,tessdata 文件夹中应包含哪些文件?

    我使用 tesseract 作为我的 ANPR 应用程序的 OCR 引擎 我已经用车牌字体训练了 tesseract 3 01v 但我需要知道 tessdata 文件夹中应包含哪些文件 我应该使用安装 tesseract 3 01v 的同一
  • 填充轮廓但保留包​​含的区域未填充

    我有这个 python 代码 据说可以填充图像的轮廓 但其中包含的孔未填充 这就是我要的 但这就是我得到的 我尝试指定轮廓层次结构来填充 cv2 但我无法得到我想要的结果 这是我尝试过的 import numpy as np import