opencv中如何合并轮廓?

2023-11-26

好的,我已经在这个项目上工作了一段时间了。

我正在构建这个玩铬合金恐龙游戏的机器人。所以我尝试了其他方法来检测字符,例如 matchTemplate,甚至制作了自己的算法来定位对象,但我最喜欢这个(findcontours)。

这是我所拥有的:

What my program sees

谁能帮我找出如何合并仙人掌的两个矩形?

img = screen_cap()
roi = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(roi,127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
first = True
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area > 200: #filtering contours
        x,y,w,h = cv2.boundingRect(cnt)
        if w/h < 4: # filtering even more
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

抱歉参加聚会有点晚了。但是,如果我搜索“合并 opencv 轮廓”,我会发现这个;我认为应该有一个答案。

您可以通过以下方法之一合并任意两个轮廓:

  • 获取每个轮廓的点列表
  • 附加它们
  • 强制将它们转换为 cv2 轮廓格式
  • 如果您不太关心细节,请获取 cv2.convexHull 。

如果您不喜欢凸包的结果,因为轮廓的凹部分很重要,那么请按照以下方法操作:

  • 获取每个轮廓的点列表
  • 附加它们
  • 获得一个共同中心
  • 以中心为中心,按顺时针顺序对所有点进行排序
  • 强制将它们转换为 cv2 轮廓格式

如果两个轮廓中有很多凹形,则当配方经过两个轮廓而忽略其原始结构时,可能会产生之字形图案。如果是这种情况,您需要遵循第三个秘诀:

  • 获取每个轮廓的点列表
  • 获得一个共同中心
  • 删除每个轮廓中位于另一个轮廓内部的点
  • 找到每个轮廓中最接近公共中心的点。
  • 遍历列出的第一个轮廓,直到到达最近的点。
  • 然后切换到另一个列表,从最近的点开始顺时针穿过另一个轮廓,直到用完
  • 切换回第一个轮廓并附加其余的点。
  • 强制将它们转换为 cv2 轮廓格式

下一个更复杂的情况是,如果轮廓之间有多个交叉点,并且您想要保留两者之间的孔。然后最好制作黑色图像并通过白色绘制轮廓cv2.fillPoly();然后通过以下方式恢复轮廓cv2.findContours()

我在这里概述了前两个食谱的一些步骤

获取每个轮廓的点列表:

import cv2
list_of_pts = [] 
for ctr in ctrs_to_merge
    list_of_pts += [pt[0] for pt in ctr]

顺时针顺序排列点

我使用的功能MSeifert 的这个帖子真的很棒按顺时针顺序排列点

class clockwise_angle_and_distance():
    '''
    A class to tell if point is clockwise from origin or not.
    This helps if one wants to use sorted() on a list of points.

    Parameters
    ----------
    point : ndarray or list, like [x, y]. The point "to where" we g0
    self.origin : ndarray or list, like [x, y]. The center around which we go
    refvec : ndarray or list, like [x, y]. The direction of reference

    use: 
        instantiate with an origin, then call the instance during sort
    reference: 
    https://stackoverflow.com/questions/41855695/sorting-list-of-two-dimensional-coordinates-by-clockwise-angle-using-python

    Returns
    -------
    angle
    
    distance
    

    '''
    def __init__(self, origin):
        self.origin = origin

    def __call__(self, point, refvec = [0, 1]):
        if self.origin is None:
            raise NameError("clockwise sorting needs an origin. Please set origin.")
        # Vector between point and the origin: v = p - o
        vector = [point[0]-self.origin[0], point[1]-self.origin[1]]
        # Length of vector: ||v||
        lenvector = np.linalg.norm(vector[0] - vector[1])
        # If length is zero there is no angle
        if lenvector == 0:
            return -pi, 0
        # Normalize vector: v/||v||
        normalized = [vector[0]/lenvector, vector[1]/lenvector]
        dotprod  = normalized[0]*refvec[0] + normalized[1]*refvec[1] # x1*x2 + y1*y2
        diffprod = refvec[1]*normalized[0] - refvec[0]*normalized[1] # x1*y2 - y1*x2
        angle = atan2(diffprod, dotprod)
        # Negative angles represent counter-clockwise angles so we need to 
        # subtract them from 2*pi (360 degrees)
        if angle < 0:
            return 2*pi+angle, lenvector
        # I return first the angle because that's the primary sorting criterium
        # but if two vectors have the same angle then the shorter distance 
        # should come first.
        return angle, lenvector

center_pt = np.array(list_of_pts).mean(axis = 0) # get origin
clock_ang_dist = clockwise_angle_and_distance(origin) # set origin
list_of_pts = sorted(list_of_pts, key=clock_ang_dist) # use to sort

强制将点列表转换为 cv2 格式

import numpy as np
ctr = np.array(list_of_pts).reshape((-1,1,2)).astype(np.int32)

将它们与cv2.convexHull instead

如果您使用它,则无需按顺时针顺序排列点。但是,凸包可能会丢失一些轮廓属性,因为它不会保留轮廓的凹角。

# get a list of points
# force the list of points into cv2 format and then
ctr = cv2.convexHull(ctr) # done.

我认为合并两个轮廓的函数应该是opencv库的内容。这个方法非常简单,遗憾的是许多使用 opencv 的程序员不得不编写这样的样板代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv中如何合并轮廓? 的相关文章

  • 在 Python 中解析 TCL 列表

    我需要在双括号上拆分以空格分隔的 TCL 列表 例如 OUTPUT 172 25 50 10 01 01 Ethernet 172 25 50 10 01 02 Ethernet Traffic Item 1 172 25 50 10 01
  • 如何传递架构以从现有数据帧创建新数据帧?

    要将 schema 传递到 json 文件 我们这样做 from pyspark sql types import StructField StringType StructType IntegerType data schema Stru
  • 类的 IPython 表示

    我正在使用我创建的模块尝试 IPython 但它没有显示类对象的实际表示 相反 它显示类似的内容 TheClass module TheClass name I heavily在这个模块中使用元类 我有真正有意义的类表示 应该向用户显示 是
  • 如何在 __init__ 中使用await设置类属性

    我如何定义一个类await在构造函数或类体中 例如我想要的 import asyncio some code class Foo object async def init self settings self settings setti
  • 为什么 dataclasses.astuple 返回类属性的深层副本?

    在下面的代码中astuple函数正在执行数据类的类属性的深层复制 为什么它不能产生与函数相同的结果my tuple import copy import dataclasses dataclasses dataclass class Dem
  • matplotlib 图中点的标签

    所以这是一个关于已发布的解决方案的问题 我试图在我拥有的 matplotlib 散点图中的点上放置一些数据标签 我试图在这里模仿解决方案 是否有与 MATLAB 的 datacursormode 等效的 matplotlib https s
  • python multiprocessing 设置生成进程等待

    是否可以生成一些进程并将生成进程设置为等待生成的进程完成 下面是我用过的一个例子 import multiprocessing import time import sys def daemon p multiprocessing curr
  • Python 3d 绘图设置固定色阶

    我正在尝试绘制两个 3d 数组 第一个数组的 z 值在范围内 0 15 0 15 第二个来自 0 001 0 001 当我绘图时 色标自动遵循数据范围 如何设置自定义比例 我不想看到 0 001 的浅色 而应该看到 0 15 的浅色 如何修
  • 为什么 web2py 在启动时崩溃?

    我正在尝试让 web2py 在 Ubuntu 机器上运行 所有文档似乎都表明要在 nix 系统上运行它 您需要下载源代码并执行以下操作 蟒蛇 web2py py 我抓住了source http www web2py com examples
  • PyQt 使用 ctrl+Enter 触发按钮

    我正在尝试在我的应用程序中触发 确定 按钮 我当前尝试的代码是这样的 self okPushButton setShortcut ctrl Enter 然而 它不起作用 这是有道理的 我尝试查找一些按键序列here http ftp ics
  • Pycharm 在 os.path 连接上出现“未解析的引用”

    将pycharm升级到2018 1 并将python升级到3 6 5后 pycharm报告 未解析的引用 join 最新版本的 pycharm 不会显示以下行的任何警告 from os path import join expanduser
  • GUI(输入和输出矩阵)?

    我需要创建一个 GUI 将数据输入到矩阵或表格中并读取此表单数据 完美的解决方案是限制输入表单仅允许float 例如 A 1 02 0 25 0 30 0 515 0 41 1 13 0 15 1 555 0 25 0 14 1 21 2
  • 在 Google App Engine 中,如何避免创建具有相同属性的重复实体?

    我正在尝试添加一个事务 以避免创建具有相同属性的两个实体 在我的应用程序中 每次看到新的 Google 用户登录时 我都会创建一个新的播放器 当新的 Google 用户在几毫秒内进行多个 json 调用时 我当前的实现偶尔会创建重复的播放器
  • Spider 必须返回 Request、BaseItem、dict 或 None,已“设置”

    我正在尝试从以下位置下载所有产品的图像 我的蜘蛛看起来像 from shopclues items import ImgData import scrapy class multipleImages scrapy Spider name m
  • 为什么 csv.DictReader 给我一个无属性错误?

    我的 CSV 文件是 200 Service 我放入解释器的代码是 snav csv DictReader open screennavigation csv delimiter print snav fieldnames 200 for
  • 如果 PyPy 快 6.3 倍,为什么我不应该使用 PyPy 而不是 CPython?

    我已经听到很多关于PyPy http en wikipedia org wiki PyPy项目 他们声称它比现有技术快 6 3 倍CPython http en wikipedia org wiki CPython口译员开启他们的网站 ht
  • Firebase Firestore:获取文档的生成 ID (Python)

    我可以创建一个新文档 带有自动生成的 ID 并存储对其的引用 如下所示 my data key value doc ref db collection u campaigns add my data 我可以像这样访问数据本身 print d
  • 等待子进程使用 os.system

    我用了很多os system在 for 循环内调用创建后台进程 如何等待所有后台进程结束 os wait告诉我没有子进程 ps 我使用的是Solaris 这是我的代码 usr bin python import subprocess imp
  • 根据 Pandas 中的列表选择数据框行的子集

    我有一个数据框df1并列出x In 22 import pandas as pd In 23 df1 pd DataFrame C range 5 B range 10 20 2 A list abcde In 24 df1 Out 24
  • NLTK:查找单词大小为 2k 的上下文

    我有一个语料库 我有一个词 对于语料库中该单词的每次出现 我想获取一个包含该单词之前的 k 个单词和该单词之后的 k 个单词的列表 我在算法上做得很好 见下文 但我想知道 NLTK 是否提供了一些我错过的功能来满足我的需求 def size

随机推荐

  • rhandsontable 更改特定行的背景

    我在 R闪亮中使用rhandsontable 我想更改第一列中带有 Sum 的行的颜色 由于行数不固定 因此根据行号选择 Sum 行不起作用 我已经尝试了附加的代码 不幸的是它不起作用 非常感谢您的帮助 library shiny libr
  • Moq 来自派生类的基类函数

    我是 Moq 的新手 刚刚观看了 Moqing 上的pluralsight 视频 所以我觉得自己有能力去编写一些测试 我有一个基类 比如说 Sheet 它实现了 ISheet 接口 Sheet 是页面的基类 abstract class S
  • tomcat在Windows上使用intellij-idea启动问题

    我正在尝试将 spring mvc 项目从 jboss 7 1 1 移动到 Tomcat 8 我通过 Windows 服务包安装了 Tomcat 8 并且它成功运行 我正在使用 intellij 为项目部署分解的 jar 但 Tomcat
  • catch 语句中可以发生复制省略吗?

    考虑一个带有带有副作用的复制构造函数的异常类 编译器可以在这里跳过调用复制构造函数吗 try throw ugly exception catch ugly exception ignoring the exception so I m n
  • Google主页使用了什么技术(吉他弦)

    What technology is used at the Google homepage 9 June 2011 They made something like a guitar pickup for the snares When
  • 当附加的 DOM 节点像事件的removeEventListener 一样被删除时,MutationObservers 是否应该被删除/断开连接?

    这里发现了一个几乎相同的问题 删除元素时 IntersectionObserver 是否应该断开连接 我还没有找到说明当一个元素带有附加元素时应该做什么的文档MutationObserver MO 从 DOM 中删除 该 API 不提供类似
  • 在 HTML 中将 JSON/YAML 层次结构显示为树?

    我的 YAML 数据看起来有点像这样 但大约有 150k all foo 1025 bar baz 37628 quux a 179 b 7 或者 JSON 中的相同内容 all bar baz 37628 quux a 179 b 7 f
  • DeprecationWarning:Collection#find:改为传递函数

    我是node js 的新手 目前正在使用discord js 来制作Discord 机器人 一旦使用任何机器人命令 控制台就会打印 DeprecationWarning 例如 node 15656 DeprecationWarning Co
  • JOIN 子句中的 MYSQL 子查询 SELECT

    好吧 好吧 我必须将子查询放在JOIN子句 因为它选择多个列并将其放入SELECT子句不允许这样做 因为它给我一个操作数错误 无论如何 这是我的查询 SELECT c id c title c description c icon p id
  • VS 构建后显示“xxx.exe 不是有效的 Win32 应用程序”

    我已经在我的 Windows 7 64 PC 上的 Visual Studio 2015 使用 IDE 中成功开发了 WinAPI 应用程序 我通常在Release模式下测试程序 然后我对我的源代码进行了一些编辑 程序编译和链接没有错误 但
  • 反射调用函数并使用默认参数

    给定以下函数 fun function x Int 12 println x x 如何使用反射调用它而不指定x 或者以某种方式使用默认值 not硬编码 您可以使用callBy 它遵循默认值 function callBy emptyMap
  • 如何将 Facebook 相册集成到网站中? [复制]

    这个问题在这里已经有答案了 可能的重复 Facebook Api 如何访问我的相册 如何在网站内显示 Facebook 相册中的照片 您可以使用图形 API 来获取相册中的图像 如下所示 https graph facebook com A
  • LESS 中的双 & 符号

    我对 LESS 编译器中的双 符号行为感到困惑 Look heading type small font size 15px 将被编译为 heading heading type small font size 15px 那很好 But w
  • 更新和删除表中的不同行时是否可能出现死锁?

    在Oracle 10 版本中 即使同时对同一个表的不同行进行更新和删除 也会导致死锁吗 该表的主键由两列组成 并且没有任何与任何其他表关联 引用的外键 并且与其他表没有父 子关系 我相信 它不会造成僵局 但我在我的应用程序中遇到了问题 添加
  • C++和C#之间通过管道进行通信

    我想通过管道将数据从 C 应用程序发送到 C 应用程序 这是我所做的 这是 C 客户端 include stdafx h include
  • 为什么引入严格性的函数称为 seq?

    我明白了seq功能以及为什么有必要引入严格性以提高效率 我不明白的是 为什么这个原语被称为seq 与严格性无关 TL DR 米兰达称之为seq 它是在什么时候引入的sequence 可能 已经是 Monad 的事情了 并且 被称为stric
  • Angular/Chart.js 错误:无法创建图表:无法从给定项目获取上下文

    这确实是我第一次使用 Chart js 我将其导入到 Angular 组件中 我现在尝试创建一个简单的条形图 我的控制台中出现以下错误 core controller js 118 Failed to create chart can t
  • Heroku 上的 url_for with _external=True 不会在 URL 上附加服务器名称

    我已经在 Heroku 上部署了一个应用程序 但问题是当我的应用程序发送电子邮件时 它没有在 URL 中附加我的服务器名称 content Content text html verification email format user f
  • SQLite 架构信息元数据

    我需要获取 SQLite 数据库中的列名及其表 我需要的是一个包含 2 列的结果集 table name column name 在 MySQL 中 我可以通过数据库上的 SQL 查询来获取此信息INFORMATION SCHEMA 然而
  • opencv中如何合并轮廓?

    好的 我已经在这个项目上工作了一段时间了 我正在构建这个玩铬合金恐龙游戏的机器人 所以我尝试了其他方法来检测字符 例如 matchTemplate 甚至制作了自己的算法来定位对象 但我最喜欢这个 findcontours 这是我所拥有的 谁