从一堆对象中提取一个对象并检测边缘

2023-12-11

在我的大学项目中,我需要通过检测叶子的边缘来根据植物叶子的形状来识别植物的种类。 (我使用OpenCV 2.4.9和C++),但源图像是在植物的真实环境中拍摄的,并且有不止一片叶子。请参阅下面的示例图片。所以这里我需要提取一片叶子的边缘图案来进一步处理。

enter image description here

使用 Canny Edge Detector 我可以识别整个图像的边缘。

enter image description here

但我不知道如何从这里开始提取一张叶子的边缘图案,可能会更清晰和完整的叶子。我不知道这是否也可能。谁能告诉我这是否可能,如何提取一片叶子的边缘,我只想知道我需要应用于图像的图像处理步骤。我不需要任何代码示例。我是图像处理和 OpenCV 的新手,通过实验进行学习。

提前致谢。

Edit

正如 Luis 所说,在使用 Canny 边缘检测进行边缘检测后,我已经对图像进行了形态学接近,但似乎我仍然很难从图像中找到最大的轮廓。 这是我处理图像所采取的步骤

  1. 应用双边滤波器降低噪声

    bilateralFilter(img_src, img_blur, 31, 31 * 2, 31 / 2);
    
  2. 通过直方图均衡调整对比度

    cvtColor(img_blur,img_equalized,CV_BGR2GRAY);
    
  3. 应用 Canny 边缘检测器

    Canny(img_equalized, img_edge_detected, 20, 60, 3);
    
  4. 阈值二值图像以去除一些背景数据

    threshold(img_edge_detected, img_threshold, 1, 255,THRESH_BINARY_INV);
    
  5. 图像的形态接近

    morphologyEx(img_threshold, img_closed, MORPH_CLOSE, getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
    

以下是我得到的结果图像。

我从上面的原始图像中得到的结果

enter image description here

源图像和第二张图像的结果

来源 :

enter image description here

Result :

enter image description here

有什么方法可以检测最大轮廓并将其从图像中提取出来吗?

请注意,我的最终目标是使用真实环境图像创建一个植物识别系统,但在这里我不能使用模板匹配或屏蔽之类的东西,因为用户必须拍摄图像并上传它,所以系统没有任何先验想法关于叶子。

这是完整的代码

#include <opencv\cv.h>
#include <opencv\highgui.h>
using namespace cv;

int main()
{
Mat img_src,     img_blur,img_gray,img_equalized,img_edge_detected,img_threshold,img_closed;
//Load original image
img_src = imread("E:\\IMAG0196.jpg");

//Apply Bilateral Filter to reduce noise
bilateralFilter(img_src, img_blur, 31, 31 * 2, 31 / 2);

//Adjust contrast by histogram equaliztion
cvtColor(img_blur,img_equalized,CV_BGR2GRAY);

//Apply Canny edge detector
Canny(img_equalized, img_edge_detected, 20, 60, 3);

//Threshold binary image to remove some background data
threshold(img_edge_detected, img_threshold, 15, 255,THRESH_BINARY_INV);

//Morphological close of the image
morphologyEx(img_threshold, img_closed, MORPH_CLOSE, getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));

imshow("Result", img_closed);
waitKey(0);
return 0;
}

谢谢。


好吧,这里也有人问过类似的问题:

  • opencv 匹配边缘图像

看起来边缘信息并不是图像的良好描述符,如果您想尝试的话,我将执行以下步骤:

  1. 加载图像并将其转换为灰度
  2. 检测边缘 - Canny、Sobel 尝试并找到最适合您的
  3. 将阈值设置为消除大部分背景的给定值 - 二值化图像
  4. 关闭图像 - 形态关闭不要关闭窗口!
  5. 计算并识别图像中的对象(斑点、分水岭)
  6. Check each object for a shape (assuming you have described shapes of the leaf you could find before or a standard shape like an ellipse) features like:
    • http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html
    • http://www.math.uci.edu/icamp/summer/research_11/park/shape_descriptors_survey.pdf
  7. 如果给定的物体具有您描述为叶子的给定形状,那么您就检测到了叶子!。

我相信给定的图像是在现实世界中拍摄的,这些算法的性能会很差,但这是一个开始。希望它有帮助:)。

-- 编辑后 06/07

好吧,既然你事先没有关于叶子的信息,我认为我们能做的最好的事情就是:

  • 加载图片
  • 双边过滤器
  • Canny
  • 提取轮廓
  • Assume:周长最大的轮廓是叶子
  • 凸包 3 或 2 个最大的轮廓(蓝线是凸包完成的)
  • 使用这个凸包对图像进行图形切割并将其分割

如果执行这些步骤,您最终会得到如下图像:

Leaf 1 segmentation

Leaf 2 segmentation

我不会在这里发布代码,但是你可以在我凌乱的github中查看它。我希望你不介意它是用 python 编写的。

叶子 - Github

尽管如此,我还有一些事情需要完成,可以改善结果。路线图是:

  • 在图形剪切中定义掩码(如文档中描述的那样)
  • 应用区域增长可能会提供更好的凸包
  • 删除所有接触图像边界的边缘可以帮助识别较大的边缘

嗯,再次希望有帮助

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

从一堆对象中提取一个对象并检测边缘 的相关文章

  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 如何在istio中配置入口网关?

    我是 istio 的新手 我想通过 istio ingress gateway 访问我的应用程序 但我不知道为什么它不起作用 这是我的kubenetes deploy yaml文件内容 apiVersion v1 kind Service
  • 停止 RMI 服务器的干净方法

    RMI 服务器无需 stopServer 功能即可正常工作 public class HelloServer extends UnicastRemoteObject implements HelloInterface private fin
  • 更改状态时如何保留同级 ui 视图?

    我有2个ui view我的应用程序中的指令 一个包含子导航 另一个是实际的页面内容 我的子导航是树结构 当您单击结束节点 或叶子 时应该是内容视图唯一更新的时间 每当您单击子导航中的非叶节点时 我希望内容视图在子导航视图更改时保持不变 发生
  • DBMS 中的最大行数

    DBMS 特别是MySQL 中表的最大行数有限制吗 我想创建用于保存日志文件的表 并且其行增加得如此之快 我想知道我应该做什么来防止出现任何问题 我认为没有官方限制 这取决于最大索引大小和文件系统限制 From MySQL 5 0 特性 支
  • 数据库正在被另一个进程使用...但是什么进程呢?

    我编写了一个非常小的 C 程序 它使用一个非常小的 SQL Server 数据库 纯粹用于一些学习和测试目的 该数据库仅在这个新项目中使用 而没有在其他地方使用 但是 我在运行调试时遇到问题 程序无法运行 因为数据库 正在被另一个进程使用
  • 单元格中的 UIView -- 无法圆化右上角

    我有一个长方形UIView静态表视图单元格中的对象 我有一个通往物体的出口 我正在尝试有选择地圆角 但它不会圆化右侧的角 这是故事板中的样子 我要配置的视图是淡黄色的 红色视图除了确认另一个视图没有被裁剪之外没有任何实际用途 不存在约束问题
  • VBA IE 自动化 - 等待下载完成

    我正在尝试自动执行一些通过 Internet Explorer 完成的任务 其中包括下载文件 然后将其复制到不同的目录并重命名 我或多或少成功地找到了有关如何执行此操作的信息 代码正在运行 但有例外 因此如果有人可以帮助我改进此代码 我将不
  • 确定记录是否存在的最快方法

    正如标题所示 我试图找出以最少的开销最快的方法来确定表中是否存在记录 示例查询 SELECT COUNT FROM products WHERE products id vs SELECT COUNT products id FROM pr
  • 如何自定义 iOS 警报视图?

    我想创建一个自定义alert view在我的 iOS 应用程序中 例如 我想放一些images在这个alert 并更改其颜色 我知道如何创建一个正常的UIAlertView 但是有没有办法定制一个alert view 我设置了自己的 UIV
  • Chrome 扩展:XMLHttpRequest 已取消(状态 == 0)

    我尝试从服务器加载 json 文件XMLHttpRequest 但我只得到status 0Chrome 开发控制台显示 已取消 我可以用这个 简化的 代码重现这个 var httpReq new window XMLHttpRequest
  • Windows 错误 5:尝试在 Windows 中删除目录时访问被拒绝

    我正在尝试删除一个目录 但是当我运行代码时 它给出 Windows 错误 5 访问被拒绝 这是我的代码 在 Release 文件夹中 有一个名为OD if os path exists os path join get path for o
  • 具有固定行数的 ddply

    我想按 行数 分解数据 也就是说 我想向我的函数发送固定数量的行 当我到达数据帧的末尾 最后一个块 时 我只需要发送该块 无论它具有固定的行数还是更少 像这样的东西 ddply df 8 rows fun somefunction 如果你想
  • Odoo 8 - 如何更改页面标题?

    我想知道如何更改页面标题并从中删除 Odoo https www odoo com forum help 1 question change login page title 34874我尝试了这个 但我什么也没发现 标题使用标准 html
  • Python:运行进度条并同时工作?

    我想知道如何同时运行进度条和其他一些工作 然后当工作完成时 停止Python 2 7 x 中的进度条 import sys time def progress bar while True for c in sys stdout write
  • 当 DIV 的高度设置为“100%”时,为什么计算出的 DIV 高度大于其内容(如 svg)? [复制]

    这个问题在这里已经有答案了 这是我的代码 div align center style width 100 height 100 padding 0px margin 0px div
  • JavaScript for 循环索引奇怪[重复]

    这个问题在这里已经有答案了 我对 JS 比较陌生 所以这可能是一个常见问题 但我在处理 for 循环和 onclick 函数时注意到一些奇怪的事情 我能够用这段代码复制这个问题
  • 如何比较数组?还有改变属性?

    我是新的 ios 开发人员 我想比较和更改属性 数组1 对象1 对象2 对象3 对象4 数组2 对象2 对象4 对象5 对象8 比较数组 1 和数组 2 如果 Array2 中存在相同的对象 请更改对象中的属性 在上面的例子中 Object
  • 如何以 root 权限启动 QProcess?

    我需要启动gphoto2来自 Qt 程序 我这样做 QString gphotoProgram usr bin gphoto2 QStringList gphotoArguments gphotoArguments lt lt captur
  • 如何修复 Linux 中的“usr/bin/google-chrome 不再运行,因此 ChromeDriver 假设 Chrome 已崩溃”错误? [复制]

    这个问题在这里已经有答案了 我正在尝试设置一个 jenkins 服务器来在 Amazon Linux 上使用 Selenium webdriver 3 142 0 和 ruby 2 3 7 托管我的自动化框架 如果我尝试使用我的脚本调用 c
  • 从一堆对象中提取一个对象并检测边缘

    在我的大学项目中 我需要通过检测叶子的边缘来根据植物叶子的形状来识别植物的种类 我使用OpenCV 2 4 9和C 但源图像是在植物的真实环境中拍摄的 并且有不止一片叶子 请参阅下面的示例图片 所以这里我需要提取一片叶子的边缘图案来进一步处