通过迭代自适应阈值和形状分析检测圆形物体簇

2024-03-12

我一直在开发一个应用程序来计算圆形物体,例如图片中的细菌菌落。

让这一切变得简单的是,物体通常与背景有很大区别。

然而,有一些困难使得分析变得棘手:

  1. 背景将呈现渐变以及快速的强度变化。
  2. 在容器的边缘,对象将是椭圆形而不是圆形。
  3. 物体的边缘有时相当模糊。
  4. 对象将聚集。
  5. 对象可以非常小(直径 6 像素)
  6. 最终,这些算法将由对图像分析没有深入了解的人使用(通过 GUI),因此参数必须直观且很少。

这个问题已在科学文献中多次提及并“解决”,例如使用循环霍夫变换或分水岭方法,但我从未对结果感到满意。

所描述的一种简单方法是通过自适应阈值和分割来获取前景(正如我在这个帖子 https://stackoverflow.com/questions/10313602/reshaping-noisy-coin-into-a-circle-form/10324759#10324759)使用距离变换的聚类对象。

我已经成功地实现了这种方法,但它并不总是能够应对强度的突然变化。另外,同行们要求我提出一种更“新颖”的方法。

因此,我正在寻找一种提取前景的新方法。

因此,我研究了其他阈值/斑点检测方法。 我尝试了 MSER,但发现它们不是很强大,而且对我来说速度很慢。

我最终想出了一个算法,到目前为止,它给了我很好的结果:

  1. 我分割图像的三个通道并减少它们的噪声(模糊/中值模糊)。对于每个通道:
  2. 我通过计算原始通道和卷积通道(通过大内核模糊)之间的绝对差来手动实现自适应阈值处理的第一步。然后,对于所有相关的阈值:
  3. 我对 2) 的结果应用阈值
  4. 找到轮廓
  5. 根据轮廓的形状(大小、面积、凸度...)验证或无效轮廓
  6. 仅有效的连续区域(i.e.然后在累加器中重新绘制(每个通道 1 个累加器)。
  7. 在累积超过阈值的连续区域后,我最终得到了“区域分数”的地图。具有最高强度的区域是最常满足形态过滤标准的区域。
  8. 然后将三个图(每个通道一个)转换为灰度并设置阈值(阈值由用户控制)

Just to show you the kind of image I have to work with: enter image description here This picture represents part of 3 sample images in the top and the result of my algorithm (blue = foreground) of the respective parts in the bottom.

这是我的 C++ 实现:3-7

/*
 * cv::Mat dst[3] is the result of the absolute difference between original and convolved channel.
 * MCF(std::vector<cv::Point>, int, int) is a filter function that returns an positive int only if the input contour is valid.
 */

/* Allocate 3 matrices (1 per channel)*/
cv::Mat accu[3];

/* We define the maximal threshold to be tried as half of the absolute maximal value in each channel*/
int maxBGR[3];
for(unsigned int i=0; i<3;i++){
    double min, max;
    cv::minMaxLoc(dst[i],&min,&max);
    maxBGR[i] = max/2;
    /* In addition, we fill accumulators by zeros*/
    accu[i]=cv::Mat(compos[0].rows,compos[0].cols,CV_8U,cv::Scalar(0));
}
/* This loops are intended to be multithreaded using
#pragma omp parallel for collapse(2) schedule(dynamic)
For each channel */
for(unsigned int i=0; i<3;i++){
    /* For each value of threshold (m_step can be > 1 in order to save time)*/
    for(int j=0;j<maxBGR[i] ;j += m_step ){
            /* Temporary matrix*/
            cv::Mat tmp;
            std::vector<std::vector<cv::Point> > contours;
            /* Thresholds dst by j*/
            cv::threshold(dst[i],tmp, j, 255, cv::THRESH_BINARY);
            /* Finds continous regions*/
            cv::findContours(tmp, contours, CV_RETR_LIST, CV_CHAIN_APPROX_TC89_L1);
            if(contours.size() > 0){
                /* Tests each contours*/
                for(unsigned int k=0;k<contours.size();k++){
                    int valid = MCF(contours[k],m_minRad,m_maxRad);
                    if(valid>0){
                        /* I found that redrawing was very much faster if the given contour was copied in a smaller container.
                         * I do not really understand why though. For instance,
                         cv::drawContours(miniTmp,contours,k,cv::Scalar(1),-1,8,cv::noArray(), INT_MAX, cv::Point(-rect.x,-rect.y));
                         is slower especially if contours is very long.
                         */
                        std::vector<std::vector<cv::Point> > tpv(1);
                        std::copy(contours.begin()+k, contours.begin()+k+1, tpv.begin());
                        /* We make a Roi here*/
                        cv::Rect rect = cv::boundingRect(tpv[0]);
                        cv::Mat miniTmp(rect.height,rect.width,CV_8U,cv::Scalar(0));
                        cv::drawContours(miniTmp,tpv,0,cv::Scalar(1),-1,8,cv::noArray(), INT_MAX, cv::Point(-rect.x,-rect.y));
                        accu[i](rect)    = miniTmp + accu[i](rect);
                    }
                }
            }
        }
    }
/* Make the global scoreMap*/
cv::merge(accu,3,scoreMap);
/* Conditional noise removal*/
if(m_minRad>2)
    cv::medianBlur(scoreMap,scoreMap,3);
cvtColor(scoreMap,scoreMap,CV_BGR2GRAY);

我有两个问题:

  1. 这种前景提取方法的名称是什么?您是否认为在这种情况下使用它可能不合适?

  2. 由于递归查找和绘制轮廓非常密集,因此我想让我的算法更快。你能告诉我有什么方法可以实现这个目标吗?

非常感谢您的帮助,


几年前,我编写了一个应用程序来检测显微镜图像中的细胞。代码是用 Matlab 编写的,我认为现在比应有的更复杂(这是我的第一个 CV 项目),所以我只会概述对您实际上有帮助的技巧。顺便说一句,它的速度慢得要命,但它确实很擅长分离大群的双胞胎细胞。

我定义了一个度量来评估给定点是单元格中心的机会: - 亮度在其周围以圆形图案减少 - 纹理亮度的变化遵循给定的模式 - 一个小区不会覆盖超过 % 的相邻小区

有了它,我开始迭代地找到最好的单元格,将其标记为已找到,然后寻找下一个。由于这样的搜索成本很高,因此我采用遗传算法在特征空间中更快地搜索。

一些结果如下:

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

通过迭代自适应阈值和形状分析检测圆形物体簇 的相关文章

  • ExecuteNonQueryAsync 并在 SQL 事务中提交

    我正在寻求对我创建的一段代码的帮助 我正在尝试在事务中从 C 进行异步 SQL 调用 例如我可能正在更新或删除表中的行 这是我到目前为止所拥有的 但我似乎无法找到有关在事务中执行此操作的太多信息 根据我在这里所拥有的以及到目前为止我所理解的
  • LRU、FIFO、随机

    当出现页面错误或缓存未命中时 我们可以使用最近最少使用 LRU 先入先出 FIFO 或随机替换算法 我想知道 哪一个提供了最好的性能 也称为未来缓存丢失 页面错误最少的可能性 架构 Coldfire 处理器 没有愚蠢的问题 这句话非常适合这
  • 在 ASP.NET Core 中全局重用变量

    我必须强制这些变量在我想使用的每个变量上重用 这让我很困难 我需要创建一个类来定义这些变量并在整个程序中使用它们 我怎样才能做到这一点 string RootFolderName Uplaod string ProductPictureFo
  • 嵌套绑定表达式

    这是一个后续问题我之前的问题 https stackoverflow com questions 2735294 templates function pointers and c0x include
  • 资源文件中的控制字符 C#

    我想添加Left To Right控制字符在resource resx文件输入Visual Studio 我在互联网上搜索并找到了一个名为在 NET 资源文件中转义序列的另一种方法 http www devx com tips Tip 34
  • 如何防止函数中的隐式转换?

    我正在编写一个实用程序类 其中包含 IsEquals 和 IsGreaterThanEquals 等接受 double 类型参数的方法 当我将浮点值发送到方法时 它们会隐式转换为双精度值并进行比较 我不希望这种事发生 当我发送 float
  • 安装/编译 pylzma(lzma python 绑定)

    我已经向作者提出了这个问题website http www joachim bauch de projects pylzma comment page 1 comment 5211 但我想我也可以在这里问 我一直在尝试使用以下设置安装 py
  • 减少最大值并保存其索引

    int v 10 2 9 1 3 5 7 1 2 0 0 int maximo 0 int b 0 int i pragma omp parallel for shared v private i reduction max maximo
  • Welzl 算法的迭代版本

    我正在使用 Welzl 算法来查找点云的最小外接圆 2d 或最小外接球体 3d 不幸的是 该算法具有非常高的递归深度 即输入点数 这个算法有迭代版本吗 我找不到任何并且不知道如何将递归更改为循环 我发现了一些迭代的最小包围圆 球算法 但它们
  • 我想知道像tineye.com这样的反向图像搜索服务是如何工作的......?

    像 TinEye 这样的反向图像搜索引擎如何工作 我的意思是进行图像搜索需要哪些参数 不知道 TinEye 是否使用这个 但是SURF http en wikipedia org wiki SURF是用于此目的的常用算法 在这里您可以看到一
  • 对指针列表进行排序

    我再次发现自己在 C 中的一些非常简单的任务上失败了 有时我希望我能从 Java 中的 OO 中学到所有知识 因为我的问题通常是从像 Java 一样思考开始的 无论如何 我有一个std list
  • 如何规划庭院灯最有效的路线

    我正在尝试挂一些庭院灯 基于另一个问题 https cs stackexchange com questions 80134 christmas light route efficiency我问 我意识到我需要一种算法来解决路由检查问题 h
  • 以 asp-for 作为参数的自定义 ViewComponent

    我想把这个包装起来
  • “未定义对 clrscr() 的引用;” [复制]

    这个问题在这里已经有答案了 include
  • 如何确定 n 高数字金字塔中的最大路线成本

    我有一个像这样的数字金字塔 7 4 8 1 8 9 2 4 6 7 4 6 7 4 9 4 9 7 3 8 8 routes 32 每个数字都按其系列中的强大程度进行索引 0 9 gt 1 1 8 gt 5 2 8 gt 4 3 7 gt
  • 基于 C++ 组件的类

    Hi 我正在使用容器编写一个基于组件的类 但是在考虑了许多不同的方法之后 我找不到真正符合我想要的方法 这是总体思路的一个例子 我已经写的代码 Abstract class Component class Component public
  • 是否可以使用 struct stat 描述符获取和设置文件名?

    是否可以在获取或设置 重命名 文件名时给出文件的绝对路径 并将 struct stat 实例作为 lstat 函数的参数 正如我在文档结构中发现的那样 struct stat dev t st dev ID of device contai
  • 在方法签名中使用 new 关键字通常只是为了可读性吗?

    我读过关于new关键词在方法签名中并看到了下面的例子this https stackoverflow com questions 1014295 c sharp new keyword in method signature发帖了 但还是不
  • 如何在迭代时从地图中删除?

    迭代时如何从地图中删除 喜欢 std map
  • 如何找到权重为 1、0、-1 且成本精确为 0 的多维路径

    我得到了一个有向图 其中有 n 个节点和边 向量的权重 每个向量的长度为 m 为数字 1 0 1 我想找到从一个节点到另一个节点 我们可以多次访问节点 的任何路径 或者说这样的路径不存在 使其权重之和等于仅由零组成的向量 我正在考虑暴力回溯

随机推荐

  • 水晶报表中从右到左的字符串

    考虑 SQL Server 中的以下查询 下图是水晶报表中查询的结果 正如你所看到的 右侧部分与sql server中的查询结果完全相同 左侧部分通过锁定函数进行转换 以满足波斯语从右到左的属性 我需要获得这个功能 首先 你需要重写你的sq
  • X11 非剪裁子窗口

    X 有非裁剪子窗口的概念吗 中的行为 Windows 和 OSX 的这些是 父母总是站在孩子后面 当父项关闭时 子项也会自动关闭 孩子们在移动时跟随父母 如果答案是否定的 那么我可以模拟 2 和 3 但是 1 怎么样 Thanks Cosm
  • 猫鼬有 isDirty 检查吗?

    我有一个涉及嵌入式模式的猫鼬设置 可以说 带有嵌入式评论的博客文章 评论可以由原始发布者以及编辑 管理员编辑 添加 编辑评论后 整个博客文章将被保存 我在嵌入式评论模式上设置了一些自定义猫鼬的 预 中间件 它会自动设置该特定评论的laste
  • 驱动程序可执行文件必须由 webdriver.ie.driver 系统属性设置

    我正在使用 Selenium 来自动化测试 我的应用程序仅使用 IE 它无法在其他浏览器上运行 Code import org openqa selenium ie InternetExplorerDriver import org ope
  • Firebase onAuthStateChanged 始终返回未定义

    我一直在尝试创建一个 util 方法 该方法将返回用户对象或用户对象是否存在 如果没有参数 它应该返回一个布尔值 如果有参数 getUser 它应该返回用户对象 但它总是返回未定义的 这似乎工作了一段时间 但后来我休息了一下 回来时它总是返
  • 在 NodeJS 中安排异步函数

    我想安排一个异步函数 异步 等待返回类型 每两分钟运行一次 我尝试使用通用setInterval 节点模块如节点计划 cron 节点计划 异步轮询但无法实现异步函数调用的轮询 这是我在代码中尝试过的 cron schedule 2 awai
  • 使用 create-react-app 时出现“未捕获的引用错误:jQuery 未定义”

    正在使用构建 React 应用程序创建反应应用程序 https github com facebookincubator create react app所以该应用程序已准备好服务器 当导入引导 javascript 插件 例如 affix
  • Android 中的日期验证

    我是 Android 编程新手 目前正在开发一个应用程序 有人可以帮助我如何验证用户输入的日期是否有效 private Pattern pattern private Matcher matcher private static final
  • 如何在 PHP 中下载现有文件

    我的服务器上有一个 pdf 文件 我想创建这样的链接 用户可以单击它并下载该 pdf 文件 我正在使用 Zend 框架与 Php 一起工作 将此代码放入 php 文件中并将其命名为 f e 下载 php
  • 当执行计划中存在“PARTITION LIST SUBQUERY”时,某些内容(错误?)会取消实例化包

    这是 Oracle 12c 的错误吗 我在 Oracle Linux 上运行 64 位 Oracle 12 1 0 2 遇到一件奇怪的事情 当执行计划切换到使用 PARTITION LIST SUBQUERY 时 受影响的查询中使用的包将丢
  • iCal 属性参数可以/应该转义吗?

    具体来说 CN 通用名称 参数 例如 ORGANIZER CN John Doe Eng mailto 电子邮件受保护 cdn cgi l email protection 恕我直言 RFC 对此含糊其辞 这是非常清楚的属性值 of typ
  • 如何将 numpy.matrix 或数组转换为 scipy 稀疏矩阵

    对于 SciPy 稀疏矩阵 可以使用todense or toarray 转换为 NumPy 矩阵或数组 进行逆运算的函数有哪些 我进行了搜索 但不知道哪些关键字应该是正确的 初始化稀疏矩阵时 您可以传递 numpy 数组或矩阵作为参数 例
  • 如何将 Jsoup 与 Volley 一起使用?

    我有一个使用 Jsoup 和 AsyncTask 的工作示例 效果很好 我只是对表现不满意 加载包含文本和图像的简单列表页面需要 3 6 秒 我想以某种方式提高性能 所以我偶然发现了截击 谁能解释一下如何在 jsoup 中使用 volley
  • 是否应该在 Windows 7 计算机上安装用于 powershell 的活动目录模块来导入它,还是可以从 Windows 2008 R2 DC 远程导入它?

    目前我正在开发任务板 用于将一些权限委托给远程管理员 我有以下问题 gt 对于在 powershell 中导入 Active Directory 模块 它是本地安装还是可以从 Windows 2008 R2 DC 远程导入 gt 对于在远程
  • 如何删除所有排队的作业,因为它会导致错误?

    我的网站将电子邮件发送作业排队到jobs桌子 我认为电子邮件服务器有问题 无法发送电子邮件 因此作业被困在作业表中 现在可能有太多作业 我收到此错误消息 Next exception Illuminate Database QueryExc
  • 这是什么字符编码?

    我正在与 Oracle DB 进行交互 该数据库的编码有些混乱 根据数据库属性为 ASCII7 但实际上对韩语字符进行编码 当我从结果集中获取一些韩语字符串并查看字节时 结果发现它们与该文件完全对应 我通过谷歌搜索一些字节序列发现 http
  • 如何将实例转换为派生类?

    我正在尝试在我正在开发的 Python 程序中使用一些继承 我有一个基类 User 它实现了用户的所有功能 我添加了未经批准的用户的概念 它就像用户一样 只是添加了一个方法 User 类有一些返回 User 对象的方法 当我子类化时 这将不
  • 适用于 Windows + C# 的 SMS 网关 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我对短信以及如何发送短信有点困惑 我四处搜寻 发现您可以购买短信 我看到有些地方花 490 美元就能收
  • 命令行动词参数的约定 -a 与 --arg

    我刚刚注意到动词样式命令参数的模式 在 git 和 NET 的 CommandLineParser lib 中 想知道是否有人可以确认 myprog dothis a someArg a arg 单破折号前缀和双破折号前缀有什么区别 单破折
  • 通过迭代自适应阈值和形状分析检测圆形物体簇

    我一直在开发一个应用程序来计算圆形物体 例如图片中的细菌菌落 让这一切变得简单的是 物体通常与背景有很大区别 然而 有一些困难使得分析变得棘手 背景将呈现渐变以及快速的强度变化 在容器的边缘 对象将是椭圆形而不是圆形 物体的边缘有时相当模糊